在建立结构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. UiAutomator自动化测试框架介绍

    UiAutomator自动化测试框架介绍 环境搭建 1         必要条件 1.1       JDK 1.2       SDK(API高于15) 1.3       Eclipse 2    ...

  2. js闭包使用

    闭包就是在一个函数内定义一个内部函数 并返回内部函数 function f1(){ var a=1; add=function(){a=a+1;} function f1Sub(){ console. ...

  3. HR开发 获取信息类型数据

    1.PNP逻辑数据库. LOOP获取信息类型数据. TABLES: PERNR . , . START-OF-SELECTION. GET PERNR . LOOP AT P0000 WHERE .. ...

  4. c# long转 datetime

    ; DateTime start = , , , , , , DateTimeKind.Utc); DateTime date = start.AddMilliseconds(time).ToLoca ...

  5. MVC中获取模型属性的Range和StringLength验证特性设置

    MVC中的客户端及服务端模型验证信息都以ModelMetadata类型作为承载,在获得属性的ModelMetadata之后(还不知道怎么获取ModelMetadata的童鞋请自行恶补),我们可以轻松得 ...

  6. Javascript.ReactNative-2-javascript-syntax-in-react-native

    JavaScript Syntax in React Native Contents: Arrow Function Let+Const Default + Rest + Spread Destruc ...

  7. VS2012开发工具BUG

    发现VS2012开发工具 新建立项目名称长度限制的一个bug, 向导方式名称长度限制56个,但建立好的项目名称长度是可以改的很长很长. 也有想是不是生成程序集的名称会有限制,同样这里生成程序集名称,及 ...

  8. 影响google PageRank的因素

    1 与pr高的网站做链接: 2 内容质量高的网站链接 3 加入搜索引擎分类目录 4 加入免费开源目录 5 你的链接出现在流量大.知名度高.频繁更新的重要网站上 6 google对PDF格式的文件比较看 ...

  9. vs2015 command prompt here

    网上搜的很多方法都不能用,比如:http://app.paraesthesia.com/CommandPromptHere/ 主要是都搞错了注册表路径,写成了: HKCR,Directory\Shel ...

  10. 关于 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause() 错误

    最近在做项目的时候发现一个如题的控制台报错. 一看右侧的报错文件是undefined 这下苦恼了,定位不到问题所在. 今天解决了这个问题,就来分享一下. 问题的关键所在是在执行了play()方法以后立 ...