Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 这段代码中的错误是什么?_C_Arrays_Duplicate Removal - Fatal编程技术网

C 这段代码中的错误是什么?

C 这段代码中的错误是什么?,c,arrays,duplicate-removal,C,Arrays,Duplicate Removal,基于对一个不同(类似)问题的答案SO给出的逻辑,为了以O(N)时间复杂度删除数组中的重复数字,我用C实现了该逻辑,如下所示。但是我的代码的结果不会返回唯一的数字。我尝试过调试,但无法获得其背后的逻辑来修复此问题 int remove_repeat(int *a, int n) { int i, k; k = 0; for (i = 1; i < n; i++) { if (a[k] != a[i]) {

基于对一个不同(类似)问题的答案SO给出的逻辑,为了以O(N)时间复杂度删除数组中的重复数字,我用C实现了该逻辑,如下所示。但是我的代码的结果不会返回唯一的数字。我尝试过调试,但无法获得其背后的逻辑来修复此问题

int remove_repeat(int *a, int n)
{
    int i, k;

    k = 0;
    for (i = 1; i < n; i++)
    {
        if (a[k] != a[i]) 
        {
            a[k+1] = a[i];
            k++;            
        }
    }
    return (k+1);
}

main()
{
    int a[] = {1, 4, 1, 2, 3, 3, 3, 1, 5};
    int n;
    int i;

    n = remove_repeat(a, 9);

    for (i = 0; i < n; i++)
            printf("a[%d] = %d\n", i, a[i]);


} 
int remove\u repeat(int*a,int n)
{
int i,k;
k=0;
对于(i=1;i
1] 以上代码中删除重复项的错误


2] 此问题的任何其他O(N)或O(NlogN)解决方案。它的逻辑?

您需要两个循环,一个用于遍历源,另一个用于检查目标数组中的每个项

你不会得到O(N)

[编辑] 您链接到的文章建议使用排序后的输出数组,这意味着在输出数组中搜索重复项可以是二进制搜索…即O(LogN)

  • 在O(n log n)时间内进行堆排序
  • 在O(n)时间内迭代,用哨兵值替换重复元素(例如
    INT\u MAX
  • 在O(n log n)中再次堆排序,以提取重复的元素

  • 仍然以O(n log n)为界。

    您的代码似乎要求对输入进行排序。使用未排序的输入进行测试时,代码不会删除所有重复项(仅相邻项)。

    您的逻辑错误,因此代码也错误。在编写代码之前,自己完成逻辑。 我建议使用一种O(NlnN)方法,并对heapsort进行修改。 通过heapsort,我们从a[i]到a[n],找到最小值并用a[i]替换,对吗? 现在是修改,如果最小值与[i-1]相同,则交换最小值和[n],将数组项的数量减少1。 它应该以O(NlnN)的方式来实现这一点。

    如果整数的数量事先已知,并且小于内存量,则可以得到O(N)解:)。进行一次传递以确定使用辅助存储的唯一整数,然后进行另一次传递以输出唯一值

    下面的代码是用Java编写的,但希望您能理解

    int[] removeRepeats(int[] a) {
        // Assume these are the integers between 0 and 1000
        Boolean[] v = new Boolean[1000]; // A lazy way of getting a tri-state var (false, true, null)
    
        for (int i=0;i<a.length;++i) {
           v[a[i]] = Boolean.TRUE;
        } 
    
        // v[i] = null => number not seen
        // v[i] = true => number seen
    
        int[] out = new int[a.length];
        int ptr = 0;
        for (int i=0;i<a.length;++i) {
            if (v[a[i]] != null && v[a[i]].equals(Boolean.TRUE)) {
                out[ptr++] = a[i];
                v[a[i]] = Boolean.FALSE;          
            }
        }
    
        // Out now doesn't contain duplicates, order is preserved and ptr represents how
        // many elements are set.
        return out;
    }
    
    int[]removeRepeats(int[]a){
    //假设这些是介于0和1000之间的整数
    Boolean[]v=new Boolean[1000];//获取三态变量的一种惰性方法(false、true、null)
    对于(int i=0;未看到i编号
    //v[i]=true=>所看到的数字
    int[]out=新的int[a.长度];
    int-ptr=0;
    
    对于(int i=0;i,您的代码只检查数组中的项是否与其前一项相同

    如果您的数组开始排序,这将起作用,因为特定数字的所有实例都是连续的

    如果您的数组没有从一开始就进行排序,这将不起作用,因为特定数字的实例可能不连续,因此您必须查看前面的所有数字,以确定是否已经看到一个

    要在O(N logn)时间内完成这项工作,您可以对数组进行排序,然后使用您已经拥有的逻辑从排序后的数组中删除重复项。显然,这只有在您能够重新排列数字时才有用

    如果要保留原始顺序,可以使用哈希表或位集之类的工具来跟踪是否已看到某个数字,并且仅在尚未看到/未看到时将每个数字复制到输出中。为此,我们更改当前的:

    if (a[k] != a[i])
        a[k+1] = a[i];
    
    例如:

    if (!hash_find(hash_table, a[i])) { 
        hash_insert(hash_table, a[i]);
        a[k+1] = a[i];
    }
    
    如果您的数字都在相当窄的范围内,或者您希望值是密集的(即,大多数值都存在),您可能希望使用位集而不是哈希表。这将只是一个位数组,设置为0或1以指示是否已看到特定的数字


    另一方面,如果您更关心复杂度的上限而不是平均情况,则可以使用基于平衡树的集合而不是哈希表。这通常会使用更多内存,运行速度也会更慢,但其预期复杂度和最坏情况复杂度基本相同(O(N log N))。在最坏的情况下,一个典型的哈希表从常数复杂度退化为线性复杂度,这将使您的总体复杂度从O(N)变为O(N2).

    您的代码仅在特定情况下有效。显然,您正在检查相邻值,但重复值可能会出现在数组中的任何位置。因此,这是完全错误的。

    尝试调试时您学到了什么?您的意图不清楚。我很清楚,它不起作用,请用您自己的话描述您试图编写的代码。@Cody-该逻辑试图构建一个从0到j的唯一数字的子数组。@Drakosha-上面还不清楚什么?试图实现一个逻辑,从数组中删除重复的元素(本例中为整数),并在同一数组中只返回唯一的元素,同时尝试在O(N)中完成时间复杂性。@goldenmean-我理解,问题是你的想法是什么,即你打算如何做到这一点。我想文章说的是“从元素a[1]到a[N]。在每个阶段i,[i]左边的所有元素都由元素a[0]到[j]组成一个排序堆。”.也就是说,对于i的每次迭代,a[]中i左边a中的元素都是通过这种逻辑获得的排序元素?我遗漏了什么吗?@Jeff-如果我也有-ve个数字,这就不起作用了,不是吗。找到一个数字的第一步可能会失败?有什么想法吗?@Drakosha所有的循环都在输入数组上,所以我认为(N) “还是我误解了?”@GoldenMean,如果你有一个受约束的宇宙(例如,数字在-50和50之间,那么你可以简单地转换值。它基本上是