调整数组顺序使奇数位于偶数前面14
2016-05-26 22:46
204 查看
题目描述:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分。
解题思路:
O(n^2)的方法:从前向后逐一扫描交换。
基本解法前后两个指针,移动交换,直到p2刚好在p1前面一个位置,代表后面的都是偶数,前半部分都是奇数。
可扩展的解法使用一个谓词(bool)函数,判断符合什么类型的条件,主体框架相同。如:判断奇偶、判断正负数等等。
测试用例:
基本解法:
可扩展的解法:
考察易维护性、可扩展性、可复用性、灵活性的认识与理解。
如果将本题改成把数组中的数按照大小分为两部分,所有负数都在非负数前面或者把能被3整除的数都放在不能被3整除的数的前面等类似的题。 这样的题目整体逻辑框架完全相同,我们可以把这个逻辑框架抽象出来,把判断的标准变成一个函数指针,这样就可把函数解耦成两部分:一是判断数字应该在数组前半部分还是后半部分的标准,二是主体框架数组的操作。STL中有很多这样的算法操作。
实现如下:
主函数:
主体框架:
判断函数:
解题思路:
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; }
相关文章推荐
- spark-streaming入门(二)
- Cookie和Session的区别详解
- Java之------单机版书店管理系统(设计思想和设计模式系列一)概述
- Leetcode 107. Binary Tree Level Order Traversal II
- Android_Activity生命周期
- 多线程、Service与IntentService的比较
- TCP中出现RST包的几种情况
- 读《构建之法》第8、9、10章有感
- C# Form窗体的功能操作,无边框窗体的移动,无边框窗体的尺寸缩放,保存和恢复窗体的尺寸和坐标信息
- openjudge2988 计算字符串距离
- SVM笔记(三) 线性可分支持向量机
- Ubuntu 编写简单的脚本
- AsyncTask
- Java基础:参数传递(一)
- Java之环境
- HTTP的303、307状态码
- SVM笔记(二) 拉格朗日对偶性
- Github中Watch 和 Star 的区别
- IntentService
- 完美适配之安卓百分比布局使用,治好广大安卓程序员的头疼病