在建立结构tnode的过程中,我们没有预设门槛。这道题目就设置了门槛,必须根据前N个字符来进行分组,于是排除了长度小于N的变量,以便减轻负担。

因为要求对变量名分组打印,组别理所应当地应该按照至少是升序来排列,在每一组内,也至少应该是升序排列(以字母顺序),于是构造一棵二叉树,它的每一个节点都指向另一棵二叉树,即一棵由二叉树构成的二叉树。这样,在我们对每一个母二叉树的节点进行访问的时候,也可以遍历它所指向的子二叉树,也就是每一个组别内的升序排列实现了。遍历母二叉树的过程也实现了各组升序排列。

代码如下:

 #include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h> #define MAXWORD 100 extern int getword(char *word, int lim);
struct tnode *addtree(struct tnode *, char *); /* 二叉树tnode,每个节点存放一个word以及其出现的次数 */
struct maketree *mtree(struct maketree *, char *);/* 二叉树maketree,每个节点指向一棵二叉树tnode */
void trreprint(struct tnode *); /* 打印二叉树tnode */
void actreeprint(struct maketree *); /* 打印二叉树maketree */
struct tnode *talloc(void); /* 为树tnode申请储存空间 */
struct maketree *atalloc(void); /* 为树maketree申请储存空间 */
char *strduper(char *s); /* word存放在一个安全的地方 */
int num;
struct tnode {
char *word;
int count;
struct tnode *left;
struct tnode *right;
}; struct maketree {
int count; /* 每个节点出现的次数 */
struct tnode *nroot; /* 指向一棵tnode二叉树 */
struct maketree *left; /* 左子树 */
struct maketree *right;/* 右子树 */
};
/* 编写程序,按字母顺序打印文本中的变量名,每一组内各变量前6个字符相同,其余字符不同,不考虑注释、字符常量等,6可在命令行中更改 */
main(int argc, char *argv[]) {
struct maketree *root;
char word[MAXWORD]; root=NULL;
num=(--argc>&&(**(++argv)=='-'))?atoi(++(*argv)):;
while(getword(word,MAXWORD)!=EOF &&(sizeof word/sizeof(char)) >=num)
if(isalpha(word[])||word[]=='_')
root=mtree(root,word);
actreeprint(root);
return ;
}
struct tnode *addtree(struct tnode *p, char *w) {
int cond; if(p==NULL) {
p=talloc();
p->word=strduper(w);
p->count=;
p->left=p->right=NULL; } else if ((cond= strcmp(w,p->word))==)
p->count++;
else if (cond <)
p->left=addtree(p->left,w);
else
p->right=addtree(p->right,w);
return p;
} struct maketree *mtree(struct maketree *aroot, char *w) { int cond; if(aroot==NULL) {
aroot=atalloc();
aroot->nroot=NULL;
aroot->nroot=addtree(aroot->nroot,w); /* 将word传递给二叉树tnode */
aroot->left=aroot->right=NULL;
aroot->count=;
} else if ((cond=strncmp(w,aroot->nroot->word,num))==) {
addtree(aroot->nroot,w);
aroot->count++;
} else if (cond <)
aroot->left=mtree(aroot->left,w);
else
aroot->right=mtree(aroot->right,w);
return aroot; } struct tnode *talloc(void) {
return (struct tnode *) malloc(sizeof(struct tnode)); }
struct maketree *atalloc(void) {
return (struct maketree *) malloc(sizeof(struct maketree));
}
char *strduper(char *s) {
char *p; p=(char *)malloc(strlen(s)+);
if(p!=NULL)
strcpy(p,s);
return p;
} void treeprint(struct tnode *p) {
if(p!=NULL) {
treeprint(p->left);
printf("%4d %s\n", p->count, p->word);
treeprint(p->right);
}
}
void actreeprint(struct maketree *p) {
if(p!=NULL)
{
actreeprint(p->left);
treeprint(p->nroot);
printf("\n");
actreeprint(p->right);
}
}

