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

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

解题思路:

  1. O(n^2)的方法:从前向后逐一扫描交换。
  2. 基本解法前后两个指针,移动交换,直到p2刚好在p1前面一个位置,代表后面的都是偶数,前半部分都是奇数。
  3. 可扩展的解法使用一个谓词(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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值