#include <iostream>
#include <string>
#include <regex>
#include <unordered_set>
#include <vector>
/*
Split a string into lowercase words.
This function:
- Normalizes the text to lowercase
- Uses a regex to extract alphabetic words
- Returns a vector of words
*/
std::vector<std::string> extractWords(const std::string& input)
{
std::vector<std::string> words;
// Convert to lowercase for consistent comparison
std::string normalized;
normalized.reserve(input.size());
std::transform(input.begin(), input.end(), std::back_inserter(normalized),
[](unsigned char c) { return std::tolower(c); });
// Regex to match sequences of letters
std::regex wordPattern("[a-z]+");
auto begin = std::sregex_iterator(normalized.begin(), normalized.end(), wordPattern);
auto end = std::sregex_iterator();
for (auto it = begin; it != end; ++it)
words.push_back(it->str());
return words;
}
/*
Find common words between two strings.
This function:
- Extracts words from both strings
- Stores words from the first string in an unordered_set for fast lookup
- Checks which words from the second string appear in the set
- Avoids duplicates by using another unordered_set
*/
std::vector<std::string> findCommonWords(const std::string& a, const std::string& b)
{
std::vector<std::string> wordsA = extractWords(a);
std::vector<std::string> wordsB = extractWords(b);
std::unordered_set<std::string> setA(wordsA.begin(), wordsA.end());
std::unordered_set<std::string> seen;
std::vector<std::string> common;
common.reserve(std::min(wordsA.size(), wordsB.size()));
for (const auto& w : wordsB) {
if (setA.count(w) && !seen.count(w)) {
common.push_back(w);
seen.insert(w);
}
}
return common;
}
int main()
{
std::string s1 = "The quick brown fox jumps over the lazy dog.";
std::string s2 = "A lazy dog sleeps while the quick fox runs away.";
auto common = findCommonWords(s1, s2);
std::cout << "Common words:\n";
for (const auto& w : common)
std::cout << w << "\n";
}
/*
run:
Common words:
lazy
dog
the
quick
fox
*/