删除已排序数组中的双精度数,然后将X放在最后

时间:2012-12-20 22:53:16

标签: c arrays sorting

这是我几天试图解决的问题。

我需要编写一个获取排序数组的程序。程序将放置999,其中两个相邻的块具有相同的值,然后将所有999放在数组的末尾。我需要在不使用其他数组的情况下执行此操作,程序必须为O(n)。

示例输入:

50,60,60,72,81,81,81,81,93,93

期望的输出:

50,60,72,81,93,999,999,999,999,999

另一个例子:

1,1,2,3,4,4,5,6,6

期望的输出:

1,2,3,4,5,6,999,999,999

我的代码。它不起作用。对于第一个例子,输出是正常的。对于第二个例子,我得到1,2,3,4,5,4,5,6,-14568127(超出数组范围)

我的算法是我用两个索引i和j遍历数组,如果a [i]!= a [i + 1]那么我前进i。如果它们相等,则j寻找下一个唯一值,并将其放入[i + 1]。

我很想听到更好的想法或代码来做到这一点。在C.

while((j!=size-1)&&(a[size-1]!=a[i]))
{
     if(a[i]!=a[i+1])
     {
         i++;
         j=i;
     }
     if(a[i]==a[i+1])
     {
         j=i;
         while(a[i]==a[j])
               j++;
         a[i+1]=a[j];
         i++;
         if(j!=size-1)
              j=i;
     }
}
i++
for(;i<size;i++)
      a[i]=999;

我编辑了代码,现在我按照陈建议的方式编写代码。首先,我遍历数组,将999放在双打的位置,当我想切换时出现问题。这是我为重新排序数组而编写的代码: 每次我把999放在某处,算上++。

这是我完美给出的两个例子。谢谢大家。

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
void main()
{
    int *a;
    int i=0,j=0,size,count=0;
    printf("Enter the size of the array\n");
    scanf("%d", &size);
    a=(int *)calloc(size,sizeof(int));
    printf("Enter %d numbers\n",size);
    for(i=0;i<size;i++)
        scanf("%d",&a[i]);
    printf("The array recieved is :\n");
    for(i=0;i<size;i++)
        printf(" %d ", a[i]);
    i=0;
    printf("\n");
    for(i=0;i<size;i++)
    {
        if(a[i]==a[i+1])
        {
            j=i+1;
            while(a[i]==a[j])
            {
                a[j]=999;
                j++;
            }
            count++;
        }
    }
    while(count!=0)
    {
        for(i=0;i<size-1;i++)
        {
            j=i;
            if(a[j]==999)
            {
                a[j]=a[j+1];
                a[j+1]=999;
            }
        }
        count--;
    }
    printf("The new array is: \n");
    for(i=0;i<size;i++)
        printf(" %d ",a[i]);
    free(a);
    getch();
}

3 个答案:

答案 0 :(得分:0)

假设这是用于学校练习,并且您不在Google工作并且需要删除世界地图中的重复位置,那么您的算法听起来是正确的。

对于非常多的潜在的dublicates,并且假设列表已经排序,您可以使用基于搜索最近的较大元素的方法,然后通过测量两个元素之间的距离,您可能会发现更有效。

答案 1 :(得分:0)

这是一种在 O(n)

中运行的一般方法

假设:输入数组不包含999(如果确实如此,则只需使用不同的标记值):

  • 遍历数组一次:
    • 对于每个元素,请展望下一个元素
    • 如果它与当前元素重复,请将其更改为999
    • 继续向前看并将重复项标记为999,直至找到不同的元素。
  • 你想要最后的所有999,所以现在,保留2个单独的指针:
    • 用于跟踪数组中第一个X的位置的索引999
    • 另一个索引num,用于跟踪我们在交换过程中的位置
  • 再次遍历数组,使用这两个指针将所有有效数字与999交换。

这可能听起来很混乱,所以这是使用你的一个例子的伪动画: (使用W作为哨兵代替'999`以便于阅读)

1,1,2,3,4,4,5,6,6,
1,W,2,3,4,4,5,6,6,
1,W,2,3,4,W,5,6,6,
1,W,2,3,4,W,5,6,W,
1,2,W,3,4,W,5,6,W,
1,2,3,W,4,W,5,6,W,
1,2,3,4,W,W,5,6,W,
1,2,3,4,5,W,W,6,W,
1,2,3,4,5,6,W,W,W,

再次,但是这次用W标注数字后缀,这样你就可以看到发生了哪些互换:

1,1,2,3,4,4,5,6,6,
1,W1,2,3,4,4,5,6,6,
1,W1,2,3,4,W2,5,6,6,
1,W1,2,3,4,W2,5,6,W3,
1,2,W1,3,4,W2,5,6,W3,
1,2,3,W1,4,W2,5,6,W3,
1,2,3,4,W1,W2,5,6,W3,
1,2,3,4,5,W2,W1,6,W3,
1,2,3,4,5,6,W1,W2,W3,

答案 2 :(得分:0)

最简单的方法是首先删除重复项,然后使用999填充数组的其余部分。

删除重复项是O(n),填充数组是O(n)。