void test_GetCloseMatches() { std::string arr[] = { "ape", "apple", "peach", "puppy"}; std::vector<string> possibilities(arr, arr + 4); auto cmes = difflib::GetCloseMatches("appel", possibilities); for (auto cm : cmes) { std::cout << cm << std::endl; } }
std::vector<std::string> CommandSystem::choose(const std::vector<std::string> &possible, const std::string &input) { #ifdef COMMAND_DEBUG std::cout << Utils::format("Testing {0} in", input); for (const auto &s : possible) std::cout << " " << s; std::cout << "\n"; #endif std::vector<std::pair<std::string, std::string::size_type> > possibilities(possible.size()); std::transform(possible.begin(), possible.end(), possibilities.begin(), [](const std::string &s) -> std::pair<std::string, std::string::size_type> { return std::make_pair(s, 0); }); for (std::string::size_type msgIndex = 0; msgIndex < input.length(); msgIndex++) { // Stop if the command is over if (Utils::isSpace(input[msgIndex])) { // Skip following whitespaces do { msgIndex++; } while (msgIndex < input.length() && Utils::isSpace(input[msgIndex])); break; } // Stop if only one command is left if (possibilities.size() == 1) { // Skip to end of command while (msgIndex < input.length() && !Utils::isSpace(input[msgIndex])) msgIndex++; continue; } decltype(possibilities) newPossibilities; // Filter possibilities for (std::size_t i = 0; i < possibilities.size(); i++) { std::string::size_type newPos = possibilities[i].first.find(input[msgIndex], possibilities[i].second); if (newPos != std::string::npos) newPossibilities.emplace_back(possibilities[i].first, newPos + 1); } // Ignore this character if there are no results // ATTENTION: This can probably lead to funny behaviour ;) if (!newPossibilities.empty()) possibilities = std::move(newPossibilities); } // Take the command with the lowest index std::string::size_type minIndex = std::string::npos; for (const auto &c : possibilities) { if (c.second < minIndex) minIndex = c.second; } for (std::size_t i = 0; i < possibilities.size(); i++) { if (possibilities[i].second != minIndex) { possibilities.erase(possibilities.begin() + i); i--; } } std::vector<std::string> result(possibilities.size()); std::transform(possibilities.begin(), possibilities.end(), result.begin(), [](const std::pair<std::string, std::string::size_type> &s) -> std::string { return s.first; }); #ifdef COMMAND_DEBUG std::cout << "Result:"; for (const auto &s : result) std::cout << " " << s; std::cout << "\n"; #endif return result; }