您的位置:首页 > 其它

调整数组顺序使奇数位于偶数前面14

2016-05-26 22:46 204 查看
题目描述:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分。

解题思路:

O(n^2)的方法:从前向后逐一扫描交换。

基本解法前后两个指针,移动交换,直到p2刚好在p1前面一个位置,代表后面的都是偶数,前半部分都是奇数。

可扩展的解法使用一个谓词(bool)函数,判断符合什么类型的条件,主体框架相同。如:判断奇偶、判断正负数等等。

测试用例:

int main(){
//数组1
int arr[5] = {1, 2, 3, 4, 5};
//输出数组
std::cout << "arr: ";
for(auto i = 0; i < 5; ++i){
std::cout << arr[i] << " "; //Output:1, 2, 3, 4, 5
}
std::cout << std::endl;

//调整数组顺序使奇数位于偶数前面
//1.基本解法
ReorderOddEven(arr, 5);
//输出数组
std::cout << "arr: ";
for(auto i = 0; i < 5; ++i){
std::cout << arr[i] << " ";//Output:1, 5, 3, 4, 2
}
std::cout << std::endl;

//数组2
int arr2[5] = {6, 7, 8, 9, 10};
//输出数组
std::cout << "arr: ";
for(auto i = 0; i < 5; ++i){
std::cout << arr2[i] << " ";//Output:6, 7, 8, 9, 10
}
std::cout << std::endl;

//2.可扩展解法
ExtendReorderEven(arr2, 5);
//输出数组
std::cout << "arr: ";
for(auto i = 0; i < 5; ++i){
std::cout << arr2[i] << " "; //Output:9, 7, 8, 6, 10
}

return 0;
}


基本解法:

//前后两个指针,**移动交换**,直到p2刚好在p1前面一个位置,代表后面的都是偶数,前半部分都是奇数。
void ReorderOddEven(int *arr, int length){
if(arr == NULL || length <= 0)
throw new std::exception("Invalid Input");
//头指针
int *begin = arr;
//尾指针
int *end = arr + length - 1;
while(begin < end){
//向后移动begin,直到它指向偶数
while(begin < end && (*begin & 0x1) != 0)
begin++;
//向前移动end,直到它指向奇数
while(begin < end && (*end & 0x1) == 0)
end--;
if(begin < end){ //begin小于end才能交换
//此时,begin指向偶数,end指向奇数。交换它们
int temp = *begin;
*begin = *end;
*end = temp;
}
}
}


可扩展的解法:

考察易维护性、可扩展性、可复用性、灵活性的认识与理解。

如果将本题改成把数组中的数按照大小分为两部分,所有负数都在非负数前面或者把能被3整除的数都放在不能被3整除的数的前面等类似的题。 这样的题目整体逻辑框架完全相同,我们可以把这个逻辑框架抽象出来,把判断的标准变成一个函数指针,这样就可把函数解耦成两部分:一是判断数字应该在数组前半部分还是后半部分的标准,二是主体框架数组的操作。STL中有很多这样的算法操作。

实现如下:

主函数:

void ExtendReorderEven(int *arr, int length){
ExtendReorder(arr, length, isEven);
}


主体框架:

void ExtendReorder(int *arr, int length, bool(*fun)(int)){
if(arr == NULL || length <= 0)
throw new std::exception("Invalid Input");
int *begin = arr;
int *end = arr + length - 1;

while(begin < end){
while(begin < end && !fun(*begin))
++begin;
while(begin < end && fun(*end))
--end;
if(begin < end){
int temp = *begin;
*begin = *end;
*end = temp;
}
}
}


判断函数:

//谓词函数,判断一个整数的奇偶性
bool isEven(int value){
return (value & 1) == 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: