Tuesday, July 28, 2009

C++ question (about moving array values)?

Hello everyone;





I've got a big project that asks me to input a binary number.





The program has to have an option that will shift the values of the array.





Asking me to do this basically:


"3. ShiftLeft


a. Shift the numbers in the array left (mimicking the shift left operator). Note: You will not use the


%26lt;%26lt; operator to do this. Remember to pad with 0’s. Only shift one spot per function call."





Can someone assist me with this one? I've set up the file, menus, inputing, printing portion of the code but this part is driving me crazy. If I submit it at this stage my grade will be butchered. I basically need a function that'll shift the values of the array to left.





eg. The function should make 1.2.3.4.5.6 to 2.3.4.5.6.1 each time its called.





Thank you very much in advance.

C++ question (about moving array values)?
So basically you need to make a kind of circular array where the first element becomes the last and everything else shifts up. The following shiftLeft() should do what you need.





It saves the first element. Shifts the remainder of the array up. Replaces the last element with the saved first element.





It should be quite fast compared to the looping suggestions already submitted.





#include %26lt;iostream%26gt;





using namespace std;





void shiftLeft(int a[], int size)


{


int length = sizeof(int) * (size - 1);





unsigned char *dest = (unsigned char *) a;


unsigned char *src = (unsigned char *) %26amp;a[1];





int save = a[0];





memmove(dest, src, length);





a[size - 1] = save;


}








int main()


{





int array[10] = {0,1,2,3,4,5,6,7,8,9};





cout %26lt;%26lt; "Before: ";





for (int i = 0; i %26lt; 10; i++)


{


cout %26lt;%26lt; array[i];


}





cout %26lt;%26lt; endl;





for (int j = 0; j %26lt; 5; ++j)


{


shiftLeft(array, 10);





cout %26lt;%26lt; "After " %26lt;%26lt; j %26lt;%26lt; ": ";





for (int i = 0; i %26lt; 10; i++)


{


cout %26lt;%26lt; array[i];


}





cout %26lt;%26lt; endl;


}





}
Reply:I am no expert at this since i have left the world of C++ for years but basically





int pos = 0; // current position


int intArray[10] = "" // array size 10 %26amp; initialize the values





void function {


intArray[7] = intArray[0]; // initialize the first value into the last array %26amp; rest you can do it in for loop;





for(int i = 1; i %26lt;= maxSize; i++)


{


intArray[i] = intArray[i+1]; // copy the array's value into its previous position


}





// at the end of function output the arrays values;


for(int i = 0; i%26lt;= maxSize; i++)


cout %26lt;%26lt; intArray[i] + ", ";





hope that helps





}
Reply:Read the value as val.





i=0,j=0,k=0





while i%26lt;val copy the value of array[i] to another array(say, temp);i++.





Then, perform the following operation for (length of array minus val) times: array[j]=array[j+val];j++.





Then you will have 'val' number of empty slots at the end of the array.





While length of array is not reached(either val or temp array),do the following:


array[j]=temp[k],j++;k++;





Done!!


NB: If needed, make changes for the array index, since array index in C++ starts from 0.
Reply:It sounds like you've got it all but the shifting, which is a bit of a headscratcher. Think about your other bitwise operators and how you could use them to determine whether a bit in a given number is set.
Reply:Go with the C++ way.





Don't shift. That is an O(n) operation.





Instead create an array class with accessor member functions that return elements of the array. Internally it will have pointers to the start of the array and a record of the padding lengths.





When you access the array through the access member functions, they will follow the internal links and present the data as if they had been shifted in storage, when in fact only the pointers had moved.





Then you would have a O(1) shift.





If you want an easy way out, just do it with a loop, but the coding efficiency gods will be disappointed with you.





This is a case of the golding rule of code efficiency -- Never move data.





----





Another way would be to store the binary number in a string of normal unsigned integers, say 32 bits per integer.





A leftshift is the same as a multiply by 2. However the MSB would overflow and you want that bit to pass to the next integer to the left when you shift.





So start with the rightmost integer. Test the MSB, clear the MSB, multiply by 2, move to the next integer to the left, repeat, but add 1 if the MSB of the previous integer was set.





So you have left shifted on an arbitrary length binary string and you haven't used %26lt;%26lt;.





------





But... you example "eg. The function should make 1.2.3.4.5.6 to 2.3.4.5.6.1 each time its called." is inconsistent with the padding instructions. The example is a rotate not a shift.





1.2.3.4.5.6 would become 1.2.3.4.5.6.0


No comments:

Post a Comment