【PTA数据结构 | C语言版】我爱背单词

本专栏持续输出数据结构题目集,欢迎订阅。

文章目录

    • 题目
    • 代码

题目

作为一个勤奋的学生,你在阅读一段英文文章时,是否希望有个程序能自动帮你把没有背过的生词列出来?本题就请你实现这个程序。

输入格式:
输入第 1 行给出 1 个正整数 n(2≤n≤10^3),为已经背下来的单词的数量。
接下来输入的每行是不超过 20 个字符的、仅由小写英文字母组成的单词。题目保证没有重复的单词。

最后是一段整理好的英文文章,文章仅包含不超过 20 个字符的、仅由小写英文字母组成的单词,单词间以 1 个空格分隔。文章末尾以符号 # 表示结束,这个符号不属于文章的内容。题目保证文章中至少有 1 个生词,且全文一共包含不超过 10^3 个单词。

输出格式:
找出每个没有背过的生词,按照其在文章中出现的顺序输出,每行输出一个生词。注意:每个生词只输出一遍,不要重复输出。

输入样例:
5
a
your
is
case
correct
this is a test case that test the correctness of your program #

输出样例:
this
test
that
the
correctness
of
program

代码

#include 
#include 
#include 
#include 

#define MAX_WORD_LENGTH 21  // 最大单词长度 + 1
#define MAX_VOCABULARY 1000 // 最大词汇量
#define HASH_TABLE_SIZE 2003 // 哈希表大小,使用质数减少冲突

// 哈希表节点结构
typedef struct Node {
    char word[MAX_WORD_LENGTH];
    struct Node* next;
} Node;

Node* hashTable[HASH_TABLE_SIZE];

// 简单哈希函数
unsigned int hash(const char* str) {
    unsigned int hashval = 0;
    for (int i = 0; str[i] != '\0'; i++)
        hashval = str[i] + (hashval << 6) + (hashval << 16) - hashval;
    return hashval % HASH_TABLE_SIZE;
}

// 插入单词到哈希表
void insert(const char* word) {
    unsigned int index = hash(word);
    Node* newNode = (Node*)malloc(sizeof(Node));
    strcpy(newNode->word, word);
    newNode->next = hashTable[index];
    hashTable[index] = newNode;
}

// 检查单词是否在哈希表中
int contains(const char* word) {
    unsigned int index = hash(word);
    Node* current = hashTable[index];
    while (current != NULL) {
        if (strcmp(current->word, word) == 0)
            return 1;
        current = current->next;
    }
    return 0;
}

// 检查单词是否已在生词列表中
int isNewWord(const char**生词列表, int 生词数量, const char* word) {
    for (int i = 0; i < 生词数量; i++) {
        if (strcmp(生词列表[i], word) == 0)
            return 0;
    }
    return 1;
}

int main() {
    int n;
    char word[MAX_WORD_LENGTH];
    const char** newWords = NULL;
    int newWordCount = 0;

    // 初始化哈希表
    for (int i = 0; i < HASH_TABLE_SIZE; i++) {
        hashTable[i] = NULL;
    }

    // 读取已背单词
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%s", word);
        insert(word);
    }

    // 读取文章并处理
    while (scanf("%s", word) == 1) {
        if (word[0] == '#') break; // 遇到结束符号
        
        // 检查是否为生词
        if (!contains(word) && isNewWord(newWords, newWordCount, word)) {
            // 动态扩容生词列表
            newWords = (const char**)realloc(newWords, (newWordCount + 1) * sizeof(const char*));
            char* newWord = (char*)malloc((strlen(word) + 1) * sizeof(char));
            strcpy(newWord, word);
            newWords[newWordCount++] = newWord;
        }
    }

    // 输出结果
    for (int i = 0; i < newWordCount; i++) {
        printf("%s\n", newWords[i]);
    }

    return 0;
}

你可能感兴趣的:(PTA,数据结构题目集,数据结构,c语言,算法)