交互字典树的实现

废稿的代码

#include  
#include  
#include  
#include  
#include  
#include  

#define ALPHABET_SIZE 26 //字母表大小

typedef struct TrieNode {
    struct TrieNode* children[ALPHABET_SIZE];//指针数组,用于存储指向子节点的指针
    bool isEndOfWord;//布尔值,用于标记当前节点是否是一个单词的结束
    char suggestions[10][50];//二维字符数组,用于存储单词建议的列表,最多存储10个长度不超过50的建议单词
    int suggestionCount;//建议单词的数量
} TrieNode; 

TrieNode* createNode() {//函数负责创建新的TrieNode节点,并进行内存分配检查
    TrieNode* node = (TrieNode*)calloc(1, sizeof(TrieNode));
    //通过calloc分配TrieNode结构体所需的内存空间
    if (node == NULL) {//内存分配失败,输出错误信息并退出程序
        fprintf(stderr, "Memory allocation error: %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }
    return node;
}

//将单词插入字典
void insert(TrieNode* root, const char* word, char suggestions[][50], int* count) {
	//输入验证
    if (root == NULL || word == NULL || *word == '\0' || strlen(word) >= 50 || suggestions == NULL || count == NULL) {
        fprintf(stderr, "Invalid input for insertion.\n");
        return;
    }
    
    TrieNode* curr = root;
    //遍历Trie,如有需要则创建节点
    for (int i = 0; word[i] != '\0'; i++) {
        char ch = tolower(word[i]);
        int index = ch - 'a';
        if (index < 0 || index >= ALPHABET_SIZE) {
            fprintf(stderr, "Invalid character in word: %c\n", word[i]);
            return;
        }
        
        //如果字符不存在于Trie中,则创建新节点
        if (curr->children[index] == NULL) {
            curr->children[index] = createNode();
            if (curr->children[index] == NULL) {
                fprintf(stderr, "Memory allocation error: %s\n", strerror(errno));
                return;
            }
        }
        curr = curr->children[index];
    }
    //标记单词结尾,并存储建议
    curr->isEndOfWord = true;
    if (*count < 10) {
        strcpy(suggestions[*count], word);
        (*count)++;
    }
}

//从Trie中删除单词
void delete(TrieNode* root, const char* word) {
    if (root == NULL || word == NULL || *word == '\0') {
        fprintf(stderr, "Invalid input for deletion.\n");
        return;
    }
    
    TrieNode* curr = root;
    //根据单词字符遍历Trie
    for (int i = 0; word[i] != '\0'; i++) {
        char ch = tolower(word[i]);
        int index = ch - 'a';
        if (index < 0 || index >= ALPHABET_SIZE || curr->children[index] == NULL) {
            return;//未找到单词
        }
        curr = curr->children[index];
    }
    
    //如果找到单词,标记其结尾未false,并重置建议
    if (curr->isEndOfWord) {
        curr->isEndOfWord = false;
        memset(curr->suggestions, 0, sizeof(curr->suggestions));
        curr->suggestionCount = 0;
    }
}

//递归保存节点到文件
void saveNode(TrieNode* node, FILE* file, char* buffer, int level) {
    //空节点或文件的基本情况
	if (node == NULL || file == NULL) {
        return;
    }
    
    //如果是单词结尾,则写入文件
    if (node->isEndOfWord) {
        buffer[level] = '\0';
        fprintf(file, "%s\n", buffer);
    }
    //递归保存子节点
    for (int i = 0; i < ALPHABET_SIZE; i++) {
        if (node->children[i] != NULL) {
            buffer[level] = i + 'a';
            saveNode(node->children[i], file, buffer, level + 1);
        }
    }
    //保存建议
    for (int i = 0; i < node->suggestionCount; i++) {
        fprintf(file, "%s\n", node->suggestions[i]);
    }
}

//保存字典Trie到文件
void saveDictionaryToFile(TrieNode* root, const char* filename) {
    if (root == NULL || filename == NULL || *filename == '\0') {
        fprintf(stderr, "Invalid input for saving the dictionary.\n");
        return;
    }
    FILE* file = fopen(filename, "w");
    if (file == NULL) {
        fprintf(stderr, "Failed to open file: %s\n", filename);
        return;
    }
    char buffer[50];
    saveNode(root, file, buffer, 0);
    fclose(file);
}

bool search(TrieNode* root, const char* word) {
    if (root == NULL || word == NULL || *word == '\0') {
        fprintf(stderr, "Invalid input for search.\n");
        return false;
    }
    
    TrieNode* curr = root;
    for (int i = 0; word[i] != '\0'; i++) {
        char ch = tolower(word[i]);
        int index = ch - 'a';
        if (index < 0 || index >= ALPHABET_SIZE || curr->children[index] == NULL) {
            return false;
        }
        curr = curr->children[index];
    }
    return curr->isEndOfWord;
}

void prefixMatch(TrieNode* root, const char* prefix) {
    if (root == NULL || prefix == NULL || *prefix == '\0') {
        fprintf(stderr, "Invalid input for prefix match.\n");
        return;
    }
    
    TrieNode* curr = root;
    for (int i = 0; prefix[i] != '\0'; i++) {
        char ch = tolower(prefix[i]);
        int index = ch - 'a';
        if (index < 0 || index >= ALPHABET_SIZE || curr->children[index] == NULL) {
            printf("No words found with the given prefix.\n");
            return;
        }
        curr = curr->children[index];
    }
    printf("Words with prefix '%s':\n", prefix);
    char buffer[50];
    strcpy(buffer, prefix);
    printWords(curr, buffer, strlen(prefix));
}

void printWords(TrieNode* root, char* buffer, int level) {
    if (root == NULL) {
        return;
    }
    if (root->isEndOfWord) {
        printf("%s\n", buffer);
    }
    for (int i = 0; i < ALPHABET_SIZE; i++) {
        if (root->children[i] != NULL) {
            buffer[level] = i + 'a';
            printWords(root->children[i], buffer, level + 1);
        }
    }
}

void generateSuggestions(TrieNode* root, const char* word, char suggestions[][50], int* count) {
    if (root == NULL || word == NULL || *word == '\0' || suggestions == NULL || count == NULL) {
        fprintf(stderr, "Invalid input for generating suggestions.\n");
        return;
    }
    *count = 0;
    TrieNode* curr = root;
    for (int i = 0; word[i] != '\0'; i++) {
        char ch = tolower(word[i]);
        int index = ch - 'a';
        if (index < 0 || index >= ALPHABET_SIZE || curr->children[index] == NULL) {
            fprintf(stderr, "Invalid character in word or word not found in the dictionary.\n");
            return;
        }
        curr = curr->children[index];
    }
    for (int i = 0; i < curr->suggestionCount; i++) {
        strncpy(suggestions[i], curr->suggestions[i], 50 - 1);
        suggestions[i][49] = '\0';
    }
    *count = curr->suggestionCount;
}

void spellCheckAndCorrect(TrieNode* root, const char* word) {
    if (root == NULL || word == NULL || *word == '\0') {
        fprintf(stderr, "Invalid input for spell check.\n");
        return;
    }
    
    if (search(root, word)) {
        printf("Word '%s' is spelled correctly.\n", word);
    } else {
        printf("Word '%s' is misspelled.\n", word);
        
        printf("Spelling correction suggestions for '%s':\n", word);
        char suggestions[10][50];
        int count = 0;
        generateSuggestions(root, word, suggestions, &count);
        
        if (count == 0) {
            printf("No suggestions found.\n");
        } else {
            for (int i = 0; i < count; i++) {
                printf("%s\n", suggestions[i]);
            }
        }
    }
}

void destroyTrie(TrieNode* root) {
    if (root == NULL) {
        return;
    }
    for (int i = 0; i < ALPHABET_SIZE; i++) {
        destroyTrie(root->children[i]);
    }
    free(root);
}

void saveTrieToFile(TrieNode* root, const char* filename) {
    FILE* file = fopen(filename, "wb");
    if (file == NULL) {
        fprintf(stderr, "Error opening file for writing: %s\n", strerror(errno));
        return;
    }
    if (root != NULL) {
        char buffer[50];
        saveNode(root, file, buffer, 0);
    }
    fclose(file);
    printf("Dictionary saved to file: %s\n", filename);
}

TrieNode* loadTrieFromFile(const char* filename) {
    FILE* file = fopen(filename, "rb");
    if (file == NULL) {
        fprintf(stderr, "Error opening file for reading: %s\n", strerror(errno));
        return NULL;
    }
    TrieNode* root = createNode();
    if (root == NULL) {
        fprintf(stderr, "Memory allocation error: %s\n", strerror(errno));
        fclose(file);
        return NULL;
    }
    char word[50];
    while (fgets(word, sizeof(word), file) != NULL) {
        size_t length = strlen(word);
        if (word[length - 1] == '\n') {
            word[length - 1] = '\0';
        }
        char suggestions[10][50];
        int count = 0;
        insert(root, word, suggestions, &count);
    }
    fclose(file);
    printf("Dictionary loaded from file: %s\n", filename);
    return root;
}

int main() {
    TrieNode* root = loadTrieFromFile("dictionary.txt");
    if (root == NULL) {
        root = createNode();
    }
    if (root == NULL) {
        printf("Memory allocation error.\n");
        return 1;
    }
    
    printf("Welcome to the Interactive Dictionary!\n");
    printf("Commands:\n");
    printf("1. Add word: add \n");
    printf("2. Delete word: delete \n");
    printf("3. Search word: search \n");
    printf("4. Prefix match: prefix \n");
    printf("5. Spell check: spellcheck \n");
    printf("6. Save dictionary: save \n");
    printf("7. Exit: exit\n\n");
    
    while (true) {
    
        char command[50];
        printf("Enter command: ");
        if (scanf("%49s", command) != 1) {
            fprintf(stderr, "Error reading command.\n");
            continue;
        }
        if (strlen(command) > 49) {
            fprintf(stderr, "Command too long. Please enter a valid command.\n");
            continue;
        }
        
        if (strcmp(command, "add") == 0) {
            char word[50];
            scanf("%49s", word);
            char suggestions[10][50];
            int count = 0;
            insert(root, word, suggestions, &count);
            printf("Word '%s' added to the dictionary.\n\n", word);
        } 
        else if (strcmp(command, "delete") == 0) {
            char word[50];
            scanf("%49s", word);
            delete(root, word);
            printf("Word '%s' deleted from the dictionary.\n\n", word);
        }
        else if (strcmp(command, "search") == 0) {
            char word[50];
            scanf("%49s", word);
            if (search(root, word)) {
                printf("Word '%s' found in the dictionary.\n\n", word);
            } else {
                printf("Word '%s' not found in the dictionary.\n\n", word);
            }
        }
        else if (strcmp(command, "prefix") == 0) {
            char prefix[50];
            scanf("%49s", prefix);
            prefixMatch(root, prefix);
            printf("\n");
        }
        else if (strcmp(command, "spellcheck") == 0) {
            char word[50];
            scanf("%49s", word);
            spellCheckAndCorrect(root, word);
            printf("\n");
        }
        else if (strcmp(command, "save") == 0) {
            char filename[50];
            scanf("%49s", filename);
            saveTrieToFile(root, filename);
            printf("\n");
        }
        else if (strcmp(command, "exit") == 0) {
            printf("Exiting Interactive Dictionary.\n");
            break;
        }
        else {
            printf("Invalid command! Please try again.\n\n");
        }
    }
    
    destroyTrie(root);
    return 0;
}

你可能感兴趣的:(大作业,交互,c#,开发语言)