Поэтому я пытаюсь найти символы на расстоянии X от каждого символа, через который я перебираю. Так что для примера ….
nearby("abcdefg", 2)
Должен возвращать набор с каждым символом в качестве ключа и его значения рядом на расстоянии 2. Это должно выглядеть следующим образом …
dictionary('a' -> set(a, b, c), 'b' -> set(a, b, c, d), 'c' -> set(a,b,c,d,e))
Мой код сейчас выглядит так …
dictionary<char, set<char>> near(const std::string word, int dist) {
dictionary<char, set<char>> map;
for (int x = 0; x < word.size(); x++) {
for (char letter : word.substr(std::max(0, x - dist), std::min(dist + 1, int(word.size()))))
map[word[x]].insert(letter);
}
return map;
}
Краткое описание вопроса:
— Однако он работает по большей части из-за подстроки в C ++. Я не могу указать, что мне нужны все символы с индексом от 0 до 4. Вместо этого он индексирует в 0, а затем включает в себя все, что находится в диапазоне от 4. Это проблематично, когда Я хочу вернуться назад, чтобы включить символы 4 буквы в передней а также сзади.
На данный момент мой код будет правильным, но в конце оставьте только один символ. Так это выглядит вместо этого …
nearby(abcdefg, 2)
dictionary('c' -> set(a,b,c))
Это оставляет d.
Вам просто нужно:
const auto start = std::max(0, x-dist);
const auto end = std::min(x+dist+1, int(word.size());
const auto len = end - start;
const auto substring = word.substr(start,len);
auto &the_set = map[word[x]];
for (const auto letter : substring)
the_set.insert(letter);
Как отмечено в комментариях, это сломается, если word.size()
> INT_MAX
, Решение сделать все в size_t
(вы мог сделать все это в std::string::size_t
но это смехотворно многословно, и на самом деле ничего вам не дает).
dictionary<char, set<char>> near(const std::string word, size_t dist) {
dictionary<char, set<char>> map;
for (size_t x = 0; x < word.size(); x++) {
const auto start = (x > dist) ? x-dist : 0; // Beware underflow
const auto end = std::min(x+dist+1, word.size());
const auto len = end - start;
const auto substring = word.substr(start,len);
auto &the_set = map[word[x]];
for (const auto letter : substring)
the_set.insert(letter);
}
}
Эта версия имеет то преимущество, что gcc скомпилирует ее с -Werror -Wall
(предыдущая версия жаловалась бы на сравнение со знаком и без знака) и не имеет приведений (всегда хороший знак).
Еще лучше была бы версия, где start
а также end
были итераторы в word
— в этот момент вам не нужно создавать подстроку совсем (Вы можете просто посмотреть на символы в оригинальном слове).
Других решений пока нет …