【问题标题】:Algorithm, that removes duplicates from array doesn't work从数组中删除重复项的算法不起作用
【发布时间】:2014-11-04 13:36:11
【问题描述】:

我有一个 char 数组,其中有一些重复值:

A B C D E F E A

这是我删除重复值的算法:

char array[20] = {'A', 'B', 'C', 'D', 'E', 'F', 'E', 'A'};
int length = 8;

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

EXPECTED OUTPUT: A B C D E F
OUTPUT: A B C D E F A

我曾尝试在论文上运行此算法,当我以书面形式执行此操作时似乎没问题,但它在我的应用程序中不起作用。

【问题讨论】:

  • 我猜counter 是结果长度。
  • 对不起,我在这里发帖时没有重写它。它应该是长度而不是计数器。
  • 您的“重复删除”步骤可靠地创建了一个新副本。你现在有a[j] == a[j+1],而不是a[j] == a[i]。总是
  • 或许了解调试器中的单步执行。 Beats 每次都“试图在纸上运行”。
  • 你发的不是算法,是代码。

标签: c++ arrays algorithm


【解决方案1】:

您应该在 if 语句中添加另一个 for 循环 检查下面的代码:

char array[20] = {'A', 'B', 'C', 'D', 'E', 'F', 'E', 'A'};

int 长度 = 8;

for(int i = 0; i <= length; i++){

        for(int j = i+1; j <= length; j++){

                if(array[j] == array[i]){

                            for(int x = j+1; x <=length; x++){

                                    array[j]=array[x];

                                    }
                            length--;
                            }

                }

        }

for(int z = 0; z <= length; z++){
      cout << array[z] << " ";
      }
      cout << endl;

【讨论】:

    【解决方案2】:

    你有未定义的行为。

    在外循环的第一次迭代(i = 0)和内循环的最后一次迭代(j = 7,其中长度 = 8)中,array[i] == array[j] 为真,因为两者都是“A”。但是随后您访问了array[j+1],这超出了范围。

    然后,当 i = 4 和 j = 6 时,您将 7 处的值(现在被垃圾覆盖,但在您的情况下显然恰好是“A”)到索引 6,给出错误的结果你看到.

    您需要以j &lt; (length - 1) 为条件复制元素以避免UB。那么你至少应该在这种情况下得到正确的结果。

    【讨论】:

    • 问题编辑显示:真实数据后面有多余的空间,包含NUL。
    • 我已经把j
    • @EvaldasB 好吧,那也是错误的。你需要检查最后一个元素,但你不应该从它后面复制。
    【解决方案3】:

    j &lt; length 允许[j + 1] 超出长度

    随着元素的移动,length 不再是有效数据的长度。 counter 可能是,但你没有显示它是如何初始化的代码。

    问题已编辑为使用length-- 而不是counter--,但错误在于将j 一直推进到包含j + 1 的内部循环的末尾。也无需在外循环中将 take i 一直延伸到 length,因为内循环将 jet 设置为 i + 1

    【讨论】:

    • 所以在第一个循环中设置了 i
    【解决方案4】:

    虽然我知道它不能直接解决问题,但这里有更好的代码替代方案,可以避免此类问题(向量初始化需要 C++11):

    std::vector<char> in{'A', 'B', 'C', 'D', 'E', 'F', 'E', 'A'};
    std::vector<char> out;
    
    std::sort (in.begin(),in.end());
    
    std::unique_copy(in.begin(), in.end(), std::back_inserter(out));
    

    如果不需要副本,也可以使用std::unique代替std::unique_copy

    【讨论】:

    • std::unique_copy 只删除连续的重复项
    • 感谢您的评论。所以必须提前进行排序。
    • 你必须排序in,而不是out :)
    【解决方案5】:

    它只适用于 i=0 到 3。

    当 i=4,array[4] = 'E',array[j] = 'F' 时,通过。 j++ 当i=4时,array[4] = 'E',array[j] = 'E',array[j]设置为array[j+1],即'A'。

    移位工作正常,但 i 的循环可能是数组的整个长度,而不是更改后的长度,因为它在 i=5 时停止。

    【讨论】:

      猜你喜欢
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-18
      • 1970-01-01
      • 2011-06-29
      • 2011-01-04
      相关资源
      最近更新 更多