这道题让我玩了一晚上。。。。。
描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,
使所有奇数位于数组的前半部分,偶数位于后半部分,并保证奇数之间相对位置不变,偶数之间相对位置不变。要求时间复杂度为O(n)。
输入
每个输入文件包含一组测试案例。
对于每个测试案例,第一行输入一个n,代表该数组中数字的个数。
接下来的一行输入n个整数。代表数组中的n个数。
输出
对应每个测试案例,
输入一行n个数字,代表调整后的数组。
注意,数字和数字之间用一个空格隔开,最后一个数字后面没有空格。
样例输入
5
1 2 3 4 5
样例输出
1 3 5 2 4
第1种实现 c++
遇到奇数直接打印,偶数存起来最后一起打印,每个数字判断一下,非末尾就输出空格。这种是一开始直接想到的方法。
#include <iostream>
using namespace std;
const int MAX_N = 1000;
int main(){
int n; // 数字个数
int num; // 当前数字
int even_arr[MAX_N]; // 偶数数组
int idx_all = 0; // 总的index
int idx_even = 0; // 偶数数组index
cin >> n;
if(n <= 0) return -1;
while(idx_all < n){
cin >> num;
// 如果是奇数,则直接输出
if(num & 1){
cout << num;
if((idx_all++) < n) cout <lt; " ";
}
// 偶数则存入偶数数组
else {
even_arr[idx_even++] = num;
idx_all++;
}
}
// 如果还有偶数未打印,则打印偶数数组
if(idx_even){
for(int i = 0; i < idx_even; ++i){
cout << even_arr[i];
if(i < idx_even - 1) cout << " ";
}
}
return 0;
}
第2种实现 c++
一位大神想到的,用递归,不过不可保证偶数间的相对位置,但是代码简洁,如果再不考虑末尾的空格,删掉判断语句的话,非常美,真的。
#include <iostream>
using namespace std;
int n; // 数字的个数
void print(){
n--;
if(n < 0) return;
int num;
cin >> num;
// 如果是奇数,就直接打印
if(num & 1){
cout << num;
if(n != 1) cout << " ";
print(); // 递归打印剩下的部分
} else {
print(); // 先打印其他的奇数
cout << num;
if(n != 1) cout << " ";
}
}
int main(){
cin >> n;
print();
return 0;
}
第3种实现 c++
然而大神并不骄傲,不满足地又提出了将std::printf和std::cout的缓冲区分开的想法将奇数和偶数用不同的缓冲区输出,这样就能一起输出奇数之后,再一起输出偶数,关键的语句是:
std::ios::sync_with_stdio(false);
std::cin.tie(0);
第1行表示将printf和cout解绑;
第2行表示将cin和cout解绑,因为不解绑的时候,每次cout执行<<操作的时候会调用flush,缓冲区清空的话,会直接导致数字按顺序打印而不是缓冲起来一起打印。
注意:
1.更多关于输入输出流的问题,具体信息参考->cin.tie与sync_with_stdio加速输入输出
2.不同操作系统、编译器可能导致结果的不同,大神的LLVM 7.0.2上是直接顺序输出了,cpp.sh的Linux在线编译器输出的是偶数在前,奇数在后,但是在我的机器上面跑,运行结果是对的,我的环境是:
windows 7,32bit,MinGW g++ 4.7.1,而且开了c++11标准“-std=c++11”
虽然这种方法很局限,但是我还是觉得很好玩。
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
int n;
int num;
cin >> n;
if(n <= 0) return -1;
ios_base::sync_with_stdio(false);
cin.tie(NULL);
for(int i = 0; i < n; ++i){
cin >> num;
if(num & 1){
printf("%d ", num);
} else {
cout << num << " ";
}
}
return 0;
}