Welcome to collectivesolver - Programming & Software Q&A with code examples. A website with trusted programming answers. All programs are tested and work.

Contact: aviboots(AT)netvision.net.il

Semrush - keyword research tool

Turn ChatGPT, Claude, Gemini, And CoPilot Into Your Personal Assistant, Business Coach, Content Creator, And More

AFFILIATE MARKETING Your all-in-one performance engine Manage affiliates, creators, and customer referrals in one unified platform—turning every partnership into measurable growth
Secure & Reliable Web Hosting, Free Domain, Free SSL, 1-Click WordPress Install, Expert 24/7 Support

Boost your online presence with premium web hosting and servers

Disclosure: My content contains affiliate links.

42,596 questions

55,330 answers

573 users

How to determine if two sentences talk about similar topic in C++

1 Answer

0 votes
#include <iostream>
#include <string>
#include <unordered_set>
#include <sstream>

/*
    Determine whether two sentences talk about similar topics
    using a simple, efficient NLP approach in idiomatic C++.

    Steps:
      1. Normalize text (lowercase + remove punctuation)
      2. Tokenize into words
      3. Remove stop-words
      4. Compute Jaccard similarity between word sets
      5. Compare against a threshold
*/

// Normalize a sentence: lowercase + remove punctuation
std::string normalize(const std::string& s) {
    std::string out;
    out.reserve(s.size());

    for (char ch : s) {
        if (std::isalnum(static_cast<unsigned char>(ch)) || std::isspace(static_cast<unsigned char>(ch))) {
            out.push_back(std::tolower(static_cast<unsigned char>(ch)));
        }
        // punctuation is skipped
    }
    return out;
}

// Tokenize into words and remove stop-words
std::unordered_set<std::string> tokenize(const std::string& s) {
    static const std::unordered_set<std::string> stop_words{
        "the","a","an","and","or","but","is","are","was","were",
        "to","of","in","on","for","with","as","by","that"
    };

    std::unordered_set<std::string> words;
    std::stringstream ss(s);
    std::string word;

    while (ss >> word) {
        if (!stop_words.count(word)) {
            words.insert(word);
        }
    }
    
    return words;
}

// Compute Jaccard similarity: |A ∩ B| / |A ∪ B|
double jaccard_similarity(const std::unordered_set<std::string>& A,
                          const std::unordered_set<std::string>& B) {
    size_t intersection = 0;

    for (const auto& w : A) {
        if (B.count(w)) {
            ++intersection;
        }
    }

    size_t union_size = A.size() + B.size() - intersection;
    
    return union_size == 0 ? 0.0 : static_cast<double>(intersection) / union_size;
}

// Determine if two sentences discuss similar topics
bool similar_topics(const std::string& s1, const std::string& s2, double threshold = 0.25) {
    auto n1 = normalize(s1);
    auto n2 = normalize(s2);

    auto w1 = tokenize(n1);
    auto w2 = tokenize(n2);

    double sim = jaccard_similarity(w1, w2);
    std::cout << "Similarity score: " << sim << "\n";

    return sim >= threshold;
}

int main() {
    std::string sentence1 = "Cats are wonderful pets that enjoy playing.";
    std::string sentence2 = "Many people keep dogs or cats as household animals.";

    std::cout << "Sentence 1: " << sentence1 << "\n";
    std::cout << "Sentence 2: " << sentence2 << "\n\n";

    bool result = similar_topics(sentence1, sentence2);

    std::cout << "Do they talk about similar topics? "
              << (result ? "Yes" : "No") << "\n";
}


/*
run:

Sentence 1: Cats are wonderful pets that enjoy playing.
Sentence 2: Many people keep dogs or cats as household animals.

Similarity score: 0.0909091
Do they talk about similar topics? No

*/

 



answered 3 days ago by avibootz
...