数组中没有重复项

时间:2014-10-11 06:48:49

标签: java c# c arrays

 void RemoveDups(){
    int f=0;
    for(int i=1;i<nelems;i++){
        if(arr[f]==arr[i]){
            for(int k=i;k<nelems;k++)
            {
                arr[k]=arr[k+1];
            }
            nelems--;
        }
        if(i==(nelems+1)){
            f++;
           i=f+1; //increment again
        }
    }
}

这是我编写的用于从数组中删除重复元素的逻辑,但这根本不起作用?我应该做些什么改变才能使它工作?或者考虑到时间复杂性,人们有更好的逻辑来做同样的事情。我不想使用内置方法来实现这一目标。

7 个答案:

答案 0 :(得分:1)

int end = input.length;

    for (int i = 0; i < end; i++) {
        for (int j = i + 1; j < end; j++) {
            if (input[i] == input[j]) {
                int shiftLeft = j;
                for (int k = j + 1; k < end; k++, shiftLeft++) {
                    input[shiftLeft] = input[k];
                }
                end--;
                j--;
            }
        }
    }

答案 1 :(得分:0)

你有两个选项, C#有一个Distinct()Linq表达式,它将为你做这个(错过了Java标签),但是如果你需要删除项目,你有没有考虑过排序首先列出,然后将当前项目与前一项目进行比较,如果它们相同,则将其删除。这意味着您的二次检测只能在阵列中运行一次。

如果您担心排序,可以轻松实现有效的冒泡排序或实现这种效果

答案 2 :(得分:0)

我认为你可以使用Set Collection

将所有值复制到HashSet,然后使用Iterator访问值

Set<Integer> hashset= new HashSet<Integer>();

答案 3 :(得分:0)

在将examlpe arr [0]与arr [5]进行比较后,您永远不会减少i,您永远不会测试arr[1] == arr[2]

你需要在增加f。

之后开始一个新循环(i)

for(int f=0;f<nelems-1;f++)
{
  for(int i=f+1;i<nelems;i++)
  {
   ...
  }
}

使用这个嵌套的for循环,你可以比较数组的每两个元素。

答案 4 :(得分:0)

一个好的开始是消除重复元素而不缩小最后完成的数组:

public class run2 extends Thread {

public static void main(String[] args) {
    int arr[] = { 1, 2, 2, 3, 5, 6, 5, 5, 6, 7 };

    for (int i = 0; i < arr.length; i++) {
        for (int j = i + 1; j < arr.length; j++) {
            if (arr[j] == -1)
                j++;

            if (arr[i] == arr[j])
                arr[j] = -1;
        }
    }

    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i] + ",");
    }
    System.out.println();
    for (int i = 0; i < arr.length; i++) {
        if (arr[i] == -1) {
            for (int j = i; j < arr.length; j++) {
                if (arr[j] != -1) {
                    arr[i] = arr[j];
                    arr[j] = -1;
                    break;
                }

            }

        }
    }

    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i] + ",");
    }
}

}

答案 5 :(得分:0)

据我所知,从你的代码中,你将每个从索引0开始的值与元素的其余部分进行比较,当你看到位于索引f的元素时,你试图移动整个数组并递减数组的大小(nelems)。看看行号。 11

if(i==(nelems+1)){
            f++;
            i=f+1;

问题是当我被设置为f + 1时,我将再次在for循环中递增以进行下一次迭代。所以基本上我开始从f + 2开始比较。而且你也在比较我(nelems + 1) )考虑到nelems递减的情况,但你没有考虑这种情况,当我到达终点而不减少nelems在那种情况下我永远不会等于(nelems + 1)。现在考虑你的逻辑,你可以做2件事。

1.这是你的工作代码。

for(int i=1;i<nelems;i++){
        if(arr[f]==arr[i]){
            for(int k=i+1;k<nelems;k++)
            {
                arr[k-1]=arr[k];
            }
            if(i==(nelems-1)){
                f++;
                i=f;
            }
            nelems--;   
        }
        if(i==(nelems-1)){//end of the loop
           f++;
           i=f; //increment again
    }
}

2.你可以使用外部for循环,一旦内部for完成,它将增加f值。

void RemoveDups(){
    for(int f=0;f<nelems;++f){
        for(int i=1;i<nelems;i++){
            if(arr[f]==arr[i]){
                for(int k=i;k<nelems;k++)
                    arr[k]=arr[k+1];
                nelems--;
            }
         }
       }
    }

现在您的问题已经解决,但代码的时间复杂度将为(O(N ^ 3))。

现在不用在第4行移动整个数组,而只需将arr [f]与最后一个元素交换。

if(arr[f]==arr[i]){
        swap(arr[f],arr[nelems-1]);   
        nelems--;
  }

它会将时间复杂度从O(N ^ 3)减少到O(N ^ 2)。

现在我建议你使用我的方法

1.只需对数组进行排序。它将在O(NlogN)中完成。 2.现在使用一个for循环你可以得到你想要的东西。

void RemoveDups(){
        int k=0,i;
            for(i=1;i<nelems;++i){
             while(arr[i]==arr[i-1])
                 ++i;
             arr[k++]=arr[i-1];
           }
    arr[k++]=arr[i-1];
}

现在基本上你有一个大小为k的数组,它按排序顺序包含非重复元素,我的解决方案的时间复杂度为O(NlogN)。

答案 6 :(得分:0)

改编此代码:

public static int[] removeDuplicates(int[] numbersWithDuplicates) {

        // Sorting array to bring duplicates together      
        Arrays.sort(numbersWithDuplicates);     

        int[] result = new int[numbersWithDuplicates.length];
        int previous = numbersWithDuplicates[0];
        result[0] = previous;

        for (int i = 1; i < numbersWithDuplicates.length; i++) {
            int ch = numbersWithDuplicates[i];

            if (previous != ch) {
                result[i] = ch;
            }
            previous = ch;
        }
        return result;
}