简体   繁体   English

C语言:实现一个包含文本文件中字符串(单词)的BST的数组

[英]C Language: Implement an array containing BST's of strings ( words ) from a text file

I am trying to create a small program that reads words from a text file of an unknown size and stores those words into an array of Binary Search Trees ( BST ) . 我正在尝试创建一个小程序,该程序从大小未知的文本文件中读取单词,并将这些单词存储到Binary Search Trees(BST)数组中。 Each index within the array represents the length of the words within that BST tree. 数组中的每个索引代表该BST树中单词的长度。

For example, index 0 contains no words but index 1 contains a BST tree with words that are one letter long and index 5 contains a BST tree with words that are 5 letters long etc. All BST trees are balanced by comparing two strings to determine if the new string is greater or smaller than the root string and then assigned accordingly. 例如,索引0不包含单词,但索引1包含具有一个字母长的单词的BST树,索引5包含具有5个字母长的单词的BST树,等等。通过比较两个字符串以确定是否平衡所有BST树新字符串大于或小于根字符串,然后进行相应分配。

My original code contains opaque objects ( void pointers ). 我的原始代码包含不透明的对象(void指针)。 But, I have included a smaller version of the program that I am trying to understand. 但是,我提供了一个我试图理解的程序的较小版本。 I included printf statements to show my debugging approach because the program keeps crashing. 我加入了printf语句来展示我的调试方法,因为该程序一直崩溃。 I have been working on this for hours on end daily and can't get it to run for the life of me. 我每天都在为此工作了几个小时,无法让它在我的一生中运行。 For some reason I couldn't determine if I was using the pointers properly so after about 5 different rewrites of this code, I decided to go with just the basics, but I can't seem to get this to work either. 由于某种原因,我无法确定我是否正确使用了指针,因此在对该代码进行了约5次不同的重写之后,我决定只使用基础知识,但我似乎也无法使其正常工作。

Please help, this is draining me. 请帮助,这让我很烦。 Thank you for your generosity and consideration in helping me with this in advance. 感谢您的慷慨和考虑,以便提前帮助我。

My output is as follows: 我的输出如下:

A CHECKPOINT
B CHECKPOINT
C CHECKPOINT
1 CHECKPOINT
2 CHECKPOINT

The code is as follows: 代码如下:

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

typedef struct my_string{
char* data;
struct my_string *left, *right;
} My_string;

void init( My_string* Root, char* data );

int main(int argc, char* argv[]){
    My_string* myStringArray[ 30 ] = {NULL};
    /*My_string* Root = NULL;*/
    FILE *fp = NULL;
    char new_string[ 30 ];
    fp = fopen( "dictionary.txt", "r");
    int string_length = 0;
    printf( "A CHECKPOINT\n");
    while( fscanf( fp, "%1024s" , new_string ) == 1 ){
        printf( "B CHECKPOINT\n");
        string_length = strlen( new_string );
        printf( "C CHECKPOINT\n");
        init( myStringArray[ string_length ], new_string );
        printf( "D CHECKPOINT\n");
    }
    printf( "" );
    fclose(fp);
    return 0;
}

void init( My_string* Root, char* data ){
    printf( "1 CHECKPOINT\n");
    int compare = 0;
    if( Root == NULL ){
        printf( "2 CHECKPOINT\n");
        (*Root).data = ( My_string* )malloc( sizeof( My_string ));
         printf( "3 CHECKPOINT\n");
        if( !Root ) exit(1);
        Root->data = data;
        Root->left = Root->right = NULL;
    }
    else{
        if( compare = strncmp( data, Root->data, 36 ) == 0 )return;
        else if( compare == -1 ) init( Root->left, data );
        else init( Root->right, data );
    }
}

Thanks again! 再次感谢!

Two general advices: 两条一般建议:

  1. Instead of debug-output you can use debugger to find the exact location of the error (learn how to use gdb , for example). 除了调试输出,您可以使用调试器查找错误的确切位置(例如,学习如何使用gdb )。 You can use debug-output, of course, but it can take more time and you have to clean up after this. 当然,您可以使用debug-output,但是它可能会花费更多时间,并且您必须在此之后进行清理。
  2. Don't ignore compiler warnings. 不要忽略编译器警告。

My compiler says: 我的编译器说:

a.c:37:22: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
(*Root).data = ( My_string* )malloc( sizeof( My_string ));

Here you try to dereference Root and assign a value to data field. 在这里,您尝试取消对“ Root引用,并为data字段分配一个值。 Since Root is NULL , the program crashes here. 由于RootNULL ,因此程序在此处崩溃。 It looks like you intended to assign value to Root here, but made a type of kind. 看起来您打算在此处为Root赋值,但是这是一种类型。 So it should be something like this: 所以应该是这样的:

Root = ( My_string* )malloc( sizeof( My_string ));

BTW, you have another problem in the code: when you pass Root as function parameter, it won't be changed after you exit the function: 顺便说一句,您在代码中还有另一个问题:当您将Root作为函数参数传递时,退出函数后将不会更改它:

My_string* Root = NULL;
init(Root, data);
// Root is NULL here

One way to fix this is to pass pointer to Root : 解决此问题的一种方法是将指针传递给Root

init(&Root, data);
void init( My_string** Root_ptr, char* data ){
    ...
}

and modify the code accordingly. 并相应地修改代码。

Another way is to change init signature and make it return a newly-created Root . 另一种方法是更改init签名,并使它返回新创建的Root I don't understand the scenario where you need to init an existing tree, so it seems a natural thing to do. 我不了解您需要初始化现有树的情况,因此似乎很自然。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM