开发者

How can I interchange the values of two arrays while preserving memory as much as possible?

开发者 https://www.devze.com 2023-02-07 20:58 出处:网络
Two arrays are to be interchanged with their values, I am seeking methods to do it开发者_开发百科 without using third array. How could it be solved? I saw some arithmetic methods (as shown below) to d

Two arrays are to be interchanged with their values, I am seeking methods to do it开发者_开发百科 without using third array. How could it be solved? I saw some arithmetic methods (as shown below) to do it for integers, but couldn't sort out my problem with string arrays.

int a[350]={350 values};
int b[350]={350 values};
for(int i=0;i<350;i++)
{
    a[i]=a[i]+b[i];
    b[i]=a[i]-b[i];    
    a[i]=a[i]-b[i];
}


If you're going to iterate over the array, you don't need a new array; just one temporary variable will suffice, and you can reuse it each iteration.

If any new memory allocation is forbidden, then you could use the arithmetic or XOR solution, as long as the data type is integral.

for(int i = 0; i < 350; ++i)
{
    a[i] = a[i] + b[i];
    b[i] = a[i] - b[i];    
    a[i] = a[i] - b[i];
}
// or
for(int i = 0; i < 350; ++i)
{
    a[i] ^= b[i];
    b[i] ^= a[i];
    a[i] ^= b[i];
}

Finally, you can always just swap the array pointers!

object[] a;
object[] b;
object[] temp;

temp = a;
a = b;
b = temp;


Why use any ridiculous tricks? Can't you spare a single int temporary?

for(int i=0;i<350;i++)
{
    std::swap(a[i], b[i]);
}

or

std::swap_ranges(a, a+350, b);

Note: on my machine, the XOR trick typically takes twice as long as just using a single temporary variable for the swap.


IF the arrays are integral, you can uses the xor trick:

for(int i = 0; i < 350; ++i) {
    a[i] = a[i] ^ b[i];
    b[i] = a[i] ^ b[i];
    a[i] = a[i] ^ b[i];
}

no temporaries needed


In C++ you can use bit xor for with pointers (I assume that strings are char* or wchar_t*). But really I don't think that one variable is bad for you and it will be better just to use std::swap.


Even better:

for(int i = 0; i < 350; ++i)
{
    a[i] ^= b[i];
    b[i] ^= a[i];
    a[i] ^= b[i];
}


I guess the author's question is swap the array not using a third array. So I think just use one variable is enough.

int tmp = 0;
for( int i = 0; i < 350; ++i )
{
    tmp = a[i];
    a[i] = b[i];
    b[i] = a[i];
}

why bother use some xor operations?


Your solution does not work: it illustrates a simple problem actually, that many have stumbled upon.

Algorithms' descriptions do not, in general, take into account the finite memory representation that computers have.

In particular here, int can only hold so many bits, and thus the addition may result in an overflow, which is undefined behavior (on x86, it wraps around, but on other processors it might trigger a hardware exception).

There are two correct (and simple) solutions to exchange two int:

  • int tmp = lhs; lhs = rhs; rhs = tmp;, also known as swap
  • lhs ^= rhs; rhs ^= lhs; lhs ^= rhs;, also known as the XOR trick

Both are obviously applicable in case of arrays.

Another solution, more efficient, would be to swap the arrays themselves.

std::swap(a,b);

Note: if the arrays are statically allocated, it's not possible to swap them directly, but you can perfectly only use pointers to the statically allocated arrays and thus swap the pointers

Caveat: objects that already have a reference to the arrays will not be notified of the swap, in this case you have no other choice than swapping their content.

0

精彩评论

暂无评论...
验证码 换一张
取 消