#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
*/