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,943 questions

55,787 answers

573 users

How to find the N most frequent non‑stopwords in a text in C

1 Answer

0 votes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/*
    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 C dynamic arrays and sorting.
*/

typedef struct {
    char *word;
    int count;
} WordFreq;

/* ---------------------------------------------------------------
   Helper: check punctuation
   --------------------------------------------------------------- */
int is_punct(char c) {
    return ispunct((unsigned char)c);
}

/* ---------------------------------------------------------------
   Tokenize text into words (simple whitespace split)
   --------------------------------------------------------------- */
char **tokenize(const char *text, int *count) {
    char *copy = strdup(text);
    char *token = strtok(copy, " \t\n");
    char **words = NULL;
    int size = 0;

    while (token) {
        char *w = strdup(token);

        /* Remove punctuation at edges */
        while (w[0] && is_punct(w[0]))
            memmove(w, w + 1, strlen(w));

        while (strlen(w) > 0 && is_punct(w[strlen(w) - 1]))
            w[strlen(w) - 1] = '\0';

        if (strlen(w) > 0) {
            /* Convert to lowercase */
            for (char *p = w; *p; ++p)
                *p = tolower((unsigned char)*p);

            words = realloc(words, sizeof(char*) * (size + 1));
            words[size++] = w;
        } else {
            free(w);
        }

        token = strtok(NULL, " \t\n");
    }

    free(copy);
    *count = size;
    return words;
}

/* ---------------------------------------------------------------
   Check if a word is a stopword
   --------------------------------------------------------------- */
int is_stopword(const char *word, char **stopwords, int stop_count) {
    for (int i = 0; i < stop_count; i++)
        if (strcmp(word, stopwords[i]) == 0)
            return 1;
    return 0;
}

/* ---------------------------------------------------------------
   Count word frequencies, skipping stopwords
   --------------------------------------------------------------- */
WordFreq *count_words_frequencies(char **words, int word_count,
                                  char **stopwords, int stop_count,
                                  int *freq_count) {
    WordFreq *freq = NULL;
    int size = 0;

    for (int i = 0; i < word_count; i++) {
        if (is_stopword(words[i], stopwords, stop_count))
            continue;

        int found = -1;
        for (int j = 0; j < size; j++) {
            if (strcmp(freq[j].word, words[i]) == 0) {
                found = j;
                break;
            }
        }

        if (found >= 0) {
            freq[found].count++;
        } else {
            freq = realloc(freq, sizeof(WordFreq) * (size + 1));
            freq[size].word = strdup(words[i]);
            freq[size].count = 1;
            size++;
        }
    }

    *freq_count = size;
    return freq;
}

/* ---------------------------------------------------------------
   Sort and extract top N most frequent words
   --------------------------------------------------------------- */
int compare_freq(const void *a, const void *b) {
    const WordFreq *wa = a;
    const WordFreq *wb = b;

    if (wa->count != wb->count)
        return wb->count - wa->count; /* descending */

    return strcmp(wa->word, wb->word); /* alphabetical */
}

WordFreq *top_n(WordFreq *freq, int freq_count, int n) {
    qsort(freq, freq_count, sizeof(WordFreq), compare_freq);

    if (freq_count > n)
        freq_count = n;

    WordFreq *top = malloc(sizeof(WordFreq) * freq_count);
    for (int i = 0; i < freq_count; i++) {
        top[i].word = strdup(freq[i].word);
        top[i].count = freq[i].count;
    }

    return top;
}

/* ---------------------------------------------------------------
   Main
   --------------------------------------------------------------- */
int main() {

    const char *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.";

    char *stopwords[] = {
        "the","is","a","to","how","after","but","this","for","by","in",
        "and","can","content","be","you","yes","no","next","about","used",
        "access","been","continues"
    };
    int stop_count = sizeof(stopwords) / sizeof(stopwords[0]);

    int word_count = 0;
    char **words = tokenize(text, &word_count);

    int freq_count = 0;
    WordFreq *freq = count_words_frequencies(words, word_count,
                                             stopwords, stop_count,
                                             &freq_count);

    int n = 7;
    WordFreq *topn = top_n(freq, freq_count, n);

    printf("Top %d most frequent non-stopwords:\n", n);
    for (int i = 0; i < n && i < freq_count; i++) {
        printf("%s : %d\n", topn[i].word, topn[i].count);
    }

    return 0;
}


/*
run:

Top 7 most frequent non-stopwords:
c : 3
language : 2
programming : 2
systems : 2
1972 : 1
computers : 1
cpu : 1

*/

 



answered 1 day ago by avibootz
edited 1 day ago by avibootz
...