Не понимаю работу алгоритма написанной на 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 шт):

Автор решения: Daniil Loban

Я постарался максимально понятно прокомментировать основные строки:

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 ну и разумеется тогда нужно соответсвенно исправить другие части кода такие как условие диапазона.

введите сюда описание изображения

→ Ссылка