use std::collections::{HashMap, HashSet};
/*
This program finds the N most frequently appearing words in a text
after removing stopwords. It demonstrates clean structure, clear
comments, and efficient use of Rust collections and sorting.
*/
// ---------------------------------------------------------------
// Tokenize text into words (simple whitespace split)
// ---------------------------------------------------------------
fn tokenize(text: &str) -> Vec<String> {
let mut words = Vec::new();
for mut w in text.split_whitespace() {
// Remove punctuation at the edges
while !w.is_empty() && w.chars().next().unwrap().is_ascii_punctuation() {
w = &w[1..];
}
while !w.is_empty() && w.chars().last().unwrap().is_ascii_punctuation() {
w = &w[..w.len() - 1];
}
if !w.is_empty() {
words.push(w.to_lowercase());
}
}
words
}
// ---------------------------------------------------------------
// Count word frequencies, skipping stopwords
// ---------------------------------------------------------------
fn count_words_frequencies(words: &[String], stopwords: &HashSet<String>) -> HashMap<String, usize> {
let mut freq = HashMap::new();
for w in words {
if !stopwords.contains(w) {
*freq.entry(w.clone()).or_insert(0) += 1;
}
}
freq
}
// ---------------------------------------------------------------
// Extract the top N most frequent words
// ---------------------------------------------------------------
fn top_n(freq: &HashMap<String, usize>, n: usize) -> Vec<(String, usize)> {
let mut items: Vec<(String, usize)> =
freq.iter().map(|(w, c)| (w.clone(), *c)).collect();
// Sort by frequency descending, then alphabetically
items.sort_by(|a, b| {
match b.1.cmp(&a.1) {
std::cmp::Ordering::Equal => a.0.cmp(&b.0),
other => other,
}
});
items.into_iter().take(n).collect()
}
// ---------------------------------------------------------------
// Main
// ---------------------------------------------------------------
fn main() {
let text =
"C is a general-purpose programming language created in 1972 by \
Dennis Ritchie. C gives programmers direct access to the features \
of CPU. It has been and continues to be used to implement \
operating systems (especially kernels) and device \
drivers. C programming language used on computers ranging from \
supercomputers to microcontrollers and embedded systems.";
let stopwords: HashSet<String> = [
"the","is","a","to","how","after","but","this","for","by","in",
"and","can","content","be","you","yes","no","next","about","used",
"access","been","continues"
]
.iter()
.map(|s| s.to_string())
.collect();
// Tokenize
let words = tokenize(text);
// Count frequencies
let freq = count_words_frequencies(&words, &stopwords);
// Get top n
let n = 7;
let topn = top_n(&freq, n);
// Print results
println!("Top {} most frequent non-stopwords:", n);
for (word, count) in topn {
println!("{} : {}", word, count);
}
}
/*
run:
Top 7 most frequent non-stopwords:
c : 3
language : 2
programming : 2
systems : 2
1972 : 1
computers : 1
cpu : 1
*/