所以我试图在部分填充的数组中删除重复的字符。该阵列是从我PC上的文件填充的。我的数组填充方法工作正常;但是,我的重复删除方法不是。这是我的方法:
void deleteRepeated(char array[], int* numberUsed)
{
for (int x = 0; x < *numberUsed ; x++)
{
cout << "Positions used: " << *numberUsed << endl;
for (int y = x+1; y < *numberUsed; y++ )
{
cout << "Positions used: " << *numberUsed << endl;
if (array[y] == array[x])
{
cout << "Positions used: " << *numberUsed << endl;
for (int z = y; z < *numberUsed; z++)
array[z] = array[z+1];
y--;
*numberUsed--;
cout << "Positions used: " << *numberUsed << endl;
}
}
}
}
我传递的是整个数组,以及该数组中使用的索引数。数组长度为10,而我的测试,我使用的是其中6个中的6个:{'g','g','n','o','r','e'}。我做错了什么?
注意:“cout&lt;&lt;”使用的位置:“&lt;&lt; * numberUsed&lt;&lt; endl”用于检查方法是否正确删除。在索引为z的最内层循环中,方法开始变得疯狂。
非常感谢任何帮助。
答案 0 :(得分:1)
每次找到重复时,都会减少使用的字符数
*numberUsed--;
但请记住控制第一个循环索引
for (int x = 0; x < *numberUsed ; x++)
所以试试这个
int count =*numberUsed;
for (int x = 0; x < count ; x++)
这样你就可以访问数组中的所有原始字符。
答案 1 :(得分:1)
(在我读到你关于STL的评论不被允许之前,我写了这个答案的第一部分,但我会留下它,因为我认为这是相当简洁的代码。)
您可以使用C ++标准库提供的功能。使用std::string
代替char数组(这几乎总是一个好主意),然后你可以执行以下操作(注意:C ++ 11只是因为unordered_set
和std::begin
):
#include <string>
#include <unordered_set>
#include <iostream>
#include <iterator>
std::string uniquechars(const std::string& s) {
std::unordered_set<char> uniquechars(std::begin(s), std::end(s));
std::string newstring(std::begin(uniquechars), std::end(uniquechars));
return newstring;
}
int main() {
std::string teststr("thisisanexamplesentence");
std::cout << "The unique characters of " << teststr << " are " << uniquechars(teststr) << std::endl;
}
请注意,它不会保留字符的原始顺序,因此如果需要,则不起作用。
如果你必须在没有标准库的情况下工作,你必须深入挖掘一下。上面的@TimChild已经很好地开始诊断您的程序有什么问题,但是有更有效的解决方案,例如保留您已经看过哪些字符的记录。当您使用char
时,我会考虑一个可以保存标记的位字段(256/8 = 32字节的额外开销)或者如果不是太多,只需要一个简单的bool数组(额外的开销256字节)。因为后者更容易实现,代码更清晰:
void deleteRepeated(char array[], int *numused) {
bool seenthischar[256] = {false};
char *readpointer = &array[0];
char *writepointer = &array[0];
int length = *numused;
for ( ;readpointer <= &array[0] + length; readpointer++) {
if (seenthischar[((unsigned char) *readpointer)]) {
*numused--;
} else {
seenthischar[((unsigned char) *readpointer)] = true;
*writepointer = *readpointer;
writepointer++;
}
}
}
这只有一个循环,所以它只需要经过一次数组,即它的时间复杂度在输入数组的长度上是线性的。