鱼C论坛

 找回密码
 立即注册
查看: 85|回复: 4

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

[复制链接]
发表于 2024-9-5 10:55:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#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[MAX];              
}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[unit];       
}

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[i]==NULL)                 //子节点为空 ,则建立新的节点,并指向此节点
                                        {
                            Tree *temp = trieCreate() ;
                            temp->isleaf = 1;      
                           
                            if(t->isleaf != 1)
                            {
                                            totaldepth += d;
                                            totalleafs++;
                            }
                      }
                      else
                      {
                          t = t->child[i];
                      }
                        
                    }
            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[i] != NULL)
            {
                t = t->child[i];
                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[i]!=NULL)
            f_free(obj->child[i]);
    }      
    free(obj);
  }
  
  int main()
  {
          int i,j,l ;
          char str[300] ;              //换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的字符啊,救救孩子吧,小学期要交作业了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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[i]) {
       t->child[i] = 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 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

### 问题分析:

能帮我写一个完整的么,还是没有理解
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-9-5 12:00:26 | 显示全部楼层
墨一一 发表于 2024-09-05 11:40
能帮我写一个完整的么,还是没有理解


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

```c
#include <

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-9-7 12:42:02 | 显示全部楼层
再问一遍。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-17 02:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表