打印文本中的所有单词,并且打印每个单词出现的行号,非实义单词不考虑(TCPL,练习6-3)

建立一棵二叉树,每个节点存放单词以及指向一个链表的指针,以及指向左右节点的指针。链表内存放行号以及指向下一个链表节点的指针。

每录入一个单词,先寻找二叉树,再寻找它的链表,分别将单词和行号插入二叉树和链表,这样,每一个单词自然就有一个属于它的行号链表。

最后打印。


代码如下:


#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>

#define MAXWORD 100
#define MAXHANG 10000 

extern int getword(char *word, int lim);
struct hang *hes(struct hes *, int);		/* 链表hang,每个节点存放行数及一个指向下一个行的指针 */
struct ci *cc(struct ci *, char *, int);/*  二叉树ci,每个节点存放一个单词以及一个指向链表hang的指针 */
void hesprint(struct hes *);			/*  打印链表 */
void ccprint(struct cc *);			/*  打印二叉树 */
struct hang *talloc(void);			/*  为树cc申请储存空间 */
struct ci *atalloc(void);		/*  为树cc申请储存空间 */
char *strduper(char *s);			/*  word存放在一个安全的地方 */
int exclude(char *);

struct hang {
	int x;
	struct hang *next;
};

struct ci {
	char *word;
	struct hang *hangg;
	struct ci *left;
	struct ci *right;
};




/*  编写程序,打印文本中的所有单词,并且打印每个单词出现的行号,is,to等非实意单词不考虑 */
main() {
	struct ci *root;
	char word[MAXWORD];
	int hangs;

	root=NULL;
	
	while((hangs=getword(word,MAXWORD))!=EOF)					/*  getword返回行号  */
		if((isalpha(word[0])||word[0]=='_')&&!exclude(word))	/*  函数exclude确认单词是否可以被忽略 */
			root=cc(root,word,hangs);
	ccprint(root);
	return 0;
}
struct ci *cc(struct ci *p, char *w, int x) {
	int cond;

	if(p==NULL) {
		p=atalloc();
		p->word=strduper(w);
		p->hangg=NULL;
		p->hangg=hes(p->hangg,x);
		p->left=p->right=NULL;

	} else if ((cond= strcmp(w,p->word))==0)
		p->hangg=hes(p->hangg,x);
	else if (cond <0)
		p->left=cc(p->left,w,x);
	else 
		p->right=cc(p->right,w,x);
	return p;
}

struct hang *hes(struct hang *p, int x) {
	
	

	if(p==NULL) {
		p=talloc();
		p->x=x;
		p->next=NULL;
	} else if (p->x==x) 
		;
	else if (p->x!=x)
		p->next=hes(p->next,x);
	return p;

}

struct hang *talloc(void) {
	return (struct hang *) malloc(sizeof(struct hang));

}
struct ci *atalloc(void) {
	return (struct ci *) malloc(sizeof(struct ci));
}
char *strduper(char *s) {
	char *p;

	p=(char *)malloc(strlen(s)+1);
	if(p!=NULL)
		strcpy(p,s);
	return p;	
}

void hesprint(struct hang *p) {
	if(p!=NULL) {
		printf("%4d ",p->x);
		hesprint(p->next);
	}
}
void ccprint(struct ci *p) {
	if(p!=NULL)
	{
		ccprint(p->left);
		printf("%s	",p->word);
		hesprint(p->hangg);
		printf("\n");
		ccprint(p->right);
	}

}

int exclude(char *s) {
	static char *ex[]={
		"a",
		"an",
		"and",
		"are",
		"in",
		"is",
		"of",
		"or",
		"that",
		"the",
		"this",
		"to"
	};
	int cond,mid;
	int low=0;
	int high=sizeof(ex)/sizeof(char *)-1;
	
	while(low<=high) {
	mid=(low+high)/2;
	if((cond=strcmp(s,ex[mid]))==0)
		return 1;
	else if(cond<0) 
		high=mid-1;
	
	else if(cond>0) 
		low=mid+1;
	
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值