Простой инжектор - для этого объекта не определен конструктор без параметров

Алгоритм с одним проходом для этой проблемы может быть следующим:

  1. Если строка пуста, возвращаем 1
  2. , пусть переходы = число соседних пар пар (c1, c2), где c1 == ' ' и c2 != ' '
  3. , если предложение начинается с пробела, return transitions else return transitions + 1

Вот пример со строкой = «Очень, очень, очень, очень, очень большая собака съела мою домашнюю работу !!!!»

 i | 0123456789
c2 |  A very, very, very, very, very big dog ate my homework!!!!
c1 | A very, very, very, very, very big dog ate my homework!!!!
   |  x     x     x     x     x    x   x   x   x  x

Объяснение

Let `i` be the loop counter.

When i=0: c1='A' and c2=' ', the condition `c1 == ' '` and `c2 != ' '` is not met
When i=1: c1=' ' and c2='A', the condition is met
... and so on for the remaining characters

Этот алгоритм правильно обрабатывает случаи с несколькими пробелами

Вот два решения, которые я придумал с помощью

Наивное решение

size_t count_words_naive(const std::string_view& s)
{
    if (s.size() == 0) return 0;
    size_t count = 0;
    bool isspace1, isspace2 = true;
    for (auto c : s) {
        isspace1 = std::exchange(isspace2, isspace(c));
        count += (isspace1 && !isspace2);
    }
    return count;
}

Если вы тщательно подумаете, сможет свести этот набор операций к внутреннему продукту, что было сделано ниже.

Внутреннее prod-решение

size_t count_words_using_inner_prod(const std::string_view& s)
{
    if (s.size() == 0) return 0;
    auto starts_with_space = isspace(s.front());
    auto num_transitions = std::inner_product(
            s.begin()+1, s.end(), s.begin(), 0, std::plus<>(),
            [](char c2, char c1) { return isspace(c1) && !isspace(c2); });
    return num_transitions + !starts_with_space;
}
10
задан Steven 6 May 2018 в 06:28
поделиться