You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CS50 PSet5拼写检查check50失败:如何修复大小写与基础词问题?

修复CS50拼写检查器的两个测试失败问题

我运行check50工具后,在以下两个测试项中失败:

  • 拼写检查大小写不敏感
  • 正确处理大多数基础词汇

请问该如何修复这些问题?这是否与我的hash函数有关?

以下是我的代码:

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

#include "dictionary.h"

// Represents a node in a hash table
typedef struct node
{
    char word[LENGTH + 1];
    struct node *next;
}
node;

// Number of words in dictionary
int word_count = 0;

// Number of buckets in hash table
const unsigned int N = 26;

// Hash table
node *table[N];

// Returns true if word is in dictionary, else false
bool check(const char *word)
{
    unsigned int n = hash(word);

    node *cursor = table[n];

    while (cursor != NULL)
    {
        if (strcasecmp(word, cursor->word) == 0)
        {
            return true;
        }

        cursor = cursor->next;
    }
    return false;
}

// Hashes word to a number
// Function credit to staff on CS50 reddit page
unsigned int hash(const char *word)
{
    unsigned int hash_value = 0;

    for (int i = 0, n = strlen(word); i < n; i++)
    {
         hash_value = (hash_value << 2) ^ word[i];
    }
    return hash_value % N; 
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Open dictionary and check for memory issue
    //Function guide credit to CS50 Guide by Anvea on YouTube
    FILE *dict = fopen(dictionary, "r");
    char word[LENGTH + 1];

    // Check for memory issue with dict
    if (dict == NULL)
    {
        printf("Dictionary is null\n");
        unload();
        return false;
    }

    while (fscanf(dict, "%s", word) != EOF)
    {
        node *n = malloc(sizeof(node));
        if (n == NULL)
        {
            return false;
        }

        strcpy(n->word, word);
        word_count++;

        // Index word using hash function
        int dict_index = hash(word);

        // Insert into hash table if already empty
        if (table[dict_index] == NULL)
        {
            n->next = NULL;
        }
        // Insert work as new node if not empyty
        else
        {
            n->next = table[dict_index];
        }

        table[dict_index] = n;
    }

    // Close dictionary file
    fclose(dict);

    // Indicate success
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    return word_count;
    return 0;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    for (int i = 0; i < N; i++)
    {
        node *cursor = table[i];

        while (cursor)
        {
            node *tmp = cursor;
            cursor = cursor->next;
            free(tmp);
        }
    }
    return true;
}

修复方案

1. 哈希函数是核心问题

你的哈希函数没有处理大小写差异,导致同一个单词的不同大小写形式(比如"Hello"和"hello")会被计算出不同的哈希值,分配到不同的哈希桶里。而check函数虽然用了strcasecmp做大小写不敏感的比较,但如果哈希桶找错了,根本就不会遍历到对应的节点,自然返回false,导致两个测试失败。

修复哈希函数:

  • 先包含<ctype.h>头文件,用来调用tolower()函数
  • 遍历每个字符时,先转成小写再参与哈希计算

修改后的哈希函数代码:

#include <ctype.h> // 必须添加这个头文件

// Hashes word to a number
unsigned int hash(const char *word)
{
    unsigned int hash_value = 0;

    for (int i = 0, n = strlen(word); i < n; i++)
    {
         // 将字符统一转为小写后再计算哈希值
         hash_value = (hash_value << 2) ^ tolower(word[i]);
    }
    return hash_value % N; 
}

2. 其他小问题修正

  • size函数里的第二个return 0;永远不会被执行,直接删掉即可,不影响功能但能让代码更简洁。

验证修复

修改完哈希函数后,重新运行check50,两个测试项应该就能通过了。因为现在同一个单词的任何大小写形式都会被哈希到同一个桶里,check函数再通过strcasecmp就能正确匹配到字典里的单词。

内容的提问来源于stack exchange,提问作者Kaley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 08:24:52