读入一个c程序,并按字母表顺序分组打印变量名,每组前N个字符相同(TCPL 练习6-2)的更多相关文章

  1. MYSQL 按某个字段分组,然后取每组前3条记录

    先初始化一些数据,表名为 test ,字段及数据为: SQL执行结果为:每个 uid  都只有 3 条记录.   SQL语句为: SELECT   * FROM   test main WHERE   ...

  2. 第一个Java程序HelloWorld

    代码如下: // 一个文件中只能有一个共有的类,并且与文件名称一致,大小写注意 public class HelloWorld{// 程序的入口public static void main(Stri ...

  3. Python初学者第一天 Python安装及第一个Python程序

    Python基础: 1day: 1.Python基础: A.编程语言介绍:     a. 计算机只能理解0和1.编程即写一段按照一定规则写代码,让计算机帮你干活:     b.机器语言:最底层的语言, ...

  4. python新手第一天学习笔记-第一个ptyhon程序和python变量

    一.python 的注释和第一个python 程序 : 1.单行注释 # Author Xiajq 2.多行注释 ''' ------------注释内容----------------------- ...

  5. 创建第一个c程序

    创建,组织,生成 ,生成. 1.我们先创建一个win32项目. 文件->新建->项目->Visual C++ ->Win32   输入项目名称   选择项目保存位置 很重要的一 ...

  6. C++学习45 流成员函数put输出单个字符 cin输入流详解 get()函数读入一个字符

    在程序中一般用cout和插入运算符“<<”实现输出,cout流在内存中有相应的缓冲区.有时用户还有特殊的输出要求,例如只输出一个字符.ostream类除了提供上面介绍过的用于格式控制的成员 ...

  7. SQL SERVER 一个SQL语句的执行顺序

    一个SQL 语句的执行顺序 1.From (告诉程序 来自哪张表  如果是表表达式 依旧是如此顺序) 2.Where(条件筛选  谓词筛选 ) 3.Group by(分组) 4.Having(分组   ...

  8. C#语言————第一章 第一个C#程序

    第一章    第一个C#程序 ******************C#程序***************     ①:建立项目:文件-->新建-->项目-->c#-->控制台程 ...

  9. GPU 编程入门到精通(三)之 第一个 GPU 程序

    博主因为工作其中的须要.開始学习 GPU 上面的编程,主要涉及到的是基于 GPU 的深度学习方面的知识,鉴于之前没有接触过 GPU 编程,因此在这里特地学习一下 GPU 上面的编程.有志同道合的小伙伴 ...

随机推荐

  1. JavaScript之作用域和引用类型

    学习js高级程序设计第四.五章 4.1基本类型和引用类型的值:基本类型值指的是简单的数据段,引用类型值指可能由多个值构成的对象. 引用类型的值是保存在内存中的对象,不能直接访问,而是按引用访问(类似指 ...

  2. TCP协议学习记录 (一) ICMP时间戳请求

    程序只实现了获取时间戳,至于将时间戳转换成具体日期和时间,暂时没有好的办法. #define TIME_STAMP_REQUEST 13 struct iphdr { unsigned ; //包头长 ...

  3. linux driver编译环境搭建和命令

    首先将ubuntu14.04的内核升级到内核3.18.12. 其次,Ubuntu14.04上驱动编译命令 $ sudo make -C ~/linux-3.18.12/ M=`pwd` modules ...

  4. 准备开发一款开源NES模拟器

    前几天无意见看到一些NES的开发资料,勾起了小时候暑假的无数美好回忆,做为一名码农,萌发了自己写一款模拟器的想法.一来可以加深自己对整个系统/游戏的理解,一来可以实现小时候的梦想:),希望可以坚持下来 ...

  5. TCP3次握手和4次挥手

    为什么握手是3次,挥手是4次? 因为握手的时候,ACK+SYN可以一起发送,而4次挥手是Server端发送对Client的FIN的ACK后不一定会立即断开连接,需要将ACK和FIN分开发送 为什么TI ...

  6. Daily Scrum 12.16

    今日完成任务: 完善了资源界面的UI设计:解决了PDF显示相同的问题:解决了下载时有时找不到文件的问题,因为上届建了upload和resource两个文件夹存文件,写代码时候写乱套了. 明日任务: 黎 ...

  7. asp.net大文件上传与上传文件进度条问题

    利用Plupload解决大容量文件上传问题, 带进度条和背景遮罩层 关于Plupload结合上传插件jquery.plupload.queue的使用 这是群里面一位朋友给的资料. 下面是自己搜索到的一 ...

  8. React阶段开发总结

    这次独立编写了React页面主要是数据切换.点击不同的按钮,Ajax请求不同的后台数据.数据驱动表格内容的显示.使用React组件开发. 开发中获得下面的心得: 1.后台给的地址早一点添加路由(写好数 ...

  9. 关于CSS中text-decoration值没有替换而是累积的疑问

    做了个实验: <!DOCTYPE html> <html> <head> <title>BaiDuTest.html</title> < ...

  10. iOS:小技巧(转)

    记录下一些不常用技巧,以防忘记,复制用. 1.获取当前的View在Window的frame: 1 2 UIWindow * window=[[[UIApplication sharedApplicat ...