Не понимаю работу алгоритма написанной на C++ функции
В универе задача:
Подсчитать количество различных символов в строке.
Преподаватель дал пример кода решения задачи:
#include <iostream>
using namespace std;
string uniqueChars(string str) {
string newStr = "";
bool arr[128];
for(int i = 0;i < 128; i++) {
arr[i] = false;
}
char c;
for(int i = 0, n = str.length();i < n; i++) {
c = str[i];
if(c < 0 || c > 127) {
continue;
}
if(!arr[c]) {
arr[c] = true;
newStr += c;
}
}
return newStr;
}
int main(void) {
string a = "Hello It's a wonderful world";
string b = uniqueChars(a);
cout << a << " => " << a.length() << "\n" <<
b << " => " << b.length();
return 0;
}
Я понял что программа состоит из двух частей: создание функции и применение этой функции к заданной строке. Но я не понимаю как работает функция.
Зачем мы создаём массив логического типа с количеством элементов 128? Почему именно 128? Почему каждому элементу присваиваем false
?
bool arr[128];
for(int i = 0;i < 128; i++) {
arr[i] = false;
}
Что происходит вот в этой части? ||
это аналог and
? Что значит continue
? Что значит !arr[c]
? Зачем мы меняем значение символа c
в массиве на True
?
if(c < 0 || c > 127) {
continue;
}
if(!arr[c]) {
arr[c] = true;
newStr += c;
}
}
Ответы (1 шт):
Я постарался максимально понятно прокомментировать основные строки:
string uniqueChars(string str) {
string newStr = ""; // новая строка содержащая только уникальные символы
bool arr[128]; // массив флагов:
// использовался ли символ равный индексу элемента
// в этом массиве (пример: `D` = 68 индекс)
for(int i = 0;i < 128; i++) {
arr[i] = false; // изначально нет использованных символов
}
char c;
for(int i = 0, n = str.length();i < n; i++) { // проходим по всей строке
c = str[i]; // преобразуем символ в число от 0 до 127
if(c < 0 || c > 127) {
continue; // если символ выходит за границы 0 и 127 то
// переходим к следующему символу
}
if(!arr[c]) { // только если символ не был использован ранее
arr[c] = true; // помечаем что он был использован сейчас
newStr += c; // и добавляем символ в результирующую строку
}
}
return newStr; // возвращаем строку уникальных символов
}
Как указано в таблице ниже все символы можно получить до 127 кода имеются в виду обычные текстовые символы применяющиеся в тексте, по правде говоря они начинаются с 33 символа если не считать пробел, но мы не можем начать массив с 32 индекса (с пробелом), поэтому в любом случае у нас есть эти лишние элементы в нашем массиве, чтобы их не было мы могли бы оптимизировать код по использованию памяти сделав следующее:
c = str[i] - 32
тогда пробел будет 0 индексом, а сам массив можно сделать длиной в 96 ну и разумеется тогда нужно соответсвенно исправить другие части кода такие как условие диапазона.