【问题标题】:CS50 pset5 speller weird bugCS50 pset5 拼写器奇怪的错误
【发布时间】:2020-09-11 08:38:44
【问题描述】:

当我第一次运行我的完整程序时,我已经完成了 cs50 pset5 拼写程序(或者我认为是这样)。它开始打印一些单词,所以我想:“Bingo!我完成了!”我非常高兴,因为我已经为此工作了好几个星期。但是,当它在浏览单词时,我注意到一些单词,比如“和”这个词,当它们在字典中时打印出来了。所以我认为我的代码中有一个小错误。但是当它来到列表的末尾时,它没有执行“拼写错误的单词:”部分和其他部分。它甚至没有以$~ 开头的新行。我不得不关闭整个终端,因为我不能在那里做任何其他事情,因为它是这样的:

OUT
THE
END

这些词是最后的词,然后只有一个空行。然后我打开了一个新的终端,和工作人员的答案核对了我的答案,结果错了很多!我试图在我的代码中找到一些错误,但我找不到任何错误。如果你能找到一些并告诉我,我真的很感激。这是我的代码:

// Implements a dictionary's functionality

#include <ctype.h>
#include <stdio.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#include "dictionary.h"
#include <strings.h>




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

// Number of buckets in hash table
const unsigned int N = 19683;
// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{ 
    unsigned int lol = hash(word);
     // TODO
   int i;
   node *cursor =table[lol];;
    while(cursor != NULL)
    {
     
    
      if(strcasecmp(word, cursor -> word) == 0)
      {
          return true;
      }
      cursor = cursor->next;
   
    }
    
    
    return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
    int count = 0;
    // TODO
  for(int i = 96; i < 122; i++)
  {
      for(int j = 96; j < 122; j++)
      {
          for(int d = 96; d < 122; d++)
          {
              count++;
              char firstletter = i;
              char secondletter = j;
              char thirdletter = d;
              
              if(word[0] == firstletter&& word[1] == secondletter && word[2] == thirdletter)
              {
                  
                  return count;
              }
          }
      }
  }
  return 1;
    
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Open dictionary and check for memory issue
    // Open dictionary file and create word array
    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;
    }

    // Read string 1 word at a time
    while (fscanf(dict, "%s", word) != EOF)
    {
        node *n = malloc(sizeof(node));
        if (n == NULL)
        {
            return false;
        }

        strcpy(n -> word, word);
      

        // 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)
{
   int count = 0;
   
    // TODO
     for(int i = 0; i < N; i++)
    {   
 
       while(table[i] != NULL)
       {
         node* cursor = table[i];
            count++;
         cursor = cursor -> next;
        }
    }
    return count;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{

    // TODO
    for(int i = 0; i < N; i++)
    {
    node *cursor = table[i];
    while(cursor)
    {
        node *temp = cursor;
        cursor = cursor -> next;
        if(temp != NULL)
        {
            return true;
        }
        free(temp);
    }
    }
  
return 1;
    
}

非常感谢, 迷失在代码中。

【问题讨论】:

  • 所以我应该在加载函数结束时做free?
  • 对不起,我想我误解了代码。我还以为是链表,结果好像是链表之类的。
  • 没关系,这发生在我们最好的人身上。
  • 那么无论如何,调用代码在哪里?这已经是一大堆代码了,但我认为问题可能在于你如何调用这些函数。如果您能将范围缩小到您怀疑可能有误的部分,将会很有帮助。
  • 我可以缩小范围,但问题是我怀疑错误已经扩散,所以我必须显示整个代码以防我没有显示有错误的部分

标签: c cs50


【解决方案1】:
  • hash 不区分大小写。文本中任何带有大写字母的单词都将进入索引 1。
  • unload 在这里有一个无限循环 while(table[i] != NULL) 因为 table[i] 永远不会改变

解决这两个问题应该会取得进展,尽管可能不会完全成功。

NB ctrl-c 应该结束一个卡在循环中的程序而不需要关闭终端。

【讨论】:

  • 我修复了卸载,但感谢哈希提示。我会试试,告诉你它是否有效
  • 好的,我试过你说的,它停止输出像'the'这样的词,这些词在字典中但都是大写的,但它仍然只是在到达列表末尾时才结束并且没有' t 做“单词拼写错误”部分。这是我的卸载代码:bool unload(void) { // TODO for(int i = 0; i &lt; N; i++) { node *cursor = table[i]; while(cursor) { node *temp = cursor; cursor = cursor -&gt; next; if(temp == NULL) { return true; } free(temp); } } return 1; }
  • 这是我的哈希码:unsigned int hash(const char *word) { int count = 0; for(int i = 96; i &lt; 122; i++) { for(int j = 96; j &lt; 122; j++) {for(int d = 96; d &lt; 122; d++) { count++; const char firstletter = i; const char secondletter = j; const char thirdletter = d; if(strcasecmp(&amp;word[0], &amp;firstletter) == 0 &amp;&amp; strcasecmp(&amp;word[2], &amp;secondletter) == 0 &amp;&amp; strcasecmp(&amp;word[3], &amp;thirdletter) == 0){ return count; } } } } return 1; }
  • 与卸载时修复的大小相同的错误。建议在将单词添加到链表时对它们进行计数并返回该值的大小。遍历列表会增加不必要的时间。
  • 但是我将单词添加到哈希链表中,那么我如何从哈希中获取一个值并返回它的大小?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
  • 2020-08-25
  • 2020-10-18
相关资源
最近更新 更多