《计算机算法基础》
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
返回参数:无;
功能:对存放在buffer2中的字符串进行二分检索,统计比较次数;
调用情况:由reading()子程序调用后返回;
(4)binarytree( )子程序
形参:字符数组buffer3;
返回参数:无;
功能:利用构造的二分检索树对buffer3中的字符串进行检索,统计比较次数;
调用情况:由reading()子程序调用后返回;
然后利用动态规划的思想由P、Q计算每一棵可能二分检索树子树的最小检索成本和对应的根结点R,下一步即可由生成的R构造出一棵最优二分检索树。接下来画出这棵二叉树,再用这棵二分检索树和二分检索法方法去检索同一C程序,进行检索成本的比较,至此,整个程序结束。
3.流程图(见下页)
4.全局变量与子程序
(1)全局变量
2.分析
由设计要求可确定程序的几大模块:读入源程序,找出其中的标示符对P、Q计数构造二分检索树显示该二分检索数用该二分检索树和二分检索同一C程序中的标示符,比较检索成本。
进一步确定几个子程序及相互间的到一个标示符,调用计数子程序对P或Q中的某一对应项进行加一操作,返回读文件子程序继续分析并调用计数子程序对P、Q计数,直至指定源程序结束,若还需继续读入,再调用度文件子程序对下一个指定的源程序进行读入和对P、Q进行计数操作,直到用户不再需要读入源程序为止。
{ /*统计待检索的C程序的标识符个数和二分检索的比较次数*/
int low=1,high=32,mid;
quantity++;
while(low<=high)
{times1++; /*每判断大小一次,比较次数加1*/
mid=(low+high)/2;
if(strcmp(buffer2,key[mid])<0)
{switch(status)
{case 0: if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_'))
/*在初态下,遇到字母或下划线,则是合法标识符的开始*/
{status=4;
buffer[i]=ch; /*转状态4并将读入字符存入缓冲数组*/
《计算机算法基础》
课程设计报告
标题:最优二分检索树
单位:计算机学院2001级13班
报告人:龚勋200131500342
指导教师:袁梦霆
编程环境:Turboc 2.0
时间:2003年12月20日
1.设计要求
设计一程序,能够读入多个C源程序,识别其中的标示符(包括关键字和非关键字),从而获得关键字和非关键字出现的概率P、Q,根据P、Q生成一棵最优二分检索树,在屏幕上显示这棵树,分别用二分检索和该最优二分检索树对某一个C语言程序中的标示符进行检索,并统计检索成本(即比较次数)。
int find1=1,find2=1; /*判断输入的文件名是否有效*/
int p[33],q[33]; /*统计源文件中关键字和非关键字出现的概率*/
int w[33][33],c[33][33],r[33][33]; /*为构造二分检索树定义的数组*/
struct tree
{int number;
{numbers+=p[i];
numbers+=q[i];
}
printf("\nthere are %d identifiers",numbers);
}
void reading(int command)
{ /*依次按字符读C源文件,每遇到合法标识符转count()函数修改计数值,
command变量用来区别是建树时还是比较检索成本时调用的该函数*/
{printf("\nfile not find,so the arrays P and Q cannot save");
return; /*指定存入的文件名错误,则返回*/
}
printf("save success!");
fputc('P',fp);
fputc(':',fp);
fputc(' ',fp);
形参:无;
返回参数:无;
功能:利用动态规划的思想计算所有可能子树的根结点序号;
调用情况:由主程序调用;
(8)createtree( )子程序
形参:整形变量a、b,分别是待建二叉树结点对应序号的起止值;
返回参数:最优二分检索树的根结点;
功能:在内存中构造最优二分检索树;
调用情况:由主程序调用;
(9)high( )子程序
形参:指向根结点的结构体指针;
返回参数:最优二分检索树的高度;
功能:求构造的最优二分检索树的高度;
调用情况:由绘图子程序drawtree()调用;
(10)drawtree( )子程序
形参:检索树的高度和内存中的根结点指针;
返回参数:无;
功能:在屏幕上画出最优二分检索树;
调用情况:由主程序调用;
5.源程序
struct tree *llink,*rlink;
}; /*二分检索树结点的内存中的表示方式*/
struct tree *root; /*构造的检索树的根结点*/
int quantity=0,times1=0,times2=0; /*作检索成本比较时用来记录标识符的个数和总共比较次数*/
void count(char buffer1[])
(2)count( )子程序
形参:字符数组buffer1
返回参数:无
功能:用二分检索查找存放在buffer1中的字符串,若找到,对P中该关键字的计数值加一;否则,对Q中相应位加一;
调用情况:由reading()子程序调用后返回;
否
是
否
是
是
否
(3)binary( )子程序
形参:字符数组buffer2;
"else","enum","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef",
"union","unsigned","void","volatile","while"}; /*C语言所有关键字,共32个*/
high=mid-1;
else if(strcmp(buffer2,key[mid])>0)
low=mid+1;
else
return;
}
}
void binarytree(char buffer3[])
{ /*统计采用构造的检索树的检索成本*/
struct tree *p=root;
while(p)
{times2++;
char filename[20];
FILE *fp;
int i,numbers=0;
printf("\nthe file you want to save the arrays P,Q:");
scanf("%s",filename);
if((fp=fopen(filename,"w"))==NULL)
char *key[ ]:存放C语言32个关键字的指针数组;
int find1,find2:分别用来记录用户输入的C源程序名和最后的检索比较程序名是否合法;
int p[33],q[33]:p[i ]和q[ i ]分别是成功检索和不成功检索的概率;
int w[33][33],c[33][33],r[33][33]:w[ i ][ j ]为子树T(i,j)的概率;c[ i ][ j ]为子树T( i ,j)的检索成本;r[ i ][ j ]为子树T( i, j)的根结点序号;
break;
case 4: if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_')||
FILE *fp;
char fileName[20];
char ch;
char buffer[35];
int status=0; /*定义的状态变量*/
int i=0,j;
char choose;
printf("\nthe file name:");
scanf("%s",fileName);
if((fp=fopen(fileName,"r"))==NULL)
i++;
}
else if(ch=='/') /*若是'/'字符,有可能是合法注释的开始,转状态1*/
status=1;
break;
case 1: if(ch=='*') /*在已经遇到'/'字符的情况下再检索到'*'字符,
则是合法注释的开始*/
status=2;
else /*若'/'字符之后不是'*',则转回初态*/
(5)save()子程序
形参:无;
返回参数:无;
功能:统计所有源文件中标识符的个数并将P、Q存入指定文件中;
调用情况:由reading()子程序调用后返回;
(6)reading( )子程序
形参:整形变量command,当command=1,表明是建树时调用;当command=2,表明是比较检索成本时调用;
low=mid+1;
else
{p[mid]++;
return; /*能检索到,则相应关键字的计数位加1并返回到reading()函数*/
}
}
q[(low+high)/2]++; /*检索不到,则该非关键字的位置应在两个数组指针正中间*/
return;
}
void binary(char buffer2[])
for(i=1;i<=32;i++)
fprintf(fp,"%2d,",p[i]);
fputc('\n',fp);
fputc('Q',fp);
fputc(':',fp);
for(i=0;i<=32;i++)
fprintf(fp,"%2d,",q[i]);
numbers+=q[0];
for(i=1;i<=32;i++)
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<graphics.h>
#define LEN sizeof(struct tree)
char *key[]={" ","auto","break","case","char","const","continue","default","do","double",
struct tree
{int number;
struct tree *llink,*rlink;
}:内存中结点的表示方式;
struct tree *root:内存中二叉树的根结点;
int quantity=0,times1=0,times2=0:作检索成本比较时文件中标识符的个数和两种方法各自比较次数*/
if(strcmp(buffer3,key[p->number])<0)
p=p->llink;
else if(strcmp(buffer3,key[p->number])>0)
p=p->rlink;
else
return;
}
}
void save()
{ /*将关键字和非关键字的计数值P、Q存入指定文件中*/
返回参数:无;
功能:当command=1,读入用户指定的源文件,按字符依次搜索其中的标识符,每找到一个便调用count()子程序对P、Q计数,直至文件结束,若还需读文件,则继续调用其本身,否则调用save()子程序将P、Q存入指定文件后,然后返回主程序;
调用情况:由主程序调用;
(7)OBST()子程序
{ /*统计一C程序中的各关键字和非关键字的个数*/
int low=1,high=32,mid;
while(low<=high)
{mid=(low+high)/2;
if(strcmp(buffer1,key[mid])<0)
high=mid-1;
else if(strcmp(buffer1,key[mid])>0)
status=0;
break;
case 2: if(ch=='*') /*遇到第二个'*'字符,有可能是注释的结束,转状态3*/
status=3;
break;
case 3: if(ch=='/') /*合法注释的结束*/
status=0;
else
status=2; /*否则,刚才遇到的'*'字符无效,转回状态2*/
{printf("cannot open file");
if(command==1)
find1=0;
if(command==2)
find2=0;
return;
}
getchar(); /*吸收输入文件名时最后敲入的回车*/
ch=fgetc(fp);
while(ch!=EOF) /*按字符依次读文件,直至结束*/
功能:对存放在buffer2中的字符串进行二分检索,统计比较次数;
调用情况:由reading()子程序调用后返回;
(4)binarytree( )子程序
形参:字符数组buffer3;
返回参数:无;
功能:利用构造的二分检索树对buffer3中的字符串进行检索,统计比较次数;
调用情况:由reading()子程序调用后返回;
然后利用动态规划的思想由P、Q计算每一棵可能二分检索树子树的最小检索成本和对应的根结点R,下一步即可由生成的R构造出一棵最优二分检索树。接下来画出这棵二叉树,再用这棵二分检索树和二分检索法方法去检索同一C程序,进行检索成本的比较,至此,整个程序结束。
3.流程图(见下页)
4.全局变量与子程序
(1)全局变量
2.分析
由设计要求可确定程序的几大模块:读入源程序,找出其中的标示符对P、Q计数构造二分检索树显示该二分检索数用该二分检索树和二分检索同一C程序中的标示符,比较检索成本。
进一步确定几个子程序及相互间的到一个标示符,调用计数子程序对P或Q中的某一对应项进行加一操作,返回读文件子程序继续分析并调用计数子程序对P、Q计数,直至指定源程序结束,若还需继续读入,再调用度文件子程序对下一个指定的源程序进行读入和对P、Q进行计数操作,直到用户不再需要读入源程序为止。
{ /*统计待检索的C程序的标识符个数和二分检索的比较次数*/
int low=1,high=32,mid;
quantity++;
while(low<=high)
{times1++; /*每判断大小一次,比较次数加1*/
mid=(low+high)/2;
if(strcmp(buffer2,key[mid])<0)
{switch(status)
{case 0: if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_'))
/*在初态下,遇到字母或下划线,则是合法标识符的开始*/
{status=4;
buffer[i]=ch; /*转状态4并将读入字符存入缓冲数组*/
《计算机算法基础》
课程设计报告
标题:最优二分检索树
单位:计算机学院2001级13班
报告人:龚勋200131500342
指导教师:袁梦霆
编程环境:Turboc 2.0
时间:2003年12月20日
1.设计要求
设计一程序,能够读入多个C源程序,识别其中的标示符(包括关键字和非关键字),从而获得关键字和非关键字出现的概率P、Q,根据P、Q生成一棵最优二分检索树,在屏幕上显示这棵树,分别用二分检索和该最优二分检索树对某一个C语言程序中的标示符进行检索,并统计检索成本(即比较次数)。
int find1=1,find2=1; /*判断输入的文件名是否有效*/
int p[33],q[33]; /*统计源文件中关键字和非关键字出现的概率*/
int w[33][33],c[33][33],r[33][33]; /*为构造二分检索树定义的数组*/
struct tree
{int number;
{numbers+=p[i];
numbers+=q[i];
}
printf("\nthere are %d identifiers",numbers);
}
void reading(int command)
{ /*依次按字符读C源文件,每遇到合法标识符转count()函数修改计数值,
command变量用来区别是建树时还是比较检索成本时调用的该函数*/
{printf("\nfile not find,so the arrays P and Q cannot save");
return; /*指定存入的文件名错误,则返回*/
}
printf("save success!");
fputc('P',fp);
fputc(':',fp);
fputc(' ',fp);
形参:无;
返回参数:无;
功能:利用动态规划的思想计算所有可能子树的根结点序号;
调用情况:由主程序调用;
(8)createtree( )子程序
形参:整形变量a、b,分别是待建二叉树结点对应序号的起止值;
返回参数:最优二分检索树的根结点;
功能:在内存中构造最优二分检索树;
调用情况:由主程序调用;
(9)high( )子程序
形参:指向根结点的结构体指针;
返回参数:最优二分检索树的高度;
功能:求构造的最优二分检索树的高度;
调用情况:由绘图子程序drawtree()调用;
(10)drawtree( )子程序
形参:检索树的高度和内存中的根结点指针;
返回参数:无;
功能:在屏幕上画出最优二分检索树;
调用情况:由主程序调用;
5.源程序
struct tree *llink,*rlink;
}; /*二分检索树结点的内存中的表示方式*/
struct tree *root; /*构造的检索树的根结点*/
int quantity=0,times1=0,times2=0; /*作检索成本比较时用来记录标识符的个数和总共比较次数*/
void count(char buffer1[])
(2)count( )子程序
形参:字符数组buffer1
返回参数:无
功能:用二分检索查找存放在buffer1中的字符串,若找到,对P中该关键字的计数值加一;否则,对Q中相应位加一;
调用情况:由reading()子程序调用后返回;
否
是
否
是
是
否
(3)binary( )子程序
形参:字符数组buffer2;
"else","enum","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef",
"union","unsigned","void","volatile","while"}; /*C语言所有关键字,共32个*/
high=mid-1;
else if(strcmp(buffer2,key[mid])>0)
low=mid+1;
else
return;
}
}
void binarytree(char buffer3[])
{ /*统计采用构造的检索树的检索成本*/
struct tree *p=root;
while(p)
{times2++;
char filename[20];
FILE *fp;
int i,numbers=0;
printf("\nthe file you want to save the arrays P,Q:");
scanf("%s",filename);
if((fp=fopen(filename,"w"))==NULL)
char *key[ ]:存放C语言32个关键字的指针数组;
int find1,find2:分别用来记录用户输入的C源程序名和最后的检索比较程序名是否合法;
int p[33],q[33]:p[i ]和q[ i ]分别是成功检索和不成功检索的概率;
int w[33][33],c[33][33],r[33][33]:w[ i ][ j ]为子树T(i,j)的概率;c[ i ][ j ]为子树T( i ,j)的检索成本;r[ i ][ j ]为子树T( i, j)的根结点序号;
break;
case 4: if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_')||
FILE *fp;
char fileName[20];
char ch;
char buffer[35];
int status=0; /*定义的状态变量*/
int i=0,j;
char choose;
printf("\nthe file name:");
scanf("%s",fileName);
if((fp=fopen(fileName,"r"))==NULL)
i++;
}
else if(ch=='/') /*若是'/'字符,有可能是合法注释的开始,转状态1*/
status=1;
break;
case 1: if(ch=='*') /*在已经遇到'/'字符的情况下再检索到'*'字符,
则是合法注释的开始*/
status=2;
else /*若'/'字符之后不是'*',则转回初态*/
(5)save()子程序
形参:无;
返回参数:无;
功能:统计所有源文件中标识符的个数并将P、Q存入指定文件中;
调用情况:由reading()子程序调用后返回;
(6)reading( )子程序
形参:整形变量command,当command=1,表明是建树时调用;当command=2,表明是比较检索成本时调用;
low=mid+1;
else
{p[mid]++;
return; /*能检索到,则相应关键字的计数位加1并返回到reading()函数*/
}
}
q[(low+high)/2]++; /*检索不到,则该非关键字的位置应在两个数组指针正中间*/
return;
}
void binary(char buffer2[])
for(i=1;i<=32;i++)
fprintf(fp,"%2d,",p[i]);
fputc('\n',fp);
fputc('Q',fp);
fputc(':',fp);
for(i=0;i<=32;i++)
fprintf(fp,"%2d,",q[i]);
numbers+=q[0];
for(i=1;i<=32;i++)
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<graphics.h>
#define LEN sizeof(struct tree)
char *key[]={" ","auto","break","case","char","const","continue","default","do","double",
struct tree
{int number;
struct tree *llink,*rlink;
}:内存中结点的表示方式;
struct tree *root:内存中二叉树的根结点;
int quantity=0,times1=0,times2=0:作检索成本比较时文件中标识符的个数和两种方法各自比较次数*/
if(strcmp(buffer3,key[p->number])<0)
p=p->llink;
else if(strcmp(buffer3,key[p->number])>0)
p=p->rlink;
else
return;
}
}
void save()
{ /*将关键字和非关键字的计数值P、Q存入指定文件中*/
返回参数:无;
功能:当command=1,读入用户指定的源文件,按字符依次搜索其中的标识符,每找到一个便调用count()子程序对P、Q计数,直至文件结束,若还需读文件,则继续调用其本身,否则调用save()子程序将P、Q存入指定文件后,然后返回主程序;
调用情况:由主程序调用;
(7)OBST()子程序
{ /*统计一C程序中的各关键字和非关键字的个数*/
int low=1,high=32,mid;
while(low<=high)
{mid=(low+high)/2;
if(strcmp(buffer1,key[mid])<0)
high=mid-1;
else if(strcmp(buffer1,key[mid])>0)
status=0;
break;
case 2: if(ch=='*') /*遇到第二个'*'字符,有可能是注释的结束,转状态3*/
status=3;
break;
case 3: if(ch=='/') /*合法注释的结束*/
status=0;
else
status=2; /*否则,刚才遇到的'*'字符无效,转回状态2*/
{printf("cannot open file");
if(command==1)
find1=0;
if(command==2)
find2=0;
return;
}
getchar(); /*吸收输入文件名时最后敲入的回车*/
ch=fgetc(fp);
while(ch!=EOF) /*按字符依次读文件,直至结束*/