Доступ к массиву целых по значению символа - PullRequest
0 голосов
/ 31 октября 2018

Вот код для подсчета вхождений каждого символа в строке:

int cnt[1000];
string s = "fooooobar";
for (char i : s) cnt[i]++;
cout << cnt['o'] << '\n';
cout << cnt['a'] << '\n';
cout << cnt['r'] << '\n';
cout << cnt['b'] << '\n';

Выход 1:

5
1
33262
129355441

Выход 2:

5
1
33262
328199857

Выход 3:

5
1
33262
-1913409871

Выход 4:

5
1
33262
-826184015

Как получить доступ к массиву int значений, индексирующих со значениями char для подсчета определенных случаев появления символа?

Почему первые 2 результата верны, третий недействителен, а четвертый недействителен и каждый раз отличается?

Я использую компилятор g ++ следующим образом:

g++ -std=c++11 -Wall filename.cpp -o

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Ваша проблема в том, что вы забыли установить массив cnt на 0 для всех индексов, потому что вы только что объявили его и не инициализировали каждый cnt[i]=0 для каждого i-го элемента, и по умолчанию каждый i-й элемент в cnt получает неопределенное (или случайное) значение, и из-за этого вы получаете неверный результат. Вам просто нужно использовать отладчик для просмотра того, что происходит в вашем коде, или просто cout каждое значение i и cnt[i] до cnt[i]++ и после, чтобы вы могли видеть, что происходит.

Вот мой фиксированный код:

int cnt[1000];

string s = "fooooobar";
for (int i = 0; i < 1000; i++){
    cnt[i] = 0;
}

for (char i : s){
    cout << "i = " << i << "cnt[" << i << "] = " << cnt[i] << endl;
    cnt[i]++;
    cout << "i = " << i << "cnt[" << i << "] = " << cnt[i] << endl;
}

cout << cnt['o'] << '\n';
cout << cnt['a'] << '\n';
cout << cnt['r'] << '\n';
cout << cnt['b'] << '\n';

когда вы закончите отладку, просто удалите функции cout, потому что они вам не нужны :) С наилучшими пожеланиями

0 голосов
/ 31 октября 2018

Самое простое решение - инициализировать все значения в вашем массиве нулями:

int cnt[1000] = {0};

Вы должны сделать это явно, если только вы не используете глобальные переменные.

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

Обмен int cnt[1000]; на std::map<char,int> Ваш код работает отлично:

std::map<char,int> cnt; // <<<<<<<<
string s = "fooooobar";
for (char i : s) cnt[i]++;
cout << cnt['o'] << '\n';
cout << cnt['a'] << '\n';
cout << cnt['r'] << '\n';
cout << cnt['b'] << '\n';

См. Рабочую демоверсию .

При использовании стандартного c ++ это выглядит как естественный и наиболее удобный подход для вашей задачи (если только вам не нужно выполнять микрооптимизации при возникновении проблем с производительностью конкретного случая).

...