您的位置:首页 > 编程语言 > C语言/C++

按指定顺序进行数组排序 C++

2016-09-22 16:45 246 查看
前几天参加了一场笔试,有一道算法题目是 给定一个char数组,需要根据指定的顺序进行数组排序,比如,数组元素依次为ABCDE,而指定顺序为30142,那么数组的排序结果则为DABCE。要求数组不能扩容,通过两两交换,使用尽量少的辅助空间,在尽量少的时间内完成对数组的排序。

函数接口为 void mSwapSort(char* pArr, char* pPos, int nCount);

其中pArr和pPos数组大小均为nCount

在笔试的时候就有一个灵感,利用给定顺序数组pPos来辅助pArr来完成交换。但限于考试时间没有最后完成,回来之后先在网上查了一下,没有找到类似的题目,所以还是整理了一下思路,自己动手。

其实无论给定的pArr数组中元素内容是什么,都可以将其抽象为012345…,也就是用其下标来代表。如题,数组元素可以抽象为01234,我们的目标就是将其通过两两交换,最后变成目标顺序30142。

从正向来看,似乎比较困难,那么我们就反其道而行,将问题逆转过来,将目标顺序30142通过两两交换,最终变回01234,而01234只要执行逆操作,就可以变为30142。为什么说将问题逆转过来就能容易得多呢,因为目标顺序的内容已经明确指定了要自身最终需要处于的位置,比如pPos[0] = 3, 这就说明这个元素是需要最终交换到pPos[3]这个位置的(此时pPos[3] = 3),只要每次都将一个元素交换到其应当处于的位置,通过一系列迭代,整个数组的元素都能交换到目标位置,也就是01234(元素和数组下标刚好对应)。而我们只需要记录下每次交换的步骤,将pArr数组中的元素按照步骤逆推回去即可,最终代码是用递归来实现的。

示例分析:

pArr(抽象化后): 0 1 2 3 4

pPos: 3 0 1 4 2

nCount: 5

操作元素交换元素下标交换后的pPos数组
--3 0 1 4 2
pPos[0]0, 34 0 1 3 2
pPos[0]0, 42 0 1 3 4
pPos[0]0, 10 2 1 3 4
pPos[0]0, 00 2 1 3 4
pPos[1]1, 20 1 2 3 4
pPos[1]1, 10 1 2 3 4
pPos[2]2, 20 1 2 3 4
pPos[3]3, 30 1 2 3 4
pPos[4]4, 40 1 2 3 4
其中两个交换元素下标相同则表示当前操作元素已经达到排序目标,可以开始操作下一个元素。

接下来按照以上交换步骤逆推,即可实现01234到30142的排序

交换元素下标交换后的pArr数组
-0 1 2 3 4
1, 20 2 1 3 4
0, 12 0 1 3 4
0, 44 0 1 3 2
0, 33 0 1 4 2
最后附上代码

#include<iostream>
#include<cstring>
#include<ctime>
#include<cstdlib>
using namespace std;

void swap(char &a, char &b){
if(&a == &b)//防止对同一元素进行交换导致其被置为0
return;
a ^= b;
b ^= a;
a ^= b;
}

void m_swap(char* arr, char* pos, int i, int len){
if(i == len)
return;
int index = pos[i]; //此次迭代需要交换的元素下标为i和index
swap(pos[i], pos[index]);

if(pos[i] == i) //当前元素已经处于排序目标位置
m_swap(arr, pos, i + 1, len);
else
m_swap(arr, pos, i, len);

swap(arr[i], arr[index]);
}

void mSwapSort(char* pArr, char* pPos, int nCount){
m_swap(pArr, pPos, 0, nCount);
}

int main(){
char arr[] = {'0', '1', '2', '3', '4', 0};
//char arr[] = {'A', 'B', 'C', 'D', 'E', 0};
char pos[] = {4, 2, 3, 1, 0};

int len = strlen(arr);

//随机打乱指定顺序数组,产生随机测试用例
srand(time(0));
for(int i = 0; i < 10; i++){
int i1 = rand() % len;
int i2 = rand() % len;
swap(pos[i1], pos[i2]);
}

//打乱后的指定顺序数组
cout << "pos target:     ";
for(int i = 0; i < len; i++)
cout << (int)pos[i];
cout << endl;

//调用函数
mSwapSort(arr, pos, len);

//输出排列后的结果
cout << "result:         ";
cout << arr << endl;

//输出指定顺序数组数组在排序后的变化,若正确运行会变成01234
cout << "pos after swap: ";
for(int i = 0; i < len; i++)
cout << (int)pos[i];
cout << endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: