读入一个c程序,并按字母表顺序分组打印变量名,每组前N个字符相同(TCPL 练习6-2)
2013-09-17 16:49
573 查看
在建立结构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>0&&(**(++argv)=='-'))?atoi(++(*argv)):6; while(getword(word,MAXWORD)!=EOF &&(sizeof word/sizeof(char)) >=num) if(isalpha(word[0])||word[0]=='_') root=mtree(root,word); actreeprint(root); return 0; } struct tnode *addtree(struct tnode *p, char *w) { int cond; if(p==NULL) { p=talloc(); p->word=strduper(w); p->count=1; p->left=p->right=NULL; } else if ((cond= strcmp(w,p->word))==0) p->count++; else if (cond <0) 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=1; } else if ((cond=strncmp(w,aroot->nroot->word,num))==0) { addtree(aroot->nroot,w); aroot->count++; } else if (cond <0) 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)+1); 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)
- 编写一个程序,输入一串不超过60个字符组成的且不包含换行符的字符串,将字符串中的A到Z的字母按英文字典字母顺序重新排列,排列后的单词的长度要与原始句子中的长度相同,并且要求只对A到Z的字母重新排列,其
- 编写一个程序读入一行输入,然后反向打印该行,您可以把输入存储在一个char数组中: 假定该行不超过255个字符。回忆一下,您可以使用具有%c说明符的scanf()从输入中一次 读入一个字符,而且当您按
- 练习 1-14 编写一个程序,打印输入中各个字符出现频度的直方图
- 通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉。
- 通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉。
- 编写一个程序读入一行输入,然后反向打印该行,您可以把输入存储在一个char数组中: 假定该行不超过255个字符。回忆一下,您可以使用具有%c说明符的scanf()从输入中一次 读入一个字符,而且当您按下回车键时会产生换行符(/n)
- 从标准输入读入一个由字母构成的串(不大于30个字符)。从该串中取出3个不重复的字符,求所有的取法。取出的字符,要求按字母升序排列成一个串。不同的取法输出顺序可以不考虑。
- 练习 7-6 编写一个程序,比较两个文件并打印它们第一个不相同的行
- C primer plus 第七章 练习2: 编写一个程序,该程序读取输入直到遇到#字符。使程序打印每个输入的字符以及它的十进制ASCII码。每行打印8个字符/编码对。
- 一个由24个字母组成的数组,其中每个字符出现3次(也就是8组相同字母,混序放在一个数组中),用程序实现将相同字母的下标存入一个8*3的数组中
- 通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉。
- 练习1-17 编写一个程序,打印长度大于80个字符的所有输入行。
- 通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉。
- 练习1-14 编写一个程序,打印输入中各个字符出现频度的直方图(水平)
- 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 结果请按字母顺序输出。
- 通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉。 比如字符串“abacacde”过滤结果为“abcde”。 要求实现函
- 练习2-1 编写一个程序一确定分别由signed及unsigned限定的char,short,int及long类型变量的取值范围。采用打印标准头文件中的相应值以及直接计算两种方式实现。通过直接计算来确定浮点类型的取值范围是一项难度很大的任务。
- 练习1-17 编写一个程序,打印长度大于80个字符的所有输入行.
- 练习1-19 编写函数 reverse(s),将字符串s 中的字符顺序颠倒过来。使用该函数编写一个程序,每次颠倒一个输入行中的字符顺序。