Дана строка, где слова разделены пробелами и двоеточиями. Нужно посчитать количество слов длиной меньше k и вернуть контейнер этих слов. Циклами пользоваться запрещено, разрешены только STL алгоритмы и контейнеры. Нет даже представления, как это всё можно сделать. Мне бы хотя бы идею.
Вот поиск символьной комбинации в стандартном потоке ввода, не через циклы while
, а с использованием предиката и алгоритма std::find_if
. Предлагаю такой вариант решения:
std::find_if(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
Predicate());
где Predicate()
вызов конструктора класса Predicate с определенным оператором ().
Предикат Вы можете реализовать для проверки того, является ли считанный объект словом, а не двоеточием (хотя из вопроса не до конца ясно, как именно разделены слова, приведите конкретный пример), и, если является словом, то проверить его длину. Смотрите класс string
и функцию-член length()
, например.
Пример реализации класса Predicate
:
// глобальными эти переменные не стоит делать, хотя бы в namespace надо их засунуть
std::uint64_t counter = 0; // счетчик всех слов в вводимом тексте
std::map<std::string, int> container; // ключ - слово, значение - кол-во копий
class Predicate
{
Predicate() {}
void operator()(const std::string & str) // предполагается ввод word : word : word и т.д.
{
if (str != “:” && str.length() < k)
{
++counter;
++container[str];
}
}
};
Еще дам пример использования std::istream_iterator
. Считывание данных с итератором:
if (iit != eos) str = *iit;
++iit;
где iit
- это std::istream_iterator<string>
, а eos
- итератор того же типа, означающий конец ввода. Вы легко сможете найти в интеренете информацию по использованным в моем ответе возможностям C++, см. этот сайт и этот сайт.
Первое, что приходит в голову по вашей задаче:
#include <iostream>
#include <algorithm>
#include <string>
#include <list>
std::list<std::string> result;
std::string str;
int size = /*Необходимая длина*/
struct Func
{
Func() {}
void operator()(char & letter)
{
if (!str.empty())
{
if (letter == ':' || letter == ' ')
{
size_t pos = str.find_first_of(":");
std::string temp = str.substr(0, pos);
if (temp.length() < size) { result.push_back(temp); }
str.erase(0, pos + 1);
}
else if (str.find_first_of(":") == std::string::npos)
{
std::string temp = str.substr(0, str.length());
if (temp.length() < size) { result.push_back(temp); }
str.clear();
}
}
}
};
int main()
{
std::getline(std::cin, str);
std::for_each(str.begin(), str.end(), Func());
/*Далее работа с контейнером result*/
}
Вот такой кусок кода вызовет объект f
со всеми словами из строки s
std::for_each(std::istream_iterator<std::string>(std::istringstream(s)), std::istream_iterator<std::string>(), f);
Проблемы две:
1. Слова выделяются по стандартным пробельным символам, поэтому проще всего перед вызовом заменить в строке двоеточия на пробелы.
2. f
не просто функция, а должна "куда-то" вернуть контейнер и количество, поэтому придется сделать класс, инициализирующийся ссылкой на контейнер, с членом operator ()( std::string &s)
, который проверит длину строки и пополнит контейнер.
Я делал бы так, создаю стек, прохожусь итератором по строке, каждую букву записываю в стек, вижу пробел или двоеточие, смотрю стек, добавляю в контейнер слово из стека если оно подходит, чищу стек и т.д.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Под Windows есть функция создания нового процесса CreateProcess которая создает процесс в новом окне, и в нее можно передать флаг CREATE_NO_WINDOW, что бы это...
При использовании QLineEdit в приложении под андоид (Qt 57, Android 6