How to find keyword matching between multiple text blocks in C

1 Answer

0 votes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
 
/*
    Check if a word is already in the list (simulating std::set)
*/
int contains(char **list, int size, const char *word) {
    for (int i = 0; i < size; i++) {
        if (strcmp(list[i], word) == 0)
            return 1;
    }
    return 0;
}
  
/*
    Add a word to the list if not already present
*/
void addWord(char ***list, int *size, const char *word) {
    if (contains(*list, *size, word))
        return;
  
    *list = realloc(*list, (*size + 1) * sizeof(char *));
    (*list)[*size] = malloc(strlen(word) + 1);
    strcpy((*list)[*size], word);
    (*size)++;
}
  
/*
    Tokenize text into words.
    - Keeps only letters and digits
    - Splits on punctuation and spaces
*/
char **tokenize(const char *text, int *outSize) {
    char **words = NULL;
    *outSize = 0;
  
    char buffer[256];
    int bi = 0;
  
    for (int i = 0; text[i]; i++) {
        char c = text[i];
  
        if (isalnum((unsigned char)c)) {
            buffer[bi++] = tolower(c);
        } else if (bi > 0) {
            buffer[bi] = '\0';
            addWord(&words, outSize, buffer);
            bi = 0;
        }
    }
  
    if (bi > 0) {
        buffer[bi] = '\0';
        addWord(&words, outSize, buffer);
    }
  
    return words;
}

/*
    // Find keyword matches across THREE OR MORE texts
    // -------------------------------------------------------------
    This function receives an array of word-lists and their sizes.
    It returns the intersection of ALL lists.
*/
char **findMatchesMultiple(char ***allLists, int *sizes, int listCount, int *outCount) {
    if (listCount == 0) {
        *outCount = 0;
        return NULL;
    }
  
    // Start with the first list
    char **result = NULL;
    int resultCount = 0;
  
    for (int i = 0; i < sizes[0]; i++) {
        addWord(&result, &resultCount, allLists[0][i]);
    }
  
    // Intersect with each remaining list
    for (int k = 1; k < listCount; k++) {
        char **temp = NULL;
        int tempCount = 0;
  
        for (int i = 0; i < resultCount; i++) {
            if (contains(allLists[k], sizes[k], result[i])) {
                addWord(&temp, &tempCount, result[i]);
            }
        }
  
        // Free old result
        for (int i = 0; i < resultCount; i++) free(result[i]);
        free(result);
  
        result = temp;
        resultCount = tempCount;
    }
  
    *outCount = resultCount;
    return result;
}
  
int main() {
    // -------------------------------------------------------------
    // Three text blocks to compare
    // -------------------------------------------------------------
    const char *text1 =
        "Machine learning allows computers to learn from data. "
        "It is widely used in modern applications.";
  
    const char *text2 =
        "Data science uses machine learning techniques. "
        "Applications rely on data-driven models.";
  
    const char *text3 =
        "Modern applications of machine learning include data analysis, "
        "automation, and intelligent systems.";
  
    // -------------------------------------------------------------
    // Tokenize all texts
    // -------------------------------------------------------------
    int size1 = 0, size2 = 0, size3 = 0;
    char **words1 = tokenize(text1, &size1);
    char **words2 = tokenize(text2, &size2);
    char **words3 = tokenize(text3, &size3);
  
    // Prepare arrays for multi-text comparison
    char **allLists[] = { words1, words2, words3 };
    int sizes[] = { size1, size2, size3 };
  
    // -------------------------------------------------------------
    // Find keyword matches across ALL texts
    // -------------------------------------------------------------
    int matchCount = 0;
    char **matches = findMatchesMultiple(allLists, sizes, 3, &matchCount);
  
    // -------------------------------------------------------------
    // Output results
    // -------------------------------------------------------------
    printf("Matched Keywords Across ALL Texts:\n");
    for (int i = 0; i < matchCount; i++)
        printf("%s ", matches[i]);
  
    printf("\n");
  
    // Free memory
    for (int i = 0; i < size1; i++) free(words1[i]);
    for (int i = 0; i < size2; i++) free(words2[i]);
    for (int i = 0; i < size3; i++) free(words3[i]);
    for (int i = 0; i < matchCount; i++) free(matches[i]);
  
    free(words1);
    free(words2);
    free(words3);
    free(matches);
  
    return 0;
}
  
  
  
/*
run:
  
Matched Keywords Across ALL Texts:
applications data learning machine 
  
*/

 



answered May 22 by avibootz
edited May 22 by avibootz

Related questions

...