(二叉查找树)存储文本中的单词--输入单词查找单词出现次数以及输出所有单词(C primer plus十七章第七题)

头文件接口:

#ifndef TREE_H_INCLUDED
#define TREE_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define MAXSIZE 100

typedef struct
{
    int count;
    char word[MAXSIZE];
}Item;

typedef struct trnode
{
    Item item;
    struct trnode * left;
    struct trnode * right;
} Trnode;

typedef struct tree
{
    Trnode * root;
}Tree;

typedef struct
{
    Trnode * parent;
    Trnode * child;
} Pair;

void Initilaizer(Tree *pt)
{
    pt->root = NULL;
}

bool ToLeft(char *str,char *item)
{
    if(strcmp(str,item) < 0)
        return true;
    return false;
}

bool ToRight(char *str,char *item)
{
    if(strcmp(str,item) > 0)
        return true;
    return false;
}

Pair SeekWord(char *str,Tree *pt)
{
    Pair look;
    look.parent = NULL;
    look.child = pt->root;

    while(look.child != NULL)
    {
        if(ToLeft(str,look.child->item.word))
            {
                look.parent =  look.child;
                look.child = look.child->left;
            }
        else if(ToRight(str,look.child->item.word))
            {
                look.parent = look.child;
                look.child = look.child->right;
            }
        else
            break;
    }
    return look;
}

void Additem(Tree *pt)
{
    FILE *fp;
    char temp[MAXSIZE];
    Pair look;
    Trnode *ptemp;

    if((fp = fopen("myfile.txt","r")) == NULL)
    {
        fprintf(stderr,"Error in openning the file!");
        exit(1);
    }

    while(fscanf(fp,"%s",temp) == 1)   //fgets的结束条件是0,fscanf的结束条件是返回值!!
    {
        look = SeekWord(temp,pt);
        if(look.child != NULL)
        {
            look.child->item.count++;
        }
        else
        {
            ptemp = (Trnode *)malloc(sizeof(Trnode));
            ptemp->item.count = 1;
            strcpy(ptemp->item.word,temp);   //不能用赋值符号,若是char*(指针)仅是赋予temp的地址这回导致所有结点的中的word都指向一个地址块导致所有单词相同
            ptemp->left = NULL;
            ptemp->right = NULL;
            if(pt->root == NULL)
                pt->root = ptemp;
            else if(ToLeft(temp,look.parent->item.word))
                 look.parent->left = ptemp;
            else if(ToRight(temp,look.parent->item.word))
                look.parent->right = ptemp;

        }
    }
}

void Traverse(Trnode *pt,void (*pfun)(Item item))
{
    Trnode * root = pt;

    if(root != NULL)
    {
        Traverse(root->left,pfun);
        pfun(root->item);
        Traverse(root->right,pfun);
    }
}

void ShowItem(Item item)
{
    printf("         The word:%s\n",item.word);
    printf("occurrence number:%d\n\n",item.count);
}

void ShowAllItem(Tree *pt)
{
    if(pt != NULL)
    {
        Traverse(pt->root,ShowItem);
    }
}
#endif // TREE_H_INCLUDED

主函数:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "tree.h"
//用fputs和fgets处理,fputs会把回车放入文档,fputs输出不会添加换行
//   每个fgets取得结束的标识就是换行符(即回车)

//这里面对一篇英文文章:我建议使用fscanf处理因为fscanf遇到空格就会结束


/* 菜单功能(二叉树存储):
 * 列出所有单词和出现次数
 * 输入单词查看其出现次数
 * 退出
*/

char *s_gets(char *str,int n)
{
    char *pt;

    pt = fgets(str,n,stdin);
    if(pt)
    {
        while(*str && *str != '\n')
            str++;
        if(*str == '\n')
            *str = '\0';
        else
            while(getchar() != '\n')
             continue;
    }

    return pt;
}

char menu(void)
{
    char ch;

    puts("A word List:");
    puts("s) show all item    b) find item");
    puts("q) quit");

    while((ch=getchar()) != EOF)
    {
        while(getchar() != '\n')
            continue;
        ch = tolower(ch);
        if(strchr("sbq",ch) == NULL)
            puts("Please enter s b or q:");
        else
            break;
    }

    if(ch == EOF)
        ch = 'q';

    return ch;
}

int main()
{
   char ch;
   Tree tree;
   Pair look;
   char *str;
   Initilaizer(&tree);
   Additem(&tree);

   while((ch = menu()) != 'q')
   {
       switch(ch)
       {
           case 's': ShowAllItem(&tree);
           break;
           case 'b':
            {
                printf("Now enter the word which you want to find:");
                s_gets(str,MAXSIZE);
                look = SeekWord(str,&tree);
                if(look.child == NULL)
                    puts("Can't find your word!");
                else
                    ShowItem(look.child->item);
            }
       }
   }

   return 0;
}

文本内容:
As the development of the Internet the traditional way of reading daily news has been challenged more and more people trend to read news online while still some people insist on reading it on the newspaper People argue which is the best way for reading news in my opinion, there is no best way different people choose different manner
Reading news online is fast and paying for free Most young people get used to it they use the computer every day so that they count on the computer to receive the all kinds of information Reading the newspaper is troublesome they don’t like to hold the paper it is not convenient While still many people like to read on the newspaper Especially the old generation, before the popularity of computer they read the news from the newspaper, they get used to this manner even the computer is convenient they just like to keep this habit
The ways to read news are various there is no need to compare them I’d prefer to read it on the Internet but sometimes I find reading it newspaper brings me fun when I have breakfast

效果图:
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值