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

这道题让我玩了一晚上。。。。。

描述

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,
使所有奇数位于数组的前半部分,偶数位于后半部分,并保证奇数之间相对位置不变,偶数之间相对位置不变。要求时间复杂度为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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值