墨一一 发表于 2024-9-5 10:55:52

为什么这个代码只输出no,查找不到yes的字符啊,救救孩子吧,小学期要交作业了{:5_1...

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

#define MAX 16
#define UNIT 4
#define MAXLEN 256

int ending=0 ;   

typedef struct TrieNode
{
    int count;
    int isleaf;
    struct TrieNode *child;            
}Tree,*Tree_r;                         //结构体指针数组

int totalleafs = 0;
int totaldepth = 0;
int totalnodes = 0;

Tree * trieCreate()                   //建立树根节点
{
    Tree * node = (Tree *)malloc(sizeof(Tree));
   
    if(!node)
                ending = 1 ;
   
    memset(node, 0, sizeof(Tree));
    return node;
}

unsigned char getbytes(unsigned char c,int index,int unit)
{
        unsigned char u[]={0b00000000,0b00000001};
        if (8 % unit != 0)
                return -1;
               
        int k = 8 - (index+1) * unit;
        c = c >> k;
       
        return c & u;       
}

void f_insert(Tree_r obj, char * strx)      //建立完整tire树      
{
    Tree * t = obj;
    char * p = strx;
    int d =0;
    while(*p != '\0')
        {
      unsigned char c = *p;                     //汉字可以看成两个字母的二进制组合,加上128,用这个数作数组下标
      
      for(int j = 0; j < 8/UNIT; j++)
      {
              d=1;
              unsigned char i = getbytes(c,j,UNIT);
                      if(t->child==NULL)               //子节点为空 ,则建立新的节点,并指向此节点
                                        {
                            Tree *temp = trieCreate() ;
                            temp->isleaf = 1;      
                           
                            if(t->isleaf != 1)
                            {
                                            totaldepth += d;
                                            totalleafs++;
                            }
                      }
                      else
                      {
                        t = t->child;
                      }
                        
                  }
            p++;
            t->count++ ;                           // 记录字典中字符串到达的位置及个数

    }      
}

int f_search(Tree_r obj, char * strx)
{
    Tree *t = obj;
    char *p = strx;
    int count = 0;
    while(*p != '\0')
        {
                unsigned char c = *p;                     //汉字可以看成两个字母的二进制组合,加上128,用这个数作数组下标
      
      for(int j = 0; j < 8/UNIT; j++)
      {
            unsigned char i = getbytes(c,j,UNIT);
            if(t->child != NULL)
            {
                t = t->child;
                count++;
            }
            else
            {
                return 0;
            }
      }
    }
   
    if(t->count != 0)
    return 1;
    else
    return 0;
}

void f_free(Tree* obj)                //释放内存
{
    if(!obj) return;
    for(int i=0;i<2; i++)   
        {
      if(obj->child!=NULL)
            f_free(obj->child);
    }      
    free(obj);
}

int main()
{
        int i,j,l ;
        char str ;            //换MAXLEN
        FILE *fpr1,*fpr2,*fpw ;
        fpr1 = NULL ;
        fpr2 = NULL ;
        fpw = NULL ;
        Tree_r root = NULL ;         //申明一个指向Trie树的指针
        root = trieCreate() ;      //建立根节点,使指针指向这个区域
       
        if(ending)
          {
                printf("Error!\n");
                return 7 ;
          }
          
        if(root==NULL)
          printf("Fail!\n");
          
        if((fpr1=fopen("C:\\Users\\tulin\\dict.txt", "r")) == NULL)
       {
            printf("File can not be opened.\n");
            return 1;
       }
    if((fpr2=fopen("C:\\Users\\tulin\\words.txt", "r")) == NULL)
       {
            printf("File can not be opened.\n");
            return 1;
       }
       
        do
          {
                  if(fscanf(fpr1,"%s",str) != EOF)    //fscanf返回值 EOF
                  {
                                                     
                        f_insert(root , str);                
               
                        totalnodes++;
                        if(ending)
                  {
                          printf("Error.\n");
                        return 7 ;
                  }
             
          }
                               
           }while(!feof(fpr1));   
       
        fpw = fopen("result1.txt", "w+");
       
        do
          {
                  if(fscanf(fpr2,"%s",str) != EOF)   
          {
                  j = f_search(root , str);
                  if(j == 1)
                        {
                                                            
                                                            
                              fprintf(fpw,"%s yes\n",str);
                             }
                    
                    else if(j == 0)
                        {
                              
                              fprintf(fpw,"%s no\n",str);
                          }
                    else
                        {
                              printf("Error.\n");
                          return 0 ;
                          }           
                  }          
          }while(!feof(fpr2));
       
        printf("Success\n");
        printf("Average depth: %f\n", (float)totaldepth / totalnodes);
        printf("Total depth: %f\n", (float)totaldepth );
        fclose(fpr1);
        fclose(fpr2);
        fclose(fpw);
        f_free(root);
       
        return 0 ;
   }
为什么这个代码只输出no,查找不到yes的字符啊,救救孩子吧,小学期要交作业了{:5_104:}

FishC 发表于 2024-9-5 11:16:06

你的代码看起来不完整,我会根据你提供的部分进行分析,并指出可能的问题和改进建议。

### 问题分析:
1. **`getbytes` 函数**:
   - 你定义的 `u` 是一个初始化错误的数组。应该定义为掩码,例如 `unsigned char u = 0b1111` 或根据 `UNIT` 动态生成。
   - `return -1;` 的行为异常,应适当处理此错误。

2. **`f_insert` 函数**:
   - 当 `t->child == NULL` 时,虽然创建了新的节点 `temp`,但是没有把它正确连接到 `t->child`,导致树结构无法维护。
   - `count` 的操作没有意义,因为 `count++` 在 `p++` 后,而不是在节点完成插入时。

3. **`f_search` 函数**:
   - 搜索时未完整实现,只看到一部分代码。应该完整遍历 `Trie` 并比较输入字符的各个字节以确定路径。

4. **字符处理**:
   - 你提到的是处理汉字,但代码中只有 `char` 型数据处理,并且没有对应处理多字节字符集的逻辑。

### 可能的改进建议:
1. 确保 `TrieNode` 中的子节点 `child` 是个数组,用于存储下一层的节点。
   
2. 在 `f_insert` 函数中,将新创建的节点挂载到当前节点的合适位置:
   if (!t->child) {
       t->child = temp;
   }

3. 修复 `getbytes` 函数以正确提取单元字节:
   unsigned char getbytes(unsigned char c, int index, int unit) {
       if (index*unit >= 8) return 0;
       int k = 8 - (index + 1) * unit;
       return (c >> k) & ((1 << unit) - 1);
   }

4. 将完整的 `f_search` 实现添加并确保正确遍历 `Trie` 树来查找目标字符串。

5. 调试修改后的代码,确保可以插入并搜索所需的字符串。

请尝试这些建议并检查其效果。如有需要进一步帮助,请提供完整的代码或具体的问题描述。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

墨一一 发表于 2024-9-5 11:40:07

FishC 发表于 2024-9-5 11:16
你的代码看起来不完整,我会根据你提供的部分进行分析,并指出可能的问题和改进建议。

### 问题分析:


能帮我写一个完整的么,还是没有理解{:5_104:}

FishC 发表于 2024-9-5 12:00:26

墨一一 发表于 2024-09-05 11:40
能帮我写一个完整的么,还是没有理解{:5_104:}

好的,这里有一个完整的 Trie 树的实现,用于从一个字典文件中读取单词并插入到 Trie 树中,然后检查另一个文件中的单词是否在字典中。

```c
#include <

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

sfqxx 发表于 2024-9-7 12:42:02

再问一遍。
页: [1]
查看完整版本: 为什么这个代码只输出no,查找不到yes的字符啊,救救孩子吧,小学期要交作业了{:5_1...