If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Array Inversion??

Hi everybody - I'm taking my first programming class ever......online (which I wouldn't have done if I had it to do over). I'm working on this assignment and I cant get through to my instructor. Here's what he wants:

Write a program to declare and initialize the following array:

int array[] = { 10, 20, 30, 40, 50, 60 };

Now add code to the program that uses a loop to exchange the outermost pair
of element values, then the next interior pair, and so on until the innermost
pair of values is exchanged. Write the program so that it is not sensitive to
the number of elements in the array and test it on an integer array that
contains an odd number of elements. Your program may not have more than one
array. You may use a temp variable in the swapping process.

The program output should be similar to the following:

original array (element 0 first): 10 20 30 40 50 60

array after exchange (element 0 first): 60 50 40 30 20 10

NOTE: you can determine the number of elements in an array with the
following:

Use the sizeof() function to determine the number of elements in any arrays
that are initialized before compilation in all the following assignments. If
the number of elements is determined at run time by console input, then you
may use a counter variable to determine the number of elements in an array.

Re: Array Inversion??

You should implement a swap in your while-loop rather than a simple assignment. As a result, you only copy the result from, e.g. x[4] into x[0] and x[3] into x[1] but forgetting to do x[0] into x[4] and x[1] into x[3]. The swapping functionalities can be achieved as follows.

Code:

int temp = array[x];
array[x] = array[n];
array[n] = temp;

In addition, you shouldn't use array[s] where s = 5 for displaying the result of the last element in the array. Since array in C/C++ is always zero-based, the valid range is from 0 to 4 for a 5 elements array.

quoted from C++ Coding Standards:

KISS (Keep It Simple Software):Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.

Re: Array Inversion??

If you are allowed the usage of containers - vectors have a reverse() member function that you could use to do the job.

Also, always try to encapsulate small pieces of logic into functions. Like in you code you could choose to make a swap function - one to print the array and one to fill the array and things like that instead of writing everything in main().

Re: Array Inversion??

xenodamus
Debug your code. See what state your data are in on every step and what changes you get after each operation. If you are not familiar with debugger, write printing methods which print state of system every now and then. For example you could change your source so (not fixing your bugs here):

If you are allowed the usage of containers - vectors have a reverse() member function that you could use to do the job.

Also, always try to encapsulate small pieces of logic into functions. Like in you code you could choose to make a swap function - one to print the array and one to fill the array and things like that instead of writing everything in main().

I think it's definately too much for "first programming lesson ever with instructor who says that sizeof() is function from iostream.h".

"Programs must be written for people to read, and only incidentally for machines to execute."

This trick does have one pitfall. You have to make sure you are not using it in an algorithm where a memory location will be swapped with itself because array[i] ^ array[j] == 0 if i == j. If this could happen you want to use a temporary variable.

I think this trick might have come from MIT's AI lab. Their people had a list of tricks and problems collectively refererred to as HAKMEM. See <http://www.inwap.com/pdp10/hbaker/hakmem/hakmem.html>.

Re: Array Inversion??

A really neat trick exists by which you can swap two values without going through a temporary variable. It relies on bit manipulation using XOR.

It is a funny trick, but not a neat trick!
At best, it won't change the program's speed.
At worst, it will reduce the program's speed, and may introduce bugs.
Moreover it only works with integers!

That you see no temporary variable doesn't mean that there are none!
In fact, a^=b, needs at least a temporary register for the value of b.
This trick avoid the explicit declaration of an automatic variable. That's fun, but useless.

