Неправильный цикл / Переполнение стека чтения

Я только учусь C ++. Я написал программу, которая показывает повторяющиеся буквы в строке (я также должен посчитать, сколько раз повторяется это письмо). Дело в том, что когда я запускаю свой код, чтобы получить повторяющиеся буквы из предложения. Это работает хорошо для некоторых, но не для некоторых. Например: «привет там» работает хорошо, возвращая h и e, но что-то вроде «люди хороши» возвращает peeeeee. Повторное письмо должно быть показано только один раз. Укажите на проблему, пожалуйста. Я предположил, что это связано с циклом, но не могу понять это точно.

void repeatWord(string sentence)
{
for(int i=0; i<sentence.length(); i++)
for(int j=i+1; j<sentence.length(); j++)
if((!isspace(sentence[i]))&&(sentence[i] == sentence[j])){
cout<<sentence[i]<<endl;
}
return;
}

0

Решение

Проблема в вашем внутреннем цикле. Он отображает букву один раз каждый раз, когда встречается. Кроме того, вы не выходите из цикла после просмотра дубликата, поэтому вы получаете экспоненциальный беспорядок.

Лучший способ — просто записать, сколько раз вы видели письмо. Для этого требуется всего один цикл и массив:

int count[256] = {0};
for( int i = 0; i < sentence.length(); i++ ) {
char c = sentence[i];
if( isalpha(c) && count[c]++ == 1 ) cout << c;
}

Вместо массива вы можете использовать std::set, Это было бы более уместно, если бы вы работали с Unicode. Тем не менее, мы просто имеем дело с char здесь, что составляет 8 бит почти на каждой архитектуре, на которой вы, вероятно, будете практиковаться.


Небольшой бонус в этом случае заключается в том, что вы вычисляете частоты букв. Вы можете вывести их следующим образом:

for( int c = 0; c < 256; c++ ) {
if( count[c] ) cout << (char)c << " : " << count[c] << endl;
}

Если вы хотите вывести счет без учета регистра, один из способов сделать это так:

for( int c = 'a'; c <= 'z'; c++ ) {
int total = count[c] + count[toupper(c)];
if( total ) cout << (char)c << " : " << total << endl;
}
3

Другие решения

Избавиться от повторяющихся букв легко: просто вставьте в <set> или удалите буквы после того, как вы их увидите. Вставка в набор более эффективна, однако:

set<char> letters;
for(int i=0; i<sentence.length(); i++)
for(int j=i+1; j<sentence.length(); j++)
if((!isspace(sentence[i]))&&(sentence[i] == sentence[j])){
letters.insert(sentence(i));
}
for(auto &i : letters)
cout << i << endl;
1