输入:
A[4] = {0,4,-1,1000} - Actual Array
P[4] = {1,0,3,2} - Order to be reshuffled
输出:
A[4] = {4,0,1000,-1}
条件:不要使用其他数组作为内存。可以使用额外的变量或两个。
问题:我在C ++中使用以下程序,但是对于数组P的某些输入,这会失败。
#include<iostream>
using namespace std;
void swap(int *a_r,int *r)
{
int temp = *r;
*r = *a_r;
*a_r = temp;
}
int main()
{
int A[4] = {0,4,-1,1000};
int P[4] = {3,0,1,2};
int value = A[0] , dest = P[0];
for(int i=0; i<4;i++)
{
swap(&A[dest],&value);
dest = P[dest];
}
for(int i=0;i<4;i++)
cout<<A[i]<<" ";
}
答案 0 :(得分:4)
由于你有一个名为P的备用数组,并且在引用的问题中没有任何内容规定它必须被视为一个常量数组,你可以这样做:
for (i = 0; i < 4; i++)
P[i] = A[P[i]];
for (i = 0; i < 4; i++)
A[i] = P[i];
如果您不允许修改P,那么您必须更加努力工作(如果A的数据类型与A的数据类型不同或兼容,您还必须更加努力地工作。 p)。
然而,我担心这是一个狡猾的技巧,并没有真正回答这个问题;它完成了工作,但没有回答这个问题。
答案 1 :(得分:1)
首先,我非常喜欢 Jonathan 的解决方案,但我觉得我也可以添加一些有趣的想法。
主要观察结果是数组P
由几个循环组成
我们考虑一下p = {1, 4, 3, 2, 0, 5}
。有三个循环:0 => 1 => 4 => 0
,2 => 3 => 2
和5 => 5
。要在一个循环旁边替换变量,我们根本不需要额外的内存。我们就像这样经历它
do {
a[i] = a[p[i]];
i = p[i];
} while (i != first_i);
(不过,最后一个元素需要特别注意。)完整的工作版本:
for (int i = 0; i < n; ++i) {
if (p[i] < 0) {
// been at index 'i' already
continue;
}
// new loop found
int j = i;
int first_value = a[i]; // to be put in last position in the chain
int prev_j; // we always store previous 'j' index
do {
a[j] = a[p[j]];
prev_j = j;
j = p[j]; // move to next 'j'
p[prev_j] = -1; // mark element as processed
} while (i != j);
a[prev_j] = first_value;
}
我的解决方案唯一的问题是它使用p
数组将元素标记为'已处理'。一些采访者可能认为没问题,其他人 - 不是,取决于他们想到的解决方案。
答案 2 :(得分:1)
int _tmain(int argc, _TCHAR* argv[])
{
A[4] = {0,4,-1,1000}
P[4] = {1,0,3,2}
int temp = arr2[0];
for(int i=0;i<4;i++)
{
for(temp = P[i];i<3;temp = P[temp])
{
if(temp >= i)
{
int data;
data = A[i];
A[i] = A[temp];
A[temp] = data;
break;
}
}
}
_getch();
return 1;
}
答案 3 :(得分:1)
int _tmain(int argc, _TCHAR* argv[])
{
A[4] = {0,4,-1,1000}
P[4] = {1,0,3,2}
int temp = arr2[0];
for(int i=0;i<4;i++)
{
for(temp = P[i];i<3;temp = P[temp])
{
if(temp >= i)
{
int data;
data = A[i];
A[i] = A[temp];
A[temp] = data;
break;
}
}
}
_getch();
return 1;
}
答案 4 :(得分:0)
略微修改以计算目标值
int main()
{
int A[4] = {0,4,-1,1000};
int P[4] = {3,0,1,2};
int value = A[0], dest = P[0];
for(int i=0; i<4-1;i++)
{
int count=0;
dest = P[i];
while(dest<i){ //if P[i] points to lower value, it got swapped with some other position.
dest = P[dest];
}
swap(&A[dest],&A[i]);
}
for(int i=0;i<4;i++)
cout<<A[i]<<" ";
cout<<"\n";
}
答案 5 :(得分:0)
可能认为它违背了问题的精神 - 但可以使用单个局部变量的多个堆栈实例(从运行时的角度来看)(代码透视)。允许变异P同样不确定,所以,FWIW - 一个递归的答案......
template <int N>
void shuffle(int (&a)[N], int p[], int i = -1)
{
if (++i < N)
{
int result = a[p[i]];
shuffle(a, p, i);
a[i] = result;
}
}