This trick is inefficient for compilers supporting temporaries in registers!
Moreover if a and b may be aliases, not only it behaves incorrectly, but also it reduces the possibilities of compiler optimization (the work can't be done in registers)!

Last edited by SuperKoko; April 12th, 2006 at 03:08 AM.

"inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.Club of lovers of the C++ typecasts cute syntax: Only recorded member.

In inline code (or with a less good optimizer) , these speed differences may be greater.

"inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.Club of lovers of the C++ typecasts cute syntax: Only recorded member.

Re: Array Inversion??

Originally Posted by LanTHrusteR

Reversing vectors is not efficient. That is the reason why standard vector doesn't have reverse member function and std::list does.

Correct, the reverse is probably just a member in microsoft implementations. I did not find it in the standards.. or Dinkumware implementation. However, as far as efficiency is concerned - I am not sure that it would be really bad considering we are using the swap mechanism with the array.

However, the vector might not actually need to be reverse at all. One could always use the reverse_iterator whenever a reverse vector is to be used. One can also mimic this behaviour with C-style arrays. And since the OP is only doing that to print to the standard output.. this is the best way to go.. without even actually doing the reverse unless that is a rigid requirement. Regards.

Re: Array Inversion??

Originally Posted by SuperKoko

It is a funny trick, but not a neat trick!
At best, it won't change the program's speed.
At worst, it will reduce the program's speed, and may introduce bugs.

These objections are practical, certainly, and ultimately we are all concerned with what's going to happen when the rubber meets the road. From other perspectives though, I sometimes find the theoretical to be interesting. Moreover, principles don't change when practical implementations do.

Originally Posted by SuperKoko

Moreover it only works with integers!

...but data in a digital computer is just a bunch of 0s and 1s. Those 0s and 1s could be an integer, text, music, or a picture. Consider the probably not portable code sample below...

That you see no temporary variable doesn't mean that there are none!
In fact, a^=b, needs at least a temporary register for the value of b.
This trick avoid the explicit declaration of an automatic variable. That's fun, but useless.

If the data you are swapping comes from memory, the compiler will have to fetch it and put it somewhere where the processor can operate on it, regardless of how you actually perform the swap. If the compiler decides to put it in registers, the actual swap could in principal be as simple as the C code implies consder...

On a different note, isn't it best to avoid using references in a function like this? Wouldn't "void swap(int * a, int * b)" make clearer at the point where this function is invoked that a and b might be altered. I try to limit my use of references to places where they are really needed, such as when overriding some operator or in a copy constructor.

We have some code in use where I work that was written before a certain gigantic software company's version of the STL was useable. This code implements its own queues and vectors, but unfortantly the function to enqueue something takes its argument as a reference. We don't have to look at this code often enough to remember how it works, and more than once we have we have thought we have stumbled onto a memory leak because we will see something like this...

Code:

if (pThing != NULL)
{
Node * pNode = new Node;
pNode->data = pThing;
queue.enque(*pNode); // So enqueue makes a copy of pNode?
// memory leak? Where is pNode deleted if not here since it has local scope?
}

What is totally unobvious is that enqueue internally generates a pointer to the reference and stores it. pNode gets deleted later when it is dequeued. But all of this would be much more obvious if enqueue accepted the non-const pointer instead of a reference.

Cheers,
GeoRanger

Last edited by GeoRanger; April 13th, 2006 at 12:59 AM.
Reason: Meant to indicate that pNode is of local scope in last code snippet.

Re: Array Inversion??

...but data in a digital computer is just a bunch of 0s and 1s. Those 0s and 1s could be an integer, text, music, or a picture. Consider the probably not portable code sample below...

Did you ever heard of non-POD types?

If the data you are swapping comes from memory, the compiler will have to fetch it and put it somewhere where the processor can operate on it, regardless of how you actually perform the swap. If the compiler decides to put it in registers, the actual swap could in principal be as simple as the C code implies consder...

While, with an intermediate temporary, a good compiler (I tested with GCC 3.2.3) may even produces no operation, and simply "rename" the variables as far as possible!
Or, a bad compiler, will simply generate:

On a different note, isn't it best to avoid using references in a function like this? Wouldn't "void swap(int * a, int * b)" make clearer at the point where this function is invoked that a and b might be altered. I try to limit my use of references to places where they are really needed, such as when overriding some operator or in a copy constructor.

Do you come from a C background?

I used the cannonical syntax of the standard library (std::swap), all C++ programmers can understand that perfectly, since they are used to std::swap!

In fact, std::swap is the best candidate for optimization, since the compiler is free to create optimizations specifically for that function.

Originally Posted by GeoRanger

What is totally unobvious is that enqueue internally generates a pointer to the reference and stores it. pNode gets deleted later when it is dequeued. But all of this would be much more obvious if enqueue accepted the non-const pointer instead of a reference.

Here, a reference is not natural, because it is a "pointer sink". But for std::swap, it is natural (at least from the point-of-view of a C++ programmer). std::swap does not delete the data!
In fact, since it is a pointer sink, a std::auto_ptr would be very natural, and implicitly documents perfectly that the function "gets ownership" of the data.

"inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.Club of lovers of the C++ typecasts cute syntax: Only recorded member.

Re: Array Inversion??

duuuuuuuuudesss, swap sounds VERY BAD!!! i mean swap?? no need to swap !!
create a new array copy old array reversed to the new array destroy old array and set the old array pointer to the new array pointer. and thats it. dont you think its HECK ALOT faster than swapping all vars??

* The Perfect Platform for Game Developers: Android
Developing rich, high performance Android games from the ground up is a daunting task. Intel has provided Android developers with a number of tools that can be leveraged by Android game developers.

* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.