A string is given, where words are separated by spaces and colons. It is necessary to count the number of words with a length less than k and return the container of these words. It is forbidden to use cycles, only STL algorithms and containers are allowed. There is even no idea how this can be done. I would at least have an idea.
4 answers
Here is a search for a symbolic combination in the standard input stream, not through while loops, but using the predicate and the std::find_if . I propose this solution:
std::find_if(std::istream_iterator<std::string>(std::cin), std::istream_iterator<std::string>(), Predicate()); where Predicate() call to the constructor of the Predicate class with a specific operator ().
You can implement the predicate to check whether the object read is a word and not a colon (although it is not completely clear from the question how exactly the words are separated, give a specific example), and if it is a word, then check its length. See the string class and the length() member function, for example.
An example implementation of the Predicate class:
// глобальными эти переменные не стоит делать, хотя бы в 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]; } } }; I will also give an example of using std::istream_iterator . Data reading with iterator:
if (iit != eos) str = *iit; ++iit; where iit is std::istream_iterator<string> , and eos is an iterator of the same type, indicating the end of the input. You can easily find information on the C ++ features used in my answer on the Internet, see this site and this site .
The first thing that comes to mind for your task:
#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*/ } Such a piece of code will call object f with all the words from string s
std::for_each(std::istream_iterator<std::string>(std::istringstream(s)), std::istream_iterator<std::string>(), f); There are two problems: 1. Words are distinguished by standard whitespace characters, so the easiest thing is to replace the colon in the string with spaces before the call. 2. f not just a function, but must return the container and quantity "somewhere", so you have to make a class, initialized by reference to the container, with the member operator ()( std::string &s) , which checks the length of the string and replenishes the container.
I would do this, create a stack, iterate through the line, write each letter to the stack, see a space or a colon, look at the stack, add a word from the stack to the container if it fits, clean the stack, etc.
- @JeeOpp most often a small piece of code is much clearer than a verbal description. - Victor