C语言二叉树字符统计,C语言实现二叉树-利用二叉树统计单词数目

昨天刚参加了腾讯2015年在线模拟考;

四道大题的第一题就是单词统计程序的设计思想;

为了记住这一天,我打算今天通过代码实现一下;

我将用到的核心数据结构是二叉树;

(要是想了解简单二叉树的实现,可以参考我的另一篇文章:http://www.cnblogs.com/landpack/p/4783120.html)

Problem

我需要统计的单词是在程序直接硬编码的;

这样做得原因是省略了文件输入输出所带来的困惑;

我的每篇文章,一般只说一个主题;

这样也方便我日后复习;

Solution

首先,我们需要定义一个结构体,如下代码所示:

const int LONGEST_WORD = ; // The longest word size

struct binary_tree {

char str[LONGEST_WORD];

int count;

struct binary_tree * left;

struct binary_tree * right;

};

typedef struct binary_tree node;

注意到,我们假设最长的单词定义为一个常量,在这里我觉得目前32这个长度应该可以啦;

如果要统计的文章是化学论文,建议你再加大数字,因为化学式通常都很长;

然后是,我们的结构体;这应该很容易理解的;

由于C语言没有提供我想要的BOOL类型,因此自己动手写啦下面的代码;

这个定义非常有用,通常它比define更加值得推荐;

enum BOOL {

NO,

YES

};

typedef enum BOOL BOOL;

接下来,我们需要知道单词之间是如何比较大小的;

因此,需要一个函数叫做cmp;

代码实现如下:

BOOL cmp(char * s, char * t)

{

int i;

for (i = ; s[i] == t[i]; i++)

if ( s[i] == '\0' )

return NO;

return (s[i] - t[i]) < ? NO:YES;

}

同时遍历两个字符串,然后对返回值进行一个处理;

这样只会返回两种情况NO/YES,不然的话会返回三种值(-1,0,正数);

那样的话,不利于我们往后的工作;

接下来呢,就是如果返回YES我们该(如何) (做什么);

如果返回NO我们又该(如何)(做什么);

因此,我们需要一个insert函数,把数据的两种不同分别插入左右子树;

void insert(node ** tree, char * val) {

node * temp = NULL;

if(!(*tree)) {

temp = (node*)malloc(sizeof(node));

temp->left = temp->right = NULL;

temp->str = val; //issue code ...

temp->count = ;

*tree = temp;

return ;

}

if(cmp(val, (*tree)->str)) {

insert(&(*tree)->left,val);

}else if (cmp(val,(*tree)->str)) {

insert(&(*tree)->right,val);

}else{

(*tree)->count++;

}

}

这段代码和前面提到的(C语言实现二叉树)里面的代码几乎一样的,哪里有详细介绍;

这里主要讲解一下注释有issue code的那行,如果这行不修改,程序将会蹦溃;

但是,我会故意不马上修改它,继续往下写;

我们需要一个函数,销毁节点:

void deltree(node * tree) {

if(tree) {

deltree(tree->left);

deltree(tree->right);

free(tree);

}

}

为了查看我们的结果,我们需要一种遍历方式;

这里我们就选择中序吧!

void print_inorder(node * tree) {

if(tree) {

print_inorder(tree->left);

printf("[%s\t\t\t]count:[%d]\n",tree->str,tree->count);

print_inorder(tree->right);

}

}

我们把头文件stdio.h/stdlib.h引入后;

把主int main(int argc, char ** arg{

node * root;

node * tmp;

//int i;

root = NULL;

/* Inserting nodes into tree */

insert(&root,"hello");

insert(&root,"hey");

insert(&root,"hello");

insert(&root,"ok");

insert(&root,"hey");

insert(&root,"hey");

insert(&root,"hey");

printf("In Order Display\n");

print_inorder(root);/* Deleting all nodes of tree */

deltree(root);

}

gcc编译运行得到如下结果:

ba10f56108b2a3b29b0bc1ecbe64c439.png

果然,我们的issue code有问题,原因是字符串不能像其他的,例如int类型一样直接用‘=’号赋值;

所以我们需要一个cpy函数:

void mystrcpy(char *s, char *t)

{

while ((*s++ = *t++) != '\0')

;

}

所有代码如下:

#include

#include

const int LONGEST_WORD = ; // The longest word size

struct binary_tree {

char str[LONGEST_WORD];

int count;

struct binary_tree * left;

struct binary_tree * right;

};

typedef struct binary_tree node;

enum BOOL {

NO,

YES

};

typedef enum BOOL BOOL;

BOOL cmp(char * s, char * t)

{

int i;

for (i = ; s[i] == t[i]; i++)

if ( s[i] == '\0' )

return NO;

return (s[i] - t[i]) < ? NO:YES;

}

void mystrcpy(char *s, char *t)

{

while ((*s++ = *t++) != '\0')

;

}

void insert(node ** tree, char * val) {

node * temp = NULL;

if(!(*tree)) {

temp = (node*)malloc(sizeof(node));

temp->left = temp->right = NULL;

//temp->str = val; //issue code ...

mystrcpy(temp->str,val);

temp->count = ;

*tree = temp;

return ;

}

if(cmp(val, (*tree)->str)) {

insert(&(*tree)->left,val);

}else if (cmp(val,(*tree)->str)) {

insert(&(*tree)->right,val);

}else{

(*tree)->count++;

}

}

void deltree(node * tree) {

if(tree) {

deltree(tree->left);

deltree(tree->right);

free(tree);

}

}

void print_inorder(node * tree) {

if(tree) {

print_inorder(tree->left);

printf("[%s\t\t\t]count:[%d]\n",tree->str,tree->count);

print_inorder(tree->right);

}

}

int main(int argc, char ** argv)

{

node * root;

node * tmp;

//int i;

root = NULL;

/* Inserting nodes into tree */

insert(&root,"hello");

insert(&root,"hey");

insert(&root,"hello");

insert(&root,"ok");

insert(&root,"hey");

insert(&root,"hey");

insert(&root,"hey");

printf("In Order Display\n");

print_inorder(root);

/* Deleting all nodes of tree */

deltree(root);

}

最后运行结果如下:

8c5833dfdf7151d3ab868870da0309ea.png

Discussion

那么这个程序已经完成啦!

还有很多可以优化的,也可以增加更多的功能;

例如,查找特定字符出现的次数;

或者特定字符所出现的行数,等等都可以;

我们会在日后慢慢完善;

See Also

无;

SDUT OJ 数据结构实验之二叉树三:统计叶子数

数据结构实验之二叉树三:统计叶子数 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descr ...

SDUT 3342 数据结构实验之二叉树三:统计叶子数

数据结构实验之二叉树三:统计叶子数 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 已知二叉 ...

SDUT-3342&lowbar;数据结构实验之二叉树三:统计叶子数

数据结构实验之二叉树三:统计叶子数 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 已知二叉树的一个按先序遍历输入的字符 ...

第六章 第一个Linux驱动程序:统计单词个数

现在进入了实战阶段,使用统计单词个数的实例让我们了解开发和测试Linux驱动程序的完整过程.第一个Linux驱动程序是统计单词个数. 这个Linux驱动程序没有访问硬件,而是利用设备文件作为介质与应用 ...

《征服c指针》学习笔记-----统计文本单词数目的程序word&lowbar;count

1.程序的要求:对用户指定的英文文本文件(包括标准输入),将英文单词按照字母顺序输出到用户指定的文本文件中(包括标准输出),并且在各单词后面显示单词的出现次数. 2.模块设计: 主要分为:1.从输入流 ...

C&plus;&plus;读取文件统计单词个数及频率

1.Github链接 GitHub链接地址https://github.com/Zzwenm/PersonProject-C2 2.PSP表格 PSP2.1 Personal Software Pro ...

【二叉树】二叉树常用算法的C&plus;&plus;实现

常见算法有: 1.求二叉树的最大深度 2.求二叉树的最小深度 3.二叉树的层次遍历 4.二叉树的前序遍历 5.二叉树的中序遍历 6.二叉树的后序遍历 7.求二叉树的节点个数 8.求二叉树的叶节点个数 ...

使用bash关联数组统计单词

使用bash关联数组统计单词 从bash 4开始支持关联数组,使用前需要声明,即 declare -A map map[key1]=value1 map[key2]=value2 map=([key1 ...

第六章第一个linux个程序:统计单词个数

第六章第一个linux个程序:统计单词个数 从本章就开始激动人心的时刻——实战,去慢慢揭开linux神秘的面纱.本章的实例是统计一片文章或者一段文字中的单词个数.  第 1 步:建立 Linu x 驱 ...

随机推荐

Angular动画(ng-class)

ng-class 同 触发的是 addClass//当给元素添加一个class时触发, removeClass //把元素的class移除时触发

Sencha Architect 2 的使用

俗话说的好, 工欲善其事必先利其器, 用Sencha开发的语言, 自己可能不太熟悉, 写出来很麻烦, 于是给大家介绍一个工具. 启动程序第一个界面: 单击第一个Go按钮, 创建一个项目.进入以后, 单 ...

X86在逻辑地址、线性地址、理解虚拟地址和物理地址

参考:http://bbs.chinaunix.net/thread-2083672-1-1.html 本贴涉及的硬件平台是X86.假设是其他平台,不保证能一一对号入座.可是举一反三,我想是全然可行的 ...

洛谷 P1028 数的计算【递推】

P1028 数的计算 题目描述 我们要求找出具有下列性质数的个数(包含输入的自然数n): 先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理: 1.不作任何处理; 2.在它 ...

jloi2015

题解: [JLOI2015]管道连接 这个很水 比较裸的斯坦纳树dp 斯坦纳树dp就是 g[i][j]表示当前在i点,状态为j 然后转移分为两种 g[i][j]=g[i][k]+g[i][k^j] 另 ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值