【问题标题】:odds to the first and evens last第一个和最后一个的赔率
【发布时间】:2012-09-20 22:49:16
【问题描述】:

我正在尝试解决... 在一个数组中,我们必须将所有奇数元素移到开头...将偶数元素移到结尾... 我试过这种方式,但这里甚至失去了秩序......有人可以帮助我吗?????? 我得到的输出是 ...1 3 5 7 9 4 8 2 6
期待一个线性的时间解决方案......

 #include<stdio.h>
 void swap(int *p,int *q)
 {
 *p=*p^*q;
  *q=*p^*q;
  *p=*p^*q;
 }
  int main()
  {
  int arr[]={ 2, 1 ,4 ,3 ,6 ,5 ,8 ,7 ,9};
  int  odd=0;
  int even=0;
  int arr_size = sizeof(arr)/sizeof(arr[0]);
  while(even< arr_size){
     if(arr[even]&1)
        swap(&arr[odd++],&arr[even++]);
     else
        even++;
  }
 int i=0;
 for(i=0;i<arr_size ;i++)
 printf("%d  ",arr[i]);
 return 0;
}

【问题讨论】:

  • 预期输出为 1,3,5,7,9,2,4,6,8,9
  • 最后是奇数还是偶数?你想要对奇数和埃文斯进行排序吗?
  • 想要即使在最后...不需要排序...
  • 所以你说你得到的输出是 1 3 5 7 9 4 8 2 6 。那有什么问题/
  • 嗯,OP好像把9当成偶数了。

标签: c arrays algorithm


【解决方案1】:

您可以通过特殊的比较函数调用qsort

#include <stdio.h>
#include <stdlib.h>

int cmp(const void * a, const void * b) {
    int aa = *((int*)a);
    int bb = *((int*)b);
    // If aa is odd and bb is even aa is smaller
    if(aa%2 == 1 && bb%2 == 0)
        return -1;
    // If bb is odd and aa is even bb is smaller
    if(aa%2 == 0 && bb%2 == 1)
        return 1;
    // If both even or odd respect current position. (If a is before b in arr a has lower address)
    if(a<b)
        return -1;
    return 1;
}
int main(void) {
    int arr[] = { 2, 1 ,4 ,3 ,6 ,5 ,8 ,7 ,9};    
    int len = sizeof(arr)/sizeof(arr[0]);
    int i;
    qsort(arr, len, sizeof(int), cmp);
    for(i=0; i<len; i++)
        printf("%d ", arr[i]);
    return 0;
}

对于不使用辅助数组的解决方案(如 HussainAl-Mutawa 所做的那样),您可以使用一种 insertion sort 来获得就地解决方案,但它的运行时间是二次增长的,所以 HussainAl-Mutawa 的版本似乎是最佳选择:)。只是为了完整起见,我的实现:

int main(void) {
    int arr[]={ 2, 1 ,4 ,3 ,6 ,5 ,8 ,7 ,9};
    int len = sizeof(arr)/sizeof(arr[0]);
    int i,j;
    for(i=1; i<len; i++) {
        int cur=arr[i];
        if(cur%2 == 0)
            continue;
        j=i;
        while(j>0 && arr[j-1]%2 == 0) {
           arr[j]=arr[j-1];
           j--;
        }
        arr[j]=cur;
    }

    for(i=0; i<len; i++)
        printf("%d ", arr[i]);

    return 0;
}

【讨论】:

  • 不幸的是,这不起作用。 qsort 不是一个稳定的排序,并且在末尾添加指针比较不足以使其如此。更多解释请参见this question
  • @SreeRam 我无法解释它是如何工作的,因为它不起作用! ;) 我链接的问题很好地解释了为什么它不明白,你不明白哪一部分?
  • @verdesmarald 好的,你提供了比较器功能...但是在分区的基础上进行快速排序工作...(假设没有重复不会带来稳定性......)
  • 我不确定你在说什么。请记住,稳定排序上下文中的“重复”表示“比较相等的元素”,因此在您的情况下,2 和 4 是重复的,因为它们都是偶数。在您的情况下,一个“无重复”的数组最多只能包含两个元素,一个是奇数,一个是偶数。
  • @verdesmarald qsort 不稳定是我想到的第一个问题,但出于好奇,我尝试使用 qsort 通过指针比较来实现解决方案:)。我用一些测试用例和编译器尝试了我的代码,它适用于所有,所以我认为不会有问题。您能否给我一个测试用例(以及您使用的编译器),我的代码确实破坏了问题需求的顺序?
【解决方案2】:

这个解决方案怎么样

#include<stdio.h>


  int main()
  {
  int i;
  int arr[]={ 2, 1 ,4 ,3 ,6 ,5 ,8 ,7 ,9};
  int arr_size = sizeof(arr)/sizeof(arr[0]);
  int sorted[arr_size];
  int sp = 0;
  for(i=0;i<arr_size;i++){
     if(arr[i]&1){
        sorted[sp++]=arr[i];
     }
  }

  for(i=0;i<arr_size;i++){
     if(!(arr[i]&1)){
        sorted[sp++]=arr[i];
     }
  }

  for(i=0;i< arr_size ;i++)
    printf("%d  ", sorted[i]);
 return 0;
}

输出是

 1  3  5  7  9  2  4  6  8  

** 更新 **

虽然上面使用了更多空间并在列表中运行了两次,但以下仅在列表中运行了一次,但仍然使用了更多空间

 int main(){

  int i;
  int arr[]={ 2, 1 ,4 ,3 ,6 ,5 ,8 ,7 ,9};
  int arr_size = sizeof(arr)/sizeof(arr[0]);
  int sorted[arr_size];
  int even = 1+arr_size/2;
  int odd  = 0;

  for(i=0;i<arr_size;i++){
     if(arr[i]&1)
        sorted[odd++]=arr[i];
     else
        sorted[even++]=arr[i];
  }

  for(i=0;i< arr_size ;i++)
    printf("%d  ", sorted[i]);

 return 0;
}

【讨论】:

  • @SreeRam 如果您想要一个就地的单通道解决方案,您应该在问题中这样说。
  • @verdesmarald sry ...应该更清楚地说明我的要求 ...tnks 的评论...
  • 我不知道除了使用链表/队列之外的任何其他方式
【解决方案3】:

如果交换不是比这更重要的,您可以简单地创建两个 for 循环,一个用于添加偶数,另一个用于赔率。 像这样的东西:-

  j=0;
  for(i=2;i<a_size;i+2)
  {
     b[j++]=a[i];
  }
  for(i=1;i<a_size;i+2)
  {
     b[j++]=a[i];
  }

在最后一次打印中。

【讨论】:

    猜你喜欢
    • 2015-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多