2014年06月04日

//统计关键字的个数
#include
#include
#include
#define MAXWORD 100 //关键字最大的个数
struct key{
 char *word;
 int count;
}keytab[]={
 {"auto",0},
 {"break",0},
 {"case",0},
 {"char",0},
 {"const",0},
 {"continue",0},
 
 {"default",0},
 {"unsigned",0},
 {"void",0},
 {"volatile",0},
 {"while",0}
};
//关键字的个数等于数组的长度除以单个元素的长度
#define NKEYS (sizeof keytab/sizeof(struct key))
int getword(char *,int );//从输入中读取下一个字符或者单词
int binsearch(char *,struct key *,int );
//从tab[0]到tab[n-1]中查找单词
int main()
{
 int n;
 char word[MAXWORD];
 while(getword(word,MAXWORD)!='EOF')
 {
  if(isalpha(word[0]))//word的第一个单词为字母
   if((n=binsearch(word,keytab,NKEYS))>=0)
    keytab[n].count++;
   //在结构体中查找成功,关键字个数加1
 }
 //统计结束,打印结果
 for(n=0;n
 {
  if(keytab[n].count>0)
   printf("M %s\n",keytab[n].count,keytab[n].word);
 }
 return 0;
}

//binsearch:find word in tab[0],...tab[n-1]
//折半查找
int binsearch(char *word,struct key tab[],int n)
{
 int cond;
 int low,high,mid;
 low=0;
 high=n-1;
 while(low<=high)
 {
  mid=(low+high)/2;
  //下面这段有点奇怪为啥
  if((cond=strcmp(word,tab[mid].word))<0)
   high=mid-1;
  else if(cond>0)
   low=mid+1;
  else
   return mid;
 }
 return -1;
}
//getword从输入中读取下一个单词是
//以字母开头的字母和数字串
//也可以是以字母开头的字母和数字串
//也可以是一个非空白字符串
//函数返回值可能是单词的第一个字符、
//文件结束符EOF或字符本身(如果不是字符或者字母本身)
int getword(char *word,int lim)
{
 int c,getch(void);
 void ungetch(int);
 char *w=word;
 while(isspace(c=getch()))//跳过空白符
  ;
 if(c!=EOF)
  *w++=c;
 if(!isalpha(c))//c不是字母
 {
  *w='\0';
  return c;
 }
 for(;--lim>0;w++)
 {
  if(!isalnum(*w=getch()))//输入不是字母或数字时,该单词结束
  {
   ungetch(*w);
   break;
  }
 }
 *w='\0';//字符串结束符'\0'
 return word[0];//返回值是单词的第一个字符
}

#define BUFSIZE 100//缓冲区的大小
char buf[BUFSIZE]; //用于ungetchar函数的缓冲区
int bufp=0;//buf中下一个空闲位置
//读取一个字符(可能是压回的字符)
int getch(void)
{
 return(bufp>0)?buf[-bufp]:getchar();
}
//把字符压回到输入中
void ungetch(int c)
{
 if(bufp>=BUFSIZE)
  printf("ungetch:too many characters\n");
 else
  buf[bufp++]=c;
}

//二叉树统计单词的个数,若单词第一次出现,则产生新的树节点
#include
#include
#include
#include

#define MAXWORD 100

struct tnode{//树的节点
 char *word;//指向单词的指针
 int count;//单词出现的次数
 struct tnode *left;//左子节点
 struct tnode *right;//右子节点
};
struct tnode *addtree(struct tnode *,char *);
struct tnode *talloc(void);
char *strdup(char *);
void treeprint(struct tnode *);
int getword(char *,int);

int main()
{
 struct tnode *root;
 char word[MAXWORD];
 root=NULL;
 while(getword(word,MAXWORD)!=EOF)
 {
  if(isalpha(word[0]))
   root=addtree(root,word);
 }
 treeprint(root);
 return 0;
}
//在p的位置或者p的下方增加一个w节点
struct tnode *addtree(struct tnode *p,char *w)
{
 int cond;
 if(p==NULL)
 {
  p=talloc();
  p->word=strdup(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;
}
//递归打印树,在每个节点,先打印左子树(小于该单词的所有单词)
//然后是该单词本身,最后是右子树(大于该单词的所有单词)
void treeprint(struct tnode *p)
{
 if(p!=NULL)
 {
  treeprint(p->left);
  printf("M %s\n",p->count,p->word);
  treeprintf(p->right);
 }
}
//创建一个node节点
struct tnode *talloc(void)
{
 return (struct tnode *)malloc(sizeof(struct tnode));
 //强制类型转换
}
//复制s
char *strdup(char *s)
{
 char *p;
 p=(char *)malloc(strlen(s)+1);
 if(p!=NULL)
  strcpy(p,s);
 return p;
}
//getword从输入中读取下一个单词是以字母开头的字母和数字串
//也可以是以字母开头德字母和数字串,也可以是一个非空白字符串
//函数返回值可能是单词的第一个字符,文件结束符EOF或者字符本身
//如果该字符不是字母字符本身
int getword(char *word,int lim)
{
 int c,getch(void);
 void ungetch(int);
 char *w=word;
 while(isspace(c=getch()))//跳过空白符
  ;
 if(c!=EOF)
  *w++=c;
 if(!isalpha(c))//c不是字母
 {
  *w='\0';
  return c;
 }
 for(;--lim>0;w++)
 {
  if(!isalnum(*w=getch()))
   //输入不是字母或者数字时,该单词结束
  {
   ungetch(*w);
   break;
  }
 }
 *w='\0';//字符串结束符'\0'
 return word[0];//返回值是单词的第一个字符
}
#define BUFSIZE 100//缓冲区的大小
char buf[BUFSIZE];//用于ungetchar函数的缓冲区
int bufp=0;//buf中下一个空闲位置
//读取一个字符,可能是压回的字符
int getch(void)
{
 return (bufp>0)?buf[--bufp]:getchar();
}
//把字符压回输入中
void ungetch(int c)
{
 if(bufp>=BUFSIZE)
  printf("ungetch:too many characters\n");
 else
  buf[bufp++]=c;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值