熟悉键树(数字查找树)算法的大虾帮忙看看程序
程序大概是为用户输入的三个特征词建立键树,然后与读取的英文文章中的每个单词做比较,如相同则特征词计数器+1,鄙人实力有限,看了很长时间也改了几个地方,但运行结果总是有错,求大虾帮忙看看吧。程序很长,不过比较好看,毕竟我水平有限,写的也比较没有技术含量。 #include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define MAXSTRLEN 1000 //英文文章最大长度
#define MAXWORLEN 20 //英文文章单词最大长度
char AString[MAXSTRLEN]; //存储英文文章
char CString[MAXWORLEN]; //存储英文文章单词,键树算法专用
typedef enum {LEAF,BRANCH}NodeKind; //结点类型
typedef struct DLTNode{
char symbol; //关键字字符
char infoptr; //叶子标志位
NodeKind kind; //结点类型
struct DLTNode *next; //指向结点右侧兄弟
struct DLTNode *first; //指向结点子树
}DLTNode,*DLTree; //键树数据结构
int filewordskeytree,tree1,tree2,tree3; //文章总词数、三个特征词计数器
void ofile()
{
int i=0;
FILE *fp;
fp=fopen("d:\\a.txt","r");
if(fp==NULL)
{
printf("open file error");
exit(0);
}
while(!feof(fp))
{
AString[i]=fgetc(fp); //英文文章读取到数组
if(feof(fp))
break;
i++;
}
AString[i]='\0';
i=0;
while(AString[i]!='\0')
{
printf("%c",AString[i]); //打印文章
i++;
}
fclose(fp);
} //打开文件
void main()
{
char name[30],k1[20],k2[20],k3[20]; //定义三关键词数组
DLTree T,L,q,p,w;
int i=0,a=0,j=0,wsum=0;
ofile(); //打开文件
printf("\nPlease input writer's name:");
scanf("%s",name);
printf("\nPlease input the first keyword:");
scanf("%s",k1);
printf("\nPlease input the second keyword:");
scanf("%s",k2);
printf("\nPlease input the third keyword:");
scanf("%s",k3); //输入相关信息
T->symbol=' ';
T->next=NULL;
T->first=NULL; //键树根结点赋值
q=T;
while(k1[i]!='\0')
{
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->symbol=k1[i];
L->next=NULL;
L->first=NULL;
q->first=L;
q=L;
i++;
} //生成关键词1分支结点
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->infoptr='!';
L->kind=LEAF;
tree1=0;
L->next=NULL;
L->first=NULL; //生成关键词1叶子结点
q->first=L;
q=L;
i=0;
q=T;
while(k2[i]!='\0')
{
if(q->first->symbol==k2[i])
{
q=q->first;
i++;
} //查找有无相同字符结点
else if(q->first->symbol <k2[i]||q->first->infoptr=='!')
{
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->symbol=k2[i];
L->next=NULL;
L->first=NULL; //生成结点右兄弟分支结点
q->first->next=L;
q=L;
i++;
while(k2[i]!='\0')
{
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->symbol=k2[i];
L->next=NULL;
L->first=NULL;
q->first=L;
q=L;
i++;
} //生成关键词2分支结点
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->infoptr='@';
L->kind=LEAF;
tree2=0;
L->next=NULL;
L->first=NULL; //生成关键词2叶子结点
q->first=L;
q=L;
i=0;
break;
}
else if(q->first->symbol>k2[i])
{
p=q->first;
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->symbol=k2[i];
L->next=NULL;
L->first=NULL; //生成结点左兄弟分支结点
q->first=L;
L->next=p;
q=L;
i++;
while(k2[i]!='\0')
{
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->symbol=k2[i];
L->next=NULL;
L->first=NULL;
q->first=L;
q=L;
i++;
} //生成关键词2分支结点
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->infoptr='@';
L->kind=LEAF;
tree2=0;
L->next=NULL;
L->first=NULL; //生成关键词2叶子结点
q->first=L;
q=L;
i=0;
break;
}
} //生成关键词2树
while(k3[i]!='\0')
{
q=T->first;
p=T->first;
w=T;
while(q)
{
if(q->symbol==k3[i])
{
q=q->first;
p=p->first;
w=w->first;
i++;
}
else
q=q->next;
} //查找有无相同字符结点
if(q->symbol <k3[i])
{
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->symbol=k3[i];
L->next=NULL;
L->first=NULL; //生成结点右兄弟分支结点
q->next=L;
q=L;
i++;
while(k3[i]!='\0')
{
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->symbol=k3[i];
L->next=NULL;
L->first=NULL;
q->first=L;
q=L;
i++;
} //生成关键词3分支结点
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->infoptr='#';
L->kind=LEAF;
tree3=0;
L->next=NULL;
L->first=NULL; //生成关键词3叶子结点
q->first=L;
q=L;
i=0;
break;
} //在右兄弟为空结点的右侧建立新结点
else if(p->symbol>k3[i])
{
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->symbol=k3[i];
L->next=p;
w->first=L;
L->first=NULL; //生成结点左兄弟分支结点
p=L;
i++;
while(k3[i]!='\0')
{
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->symbol=k3[i];
L->next=NULL;
L->first=NULL;
p->first=L;
p=L;
i++;
} //生成关键词3分支结点
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->infoptr='#';
L->kind=LEAF;
tree3=0;
L->next=NULL;
L->first=NULL; //生成关键词3叶子结点
p->first=L;
p=L;
i=0;
break;
} //在第一个孩子结点左侧建立新结点
else if(p->symbol <k3[i]&&q->symbol>k3[i])
{
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->symbol=k3[i];
L->next=q;
L->first=NULL;
p->next=L; //两结点间生成新结点
p=L;
i++;
while(k3[i]!='\0')
{
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->symbol=k3[i];
L->next=NULL;
L->first=NULL;
p->first=L;
p=L;
i++;
} //生成关键词3分支结点
L=(DLTree*)malloc(1*sizeof(DLTree));
if(!L)
{
printf("malloc DLTree error");
exit(0);
}
L->infoptr='#';
L->kind=LEAF;
tree3=0;
L->next=NULL;
L->first=NULL; //生成关键词3叶子结点
p->first=L;
p=L;
i=0;
break;
} //在两结点间建立新结点
} //生成关键词3树
p=NULL;
q=NULL;
w=NULL;
while(AString[a]!='\0')
{
while(1)
{
if(AString[a]=='\0'||AString[a]==' '||AString[a]=='\n'||AString[a]==','||AString[a]=='.')
break;
CString[j]=AString[a];
a++;j++;
} //读取英文单词到数组
CString[j]='\0';
j=0;
while(CString[j]!='\0')
j++; //计算单词长度
p=T->first;
i=0;
while(p&&i <j)
{
while(p&&p->symbol <CString[i])
p=p->next; //兄弟中查找
if(p&&p->symbol==CString[i])
{
p=p->first;
++i;
} //找到后继续查找子树
else
p=NULL; //没有找到
}
if(p&&p->kind==LEAF)
{
if(p->infoptr=='!')
tree1++;
if(p->infoptr=='@')
tree2++;
if(p->infoptr=='#')
tree3++;
}
wsum++; //文章总词数计数
j=0;
if(AString[a]=='\0') break;
while(1)
{
if(AString[a]==' '||AString[a]=='\n'||AString[a]==','||AString[a]=='.')
a++;
else
break;
} //跳过非单词字符
} //键树查找算法
filewordskeytree=wsum; //传递总词数信息
printf("\n%d,%d,%d,%d",filewordskeytree,tree1,tree2,tree3);
}