My main idea is to shrink they array from both sides . For example if the input is 1234 , wanna print 1234 and then 4321 (the reversed) .
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int reversedArray(int* x)
{
cout<< "*x out of while =" << *x <<endl ;
while( *x != 0 )
{
cout << "*x=" << *x << endl;
cout<< "====================== im in reversed =================" << endl ;
return reversedArray( x+1 );
}
cout<< "after return " << *x << endl;
}
int main ()
{
int Array[] = {10,2,3,4,8 ,0} ;
int* p_Array = Array;
reversedArray( Array );
}
After the "while" , why the functions that are in the stack, do not return to the next line ( " the --> cout<< "after return " <<*x <
void printReversed(int * x)
{
if (*x == 0) return;
std::cout << *x;
printReversed(x+1);
std::cout << *x;
}
The line:
return reversedArray( x+1 );
exits the function. So you never repeat the while or execute any of the code after the while if you go into the while. This makes the while effectively an if statement.
The code posted by Crazy Eddie does the job and Barmar explains the ineffectiveness of the while loop. I decided to post a non-recursive way to address the problem mentioned.
#include <iostream>
#include <vector>
using namespace std;
vector<int> reverseArray(vector<int>& arr) {
vector<int> ans;
int n = arr.size();
// insert all elements in the reverse order
for (size_t i = 0; i < n; i++) {
ans.push_back(arr[n-i-1]);
}
return ans;
}
int main ()
{
int array[] = {10, 2, 3, 4, 8, 0};
// convert into vector
vector<int> arr(array, array+6);
vector<int> rev = reverseArray(arr);
// merging the 2 arrays
arr.insert(arr.end(), rev.begin(), rev.end());
// printArray(arr) -- implement to fit your needs;
}
When you pass an int[] to a function it decays to an int* which is simply an address in memory. C++ a better plan would be to use copy_backward with an ostream_iterator:
copy_backward(Array, Array + sizeof(Array) / sizeof(*Array), ostream_iterator<int>(cout, " "))
Note that this method uses the actual size of the array, and does not depend upon a terminal element. Thus, no numbers are offlimits, and it's impossible to segfault by failing to provide the terminating element.
If you have access to C++11 you can simplify that a bit further to:
copy(crbegin(Array), crend(Array), ostream_iterator<int>(cout, " "))
Live Example
Related
I need to print an array by implementing the use of a function before the main function. So I tried the following function:
int* printArr(int* arr)
{
for (int i = 0; i < 5; i++) {
cout << arr[i];
}
return arr;
}
I encountered two problems when implementing this into the whole code.
First, this is printing what I think is the address of the array and not the actual array. Pretty sure this is because of the return arr; in line 10. But if I do not write return then the code will produce an error. How can I fix this?
Second, I do not understand the second argument printArr has. In line 19, you can see cout << printArr(arr, 5) << endl;. How come there is a single numeric value, that one being 5 in this case, as an argument? How can I account for this in my function?
Please keep in mind that I am new to C++ and coding in general. Also, this code was given to me, hence why I do not understand certain aspects of it.
This is my code so you can see what I mean:
#include <iostream>
using namespace std;
// Declare function printArr here
int* printArr(int* arr)
{
for (int i = 0; i < 5; i++)
{cout << arr[i];}
return arr;
}
int main()
{
int arr[5] = {1, 3, 5, 7,9};
int last_num = arr[sizeof(arr)/sizeof(int)-1];
cout << "Before reversing" << endl;
cout << printArr(arr, 5) << endl;
// reverse "arr" using reference(&)
cout << "After reversing" << endl;
printArr(arr, 5);
return 0;
}
The declaration and implementation of printArr() is all wrong.
First, this is printing what I think is the address of the array and not the actual array.
The printArr() function itself is printing the contents of the array (well, the first 5 elements anyway), and then returning the address of the array. It is main() that is printing that address afterwards, when it passes the return value of printArr() to std::cout <<.
Pretty sure this is because of the return arr; in line 10. But if I do not write return then the code will produce an error. How can I fix this?
By getting rid of the return type altogether. There is no good reason to return the array pointer at all in this example, let alone to pass that pointer to std::cout. So printArr() should be returning void, ie nothing.
Second, I do not understand the second argument printArr has. In line 19, you can see cout << printArr(arr, 5) << endl;. How come there is a single numeric value, that one being 5 in this case, as an argument?
Because main() is passing in the element count of the array (5) so that printArr() can know how many elements to actually print, instead of hard-coding that value in the loop. However, your declaration of printArr() does not have a 2nd parameter with which to accept that value, that is why you are getting errors.
How can I account for this in my function?
By adding a 2nd parameter in the function declaration, eg:
#include <iostream>
using namespace std;
// Declare function printArr here
void printArr(int* arr, int size)
{
for (int i = 0; i < size; i++)
{
cout << arr[i] << ' ';
}
cout << endl;
}
int main()
{
int arr[5] = {1, 3, 5, 7, 9};
const int count = sizeof(arr)/sizeof(arr[0]);
int last_num = arr[count-1];
cout << "Before reversing" << endl;
printArr(arr, count);
// reverse "arr" using reference(&)
cout << "After reversing" << endl;
printArr(arr, count);
return 0;
}
Live Demo
I'm trying to learn how std::allocator works and I tried to do a simple task. The task is to delete for example the second element and to shift the elements to the left when the elements has been deleted.
For example, we have this as an input array: 1,2,3 and the output should look like 1,3. And what I get as input is: 1,3,3
This thing doesn't happen and that's why I'm here asking you.
But, when I have **std::allocator<string> myVar** instead of **std::allocator<int> myVar** it works.
Then the input: one, two, three and output is: one, three
Here's the code using std::allocator<int>:
#include <iostream>
#include <memory>
using namespace std;
int main()
{
allocator<int> a1;
int* arr = a1.allocate(3);
for (int i = 0; i < 3; i++)
a1.construct(arr + i, i + 1);
a1.destroy(arr + 1);
a1.construct(arr + 1, 3);
for (int i = 0; i < 3; i++)
cout << arr[i] << " ";
cout << endl;
a1.deallocate(arr, 3);
return 0;
}
And here's the code with std::allocator<string>:
#include <iostream>
#include <memory>
#include <string>
using namespace std;
int main()
{
allocator<string> a1;
string* wrd = a1.allocate(3);
a1.construct(wrd, "one");
a1.construct(wrd + 1, "two");
a1.construct(wrd + 2, "three");
a1.destroy(wrd + 1);
cout << wrd[0] << " " << wrd[1] << " " << wrd[2] << endl;
a1.deallocate(wrd, 3);
return 0;
}
When you call allocator::destroy, it just destroys the object in the memory -- it doesn't do anything to the memory (its still there) or move anything. When you later try to do somthing with that memory, you get undefined behavior, but in the case of your strings, the "undefined behavior" turns out to be "act as if it was an empty string", so nothing gets printed.
If you were to call a1.construct(wrd+1, "three"); after the call to a1.destroy ins your string code (to make it the same as your int code), you would see it prints one three three
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. */
string list[] = {"fiorello", "nonuterine", "asquint", "commodore", "semiprogressive",
"aviculturist", "brayley", "tendentious", "hungriness", "overbulkily",
"subfumigation", "praline", "fiorello", "presurvey", "unjealous",
"brayley", "unimpassionate", "welshman", "dcor", "traducianist"};
int size = sizeof(list);
for (int i = 0; i < size; i++) {
cout << list[i] << endl;
// THIS IS WHERE I REALIZE NOTHING ELSE PRINTS AFTER THIS POINT.
}
cout << endl;
int z = sizeof(list) / sizeof(list[0]);
sort(list, list + z);
for (int y = 0; y < z; y++) {
cout << list[y] << endl;
}
return 0;
}
I don't have a strong background in C++, coming from HTML, CSS etc. so trying to figure this out.
What I'm trying to accomplish is to print out the array, then print out in alphabetical order, then find duplicates and remove and print out again. And lastly, find length of each word in array and print that out.
As mentioned in comments, you are using sizeof incorrectly the first time. A good solution would be to not use it at all, instead use standard library algorithms which will find the size by template deduction:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string list[]={"fiorello","nonuterine","asquint","commodore","semiprogressive","aviculturist","brayley","tendentious","hungriness","overbulkily","subfumigation","praline","fiorello","presurvey","unjealous","brayley","unimpassionate","welshman","dcor","traducianist"};
// Operate on each item in list - don't need to mention count explicitly
for ( auto&& s : list )
cout << s << '\n';
cout << endl;
// Same as sort(list, list+z)
sort( begin(list), end(list) );
for ( auto&& s : list )
cout << s << '\n';
cout << endl;
}
Your comments suggest you plan to remove duplicates but you still want to use a C-style array. So presumably you'll be using a variable for the list count; you can get this by using:
size_t count = distance( begin(list), end(list) );
rather than using the sizeof thing. As well as being less error-prone, this will keep working even if you later change the code to use a container instead of a C-style array.
I have made this code to store the position of each bit 1 entered in a binary sequence. The output of the program is not what it is desired. The output I get for 10100 is 0x7fff9109be00. Here is the code:
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
bitset <5> inpSeq;
int x = 0;
int xorArray[x];
unsigned int i;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for ( i = 0; i < inpSeq.size(); i++)
{
if ( inpSeq[i] == 1 )
{
x = x+1;
xorArray[x] = i;
}
}
cout << xorArray << "\n";
}
Update for clarity: What I had in mind was that 'cout << xorArray' will print bit 1's positions.
cout << xorArray << "\n";
This does not print the elements of xorArray; it prints its address.
You must iterate ("loop over") it:
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
Your other problem is that you're trying to use a variable-length array, which does not exist in C++. Use a vector instead.
Now it gives you your desired output:
#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
int main()
{
bitset<5> inpSeq("10111");
std::vector<int> xorArray;
for (unsigned int i = 0; i < inpSeq.size(); i++) {
if (inpSeq[i] == 1)
xorArray.push_back(i);
}
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
}
If you're not using C++11 for whatever reason, you can perform that final loop the traditional way:
for (std::vector<int>::const_iterator it = xorArray.begin(),
end = xorArray.end(),
it != end; ++it) {
cout << *it << ' ';
}
Or the naive way:
for (unsigned int i = 0; i < xorArray.size(); i++)
cout << xorArray[i] << ' ';
I am a little unclear on exactly what you are trying to achieve, but I think the following might help.
#include <iostream>
#include <bitset>
#include <list>
using namespace std;
int main() {
bitset<5> inpSeq;
unsigned int i;
list<int> xorList;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for (i = 0; i < inpSeq.size(); ++i) {
if (inpSeq[i] == 1) {
xorList.push_back(i);
}
}
for (list<int>::iterator list_iter = xorList.begin();
list_iter != xorList.end(); list_iter++)
{
cout << *list_iter << endl;
}
return 0;
}
The reason why I am using a list is because you mentioned wanting to store the positions of the 1 bit. The list is being used as the container for those positions, in case you need them in another point in the program.
One of the problems with the original code was that you assigned variable 'x' the value 0. When you declared xorArray[x], that meant you were essentially creating an array of length 0. This is incorrect syntax. It looks like you actually were trying to dynamically allocate the size of the array at runtime. That requires a different syntax and usage of pointers. The list allows you to grow the data structure for each 1 bit that you encounter.
Also, you cannot print an array's values by using
cout << xorArray << endl
That will print the memory address of the first element in the array, so, xorArray[0]. Whenever you want to print the values of a data structure such as a list or array, you need to iterate across the structure and print the values one by one. That is the purpose of the second for() loop in the above code.
Lastly, the values stored are in accordance with the 0 index. If you want positions that start with 1, you'll have to use
xorList.push_back(i+1);
Hope this helps!
I'm wondering if it's possible to swap the contents of two C++ arrays that are of different sizes (without using any predefined C++ functions)? My code is as follows:
#include <iostream>
#include <string>
using namespace std;
void swapNames(char a[], char b[])
{
//can be done with one temp; using two for clarity purposes
char* temp = new char[80];
char* temp2 = new char[80];
int x = 0;
while(*(b+x)!='\0')
{
*(temp+x) = *(b+x);
x=x+1;
}
x=0;
while(*(a+x)!='\0')
{
*(temp2+x) = *(a+x);
x=x+1;
}
x=0;
while(*(temp2+x)!='\0')
{
*(b+x) = *(temp2+x);
x=x+1;
}
x=0;
while(*(temp+x)!='\0')
{
*(a+x) = *(temp+x);
x=x+1;
}
}
int main()
{
char person1[] = "James";
char person2[] = "Sarah";
swapNames(person1, person2);
cout << endl << "Swap names..." << endl;
cout << endl << "Person1 is now called " << person1;
cout << "Person2 is now called " << person2 << endl;;
}
My initial idea was to pass in references to person1 and person2 themselves, store the data in temp variables, delete the memory allocated to them, and link them to newly created arrays with the swapped data. I figured this would avoid predefined memory limits. It seems, though, that passing in references(&) to arrays is very much not allowed.
The above works fine if person1 and person2 are of the same size. However, once we have names of different sizes we run into problems. I assume this is because we can't alter the memory block we allocated when we initially created person1 and person2.
Also, is it possible to create a new array in C++ without predefining the size? IE a way to create my temp variables without placing a limit on their sizes.
char person1[] = "James";
is just a shorthand for:
char person1[6] = "James";
You cannot later store more than 6 characters in person1. If what you really want are strings of varying lengths, I would suggest ditching C style strings in favor of the std::string standard library type:
#include <string>
#include <algorithm>
std::string person1 = "James";
std::string person2 = "Sarah";
swap(person1, person2);
If your book teaches C style strings before std::strings, you should consider getting a new book.
References to arrays are allowed, as long as the array is fixed size.
There's an easy answer instead of all the complex things you are considering. Just use a vector.
vector<char> a;
vector<char> b;
...
a.swap(b);
What could be easier?
Also vectors are the answer to your question, 'Also, is it possible to create a new array in C++ without predefining the size?'. You can create a vector and then resize it later (which is almost the same thing).
You should always prefer container classes over raw arrays. But, if you absolutely must use an array, you can certainly accomplish swapping without resorting to dynamically allocating the temporary array. Use templates to statically determine the type and size of the arrays being passed into the swap function.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
template<typename T, size_t N>
void swap_arrays( T(&left)[N], T(&right)[N] )
{
T temp[N];
// copy left to temp
std::copy( std::begin(left), std::end(left), std::begin(temp) );
// copy right to left
std::copy( std::begin(right), std::end(right), std::begin(left) );
// copy temp to right
std::copy( std::begin(temp), std::end(temp), std::begin(right) );
}
template<typename T, size_t N>
void swap_and_print( T(&left)[N], T(&right)[N] )
{
std::cout << "\nBefore swapping: \n";
std::cout << " Left:";
std::for_each( std::begin(left), std::end(left),
[]( T const& t ) { std::cout << " " << t; } );
std::cout << "\n Right:";
std::for_each( std::begin(right), std::end(right),
[]( T const& t ) { std::cout << " " << t; } );
swap_arrays( left, right );
std::cout << "\nAfter swapping: \n";
std::cout << " Left:";
std::for_each( std::begin(left), std::end(left),
[]( T const& t ) { std::cout << " " << t; } );
std::cout << "\n Right:";
std::for_each( std::begin(right), std::end(right),
[]( T const& t ) { std::cout << " " << t; } );
}
int main()
{
int foo1[] = {1,2,3,4,5};
int bar1[] = {6,7,8,9,10};
swap_and_print( foo1, bar1 );
char foo2[] = "James";
char bar2[] = "Sarah";
swap_and_print( foo2, bar2 );
}
Output:
Before swapping:
Left: 1 2 3 4 5
Right: 6 7 8 9 10
After swapping:
Left: 6 7 8 9 10
Right: 1 2 3 4 5
Before swapping:
Left: J a m e s �
Right: S a r a h �
After swapping:
Left: S a r a h �
Right: J a m e s �
Note: The weird character at the end of the second example is because the inputs are char arrays that include the terminating null character; and what you're seeing is its visual representation (since the code is printing it out as a character).