基数和偶数分离
2016-01-15 18:42
351 查看
/* 仅用O(1)的空间,将整数数组按奇偶数分成2部分,数组左边是奇数、右边是偶数。 (要求:给出完整代码,尽量高效,简洁) */ /*下面是我的写的代码*/ #include <stdio.h> #define MAX 10 //交换变量 void swap(int *p, int *q) { if (p==NULL || q==NULL) return; *p ^= *q; *q ^= *p; *p ^= *q; } //将数组中基数和偶数分离 void arr_deal(int *arr, int num) { int i = 0, j = num-1; if (NULL == arr || num < 1) return; while (i < j) { while (arr[i]%2==1 && i<j) i++; while (arr[j]%2==0 && i<j) j--; if (i < j) swap(&arr[i], &arr[j]); } } //显示数组中的内容 void display(int *arr, int num) { int i; for (i=0; i<num; i++) printf("%d ", arr[i]); printf("\n"); } //主函数 int main(int argc, char *argv[]) { int arr[MAX] = {2, 22, 4, 5, 3, 6, 3, 27, 0, 11}; display(arr, MAX); arr_deal(arr, MAX); display(arr, MAX); return 0; }
标准答案:
#include <stdio.h> #include <stdlib.h> #define bool int #define false 0 #define true 1 void Reorder(int *pData, unsigned int length, bool (*func)(int)); bool isEven(int n); void ReorderOddEven_1(int *pData, unsigned int length) { if(pData == NULL || length == 0) return; int *pBegin = pData; int *pEnd = pData + length - 1; while(pBegin < pEnd) { // 向后移动pBegin,直到它指向偶数 while(pBegin < pEnd && (*pBegin & 0x1) != 0) // pBegin ++; // 向前移动pEnd,直到它指向奇数 while(pBegin < pEnd && (*pEnd & 0x1) == 0) pEnd --; if(pBegin < pEnd) { int temp = *pBegin; *pBegin = *pEnd; *pEnd = temp; } } } void Reorder(int *pData, unsigned int length, bool (*func)(int)) { if(pData == NULL || length == 0) return; int *pBegin = pData; int *pEnd = pData + length - 1; while(pBegin < pEnd) { //向后移动pBegin while(pBegin < pEnd &&!func(*pBegin)) pBegin ++; // 向前移动pEnd while(pBegin < pEnd &&func(*pEnd)) pEnd --; if(pBegin < pEnd) { int temp = *pBegin; *pBegin = *pEnd; *pEnd = temp; } } } bool isEven(int n) { return (n & 1) == 0; }
对于标准答案的总结:
思路:
两个指针,分别从头和从尾遍历数组
精彩的部分:
定义布尔:有利于代码的可读性 #define false 0 #define true 1 将功能封装成函数: 有利于调试,纠错,提高代码的复用 判断参数的有效性: 有利于代码的健壮性 if(pData == NULL || length == 0) return; 边界的判断: while(pBegin < pEnd && (*pBegin & 0x1) != 0) if(pBegin < pEnd) { int temp = *pBegin; *pBegin = *pEnd; *pEnd = temp; } 高效性: 对于除法和乘法,采用位运算,提高效率 pBegin & 0x1 (n & 1) == 0; 利用函数指针,实现切面编程,构成框架: bool (*func)(int) 调用判断奇数和偶数的判断:bool isEven(int n)(原型) 善用指针:(不知道算不算) int temp = *pBegin; *pBegin = *pEnd; *pEnd = temp; 注释: 在关键的位置标识
不足之处:
将int变装成bool:该设计存在问题 #define bool int 改为typedef int bool 函数参数并没有全部做判定 可能传入非法数值
编程小总结
切面编程: 框架的搭建 现在写好的函数可以调用以后写好的函数 函数参数中有调用的函数,但是不确定,用指针代替,等到想用哪个,就在 外面传入,有利于代码的维护和升级 例如: 4000 要调用bool isEven(int n); 但是没有写出来(计划将来写),但是仍然想先调用其功能(预先想好的功能),函数可以这么写 void Reorder(int *pData, unsigned int length, bool (*func)(int)); 调用判断奇数和偶数的判断:bool isEven(int n)(原型) 拓展: 对于不确定,可以都考虑指针,具体要传入参数,在外部指定传入即好 位运算: 遇到乘法、除法、求余,都可以使用位运算,提高效率 例如: x%2 <=> n&1 注意:只是用在偶数中 例如: // 向后移动pBegin,直到它指向偶数 while(pBegin < pEnd && (*pBegin & 0x1) != 0) // pBegin ++; // 向前移动pEnd,直到它指向奇数 while(pBegin < pEnd && (*pEnd & 0x1) == 0) pEnd --; 以后要在关键位置注释,比较难懂的代码加上功能注释,需要标识位置(调试)
相关文章推荐
- .NET中提升UAC权限的方法总结
- 数据库之组合查询
- windows相关小知识
- Android 从输入法 到 EditText 研究
- mysql常见错误码
- Linux Bash算数运算方法小结
- Java提高学习之Object(3)
- python中的时间函数编写
- Android GPU加速渲染自定义View 性能改善<13>
- Atitit.java jna 调用c++ dll 的总结
- 第一次写python爬虫
- 协议和委托的各种用法
- Java 并发和多线程(一) Java并发性和多线程介绍[转]
- Atitit.java jna 调用c++ dll 的总结
- jqGrid几个需要注意的默认设置
- Android ADB命令大全(通过ADB命令查看wifi密码、MAC地址、设备信息、操作文件、查看文件、日志信息、卸载、启动和安装APK等)
- Android Studio 快捷键一览表
- Atitit.java jna 调用c++ dll 的总结
- 北京乘客零下7度穿内裤乘地铁
- SQLServer中DataLength()和Len()两内置函数的区别