C++ 从数组中删除重复项的算法不';行不通
我有一个char数组,它有一些重复的值:C++ 从数组中删除重复项的算法不';行不通,c++,arrays,algorithm,C++,Arrays,Algorithm,我有一个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] ==
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
这是我删除重复值的算法:
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
char数组[20]={'A','B','C','D','E','F','E','A'};
整数长度=8;
for(int i=0;i
我曾尝试在论文上运行此算法,当我以书面形式执行此操作时,它似乎没有问题,但它在我的应用程序中不起作用。
j
允许[j+1]
超出长度
随着元素的移动,length
不再是有效数据的长度<代码>计数器可能是,但不显示如何初始化的代码
问题编辑为使用
长度--
而不是计数器--
,但错误在于将j
一直推进到包含j+1
的内部循环的末尾。由于内环将jet设置为i+1j
允许[j+1]
超出长度,因此也不需要将takei
一直延伸到外环的长度
随着元素的移动,length
不再是有效数据的长度<代码>计数器
可能是,但不显示如何初始化的代码
问题编辑为使用长度--
而不是计数器--
,但错误在于将j
一直推进到包含j+1
的内部循环的末尾。也不需要在外循环中将takei
一直扩展到length
,因为内循环将jet设置为i+1
您有未定义的行为
在外循环的第一次迭代(i=0)和内循环的最后一次迭代(j=7,其中长度=8)中,array[i]==array[j]
为真,因为两者都是“A”。但是您可以访问数组[j+1]
,这超出了范围
然后,当i=4和j=6时,将7处的值(现在被垃圾覆盖,但在本例中显然恰好是“A”)复制到索引6,从而得出错误的结果
您需要使元素的复制以j<(长度-1)
为条件,以避免UB。那么您至少应该在这个实例中得到正确的结果。您有未定义的行为
在外循环的第一次迭代(i=0)和内循环的最后一次迭代(j=7,其中长度=8)中,array[i]==array[j]
为真,因为两者都是“A”。但是您可以访问数组[j+1]
,这超出了范围
然后,当i=4和j=6时,将7处的值(现在被垃圾覆盖,但在本例中显然恰好是“A”)复制到索引6,从而得出错误的结果
您需要使元素的复制以j<(长度-1)
为条件,以避免UB。那么您至少应该在这个实例中得到正确的结果。虽然我知道它不能直接解决问题,但下面是一个更好的代码替代方案,您可以通过它避免此类问题(向量初始化需要C++11):
std::在{'A','B','C','D','E','F','E','A'中的向量;
std::向量输出;
std::sort(in.begin()、in.end());
std::unique_copy(in.begin()、in.end()、std::back_inserter(out));
如果您不需要副本,您也可以使用std::unique
而不是std::unique\u copy
虽然我知道它不能直接解决问题,但下面是更好的代码替代方案,您可以通过它避免此类问题(向量初始化需要C++11):
std::在{'A','B','C','D','E','F','E','A'中的向量;
std::向量输出;
std::sort(in.begin()、in.end());
std::unique_copy(in.begin()、in.end()、std::back_inserter(out));
如果您不需要副本,也可以使用std::unique
而不是std::unique\u copy
它只在i=0到3之间工作
当i=4时,数组[4]='E',数组[j]='F',它通过。j++
当i=4时,数组[4]='E',数组[j]='E',数组[j]被设置为数组[j+1],即'A'
移位工作正常,但i的循环可能是数组的整个长度,而不是更改的长度,因为它在i=5时停止。它只在i=0到3之间工作
当i=4时,数组[4]='E',数组[j]='F',它通过。j++
当i=4时,数组[4]='E',数组[j]='E',数组[j]被设置为数组[j+1],即'A'
移位工作正常,但i的循环可能是数组的整个长度,而不是更改的长度,因为它在i=5时停止。您应该在if语句中添加另一个for循环
检查以下代码:
char array[20] = {'A', 'B', 'C', 'D', 'E', 'F', 'E', 'A'};
整数长度=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;
for(inti=0;i您应该在if语句中添加另一个for循环
检查以下代码:
char array[20] = {'A', 'B', 'C', 'D', 'E', 'F', 'E', 'A'};
整数长度=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;
for(int i=0;我猜counter
是结果长度。很抱歉,我在这里发帖时没有重写它。它应该是长度而不是计数器。你的“删除副本”步骤可靠地创建了一个新的副本。而不是a[j]==a[i]
你现在有了a[j]==a[j+1]
.Always可能会学习在调试器中单步执行。每次都会“尝试在纸上运行”。你发布的不是算法,而是代码。我猜计数器
是结果长度。很抱歉,我在这里发布时没有重写它。它应该是长度而不是计数器。你的“重复删除”步骤可靠地创建了一个新的副本。您现在拥有的不是a[j]==a[i]
,而是a[j]==a[j+1]
。可能会一直学习在调试器中单步执行。比“尝试在纸上运行”更好