在建立结构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. java中的算术运算符、赋值运算符、比较运算符、逻辑运算符、条件运算符

    一.算术运算符 算术运算符主要用于进行基本的算术运算,如加法.减法.乘法.除法等. Java 中常用的算术运算符: 其中,++ 和 -- 既可以出现在操作数的左边,也可以出现在右边,但结果是不同滴 例 ...

  2. 配置Eclipse编写HTML/JS/CSS/JSP页面的自动提示。

    我们平时用eclipse开发jsp页面时智能提示效果不太理想,今天用了两个小时发现了eclipse也可以像Visual Studio 2008那样完全智能提示HTML/JS/CSS代码,使用eclip ...

  3. Sql Server 分区之后增加新的分区

    随着时间的推移,你可能会希望为已分区的表添加额外的分区(例如,可以为每一个新年创建一个新的分区).要增加一个新的分区,可以使用ALTER PARTITION SCHEME和ALTER PARTITIO ...

  4. NopCommerce 框架系列(一)

    今天,终于抽出时间来写写博文,也希望自己能养成写博文的好习惯,大神勿喷. 我从NopCommerce官网上下载了源码,以便自己学习研究,如有需要下载源码的朋友,请点击链接: http://www.no ...

  5. JSP知识

    五.JSP概述及最佳实践1.更改MyEclipse生成的JSP模板.模板文件与Servlet.java(Servlet模板文件)很近.2.学好JSP的关键:JSP就是Servlet.一定要记住JSP中 ...

  6. 网站内容禁止复制和粘贴、另存为的js代码(转)

    1.使右键和复制失效 方法1: 在网页中加入以下代码: 代码如下: <script language="Javascript"> document.oncontextm ...

  7. 【Java学习笔记】集合转数组---toArray()

    package p2; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ...

  8. delegate notification kvo三者比较

    IOS 如何选择delegate.notification.KVO? 前面分别讲了delegate.notification和KVO的实现原理,以及实际使用步骤,我们心中不禁有个疑问,他们的功能比较类 ...

  9. Json数据中的特殊字符处理

    今天在项目中遇到一个问题,页面上的数据突然显示不出来了,查验后得知是Json数据出现了问题.使用JSON从后台向前台传输数据的时候,当数据本身含有一些特殊字符,会导致JSON数据的解析出错.如果内容中 ...

  10. Qt Qwt之坐标轴移动

    最近接触到个pro需要做到这方面,于是找了相关材料,也跟好些人讨论,目前就最简单的使用方法,通过按钮触发去控制 X,Y轴的移动,比例自己定义 这个是X轴放大的 QwtInterval tempInte ...