用c语言实现一个简单的输入法联想功能

手机输入法的联想功能十分常见,通过c语言同样可以实现一个简单的输入法联想功能。

首先读取一个文字量比较大的文件,通过线性表对汉字间的关系进行加权存储,再记录到总体的单链表里,并进行排序处理,在输入时将权值大的四个选项作为备选汉字,方便输入,并在最后可以导出输入的内容。

我在这里设置了两个版本,版本0是精简推荐,考虑到成语为四字自成一体,版本1增加成语推荐,成语进行联想推荐,方便在输入时的多元化。

我在这里读取一个名为"b.txt"的文本文件,用来计算权值,内容可自行添加,但是必须是汉语或汉语字符,可以有换行,"CY.txt"储存成语,在其中存上成语,注意不能有空格或其他字符

注意,文本文件默认编码是UTF-8,而c语言读取时是按ANSI码来读,因此需要事先把文件另存为ANSI编码格式

读取文件时,由于汉字是两个字节组成,文件要按块读写

fseek(fp, 0, SEEK_END);
int size = ftell(fp);
fseek(fp, 0, SEEK_SET);
if(size > 0){//printf("size: %d\n",size);hanzi=(char *)malloc((size+1)*sizeof(char));}int ret = fread(hanzi,2,size/2, fp);int size1=size;for(int i=0;i<size1;i++){if(hanzi[i]=='\n')             //去掉回车{for(int j=i;j<size1;j++){hanzi[j]=hanzi[j+1];size1=size1-1;}}}

在之后的代码中记录一个汉字,和这个汉字的下一个汉字,把下一个汉字记录在以上一汉字为内容的线性表中,并将权值设置为1,如果之后两个字又以同样的顺序出现,下一个汉字的权值加1,通过这种方法表示这个组合方式出现的频率高低。

成语的思路和上述方法类似,只是需要同时存三个汉字在以第一个汉字为内容的链表中。

输入’66’变换成语

之后设置输入函数,检测输入内容,汉字需要两个字节存储,因此我们用一个字符型数组nr[2]来存输入的汉字,将输入的两个字符型变量和储存好的并已进行权值排序的内容进行比较输出权值较大的四个汉字作为选项

这里我用冒泡排序法实现权值排序

void Sort(sqlist &L,int num)
{                                    //权值排序int i,j;char n1,n2;int a1;for(i=0;i<num-1;i++){for(j=0;j<num-i-1;j++){if(L.elem[j].a<L.elem[j+1].a){a1=L.elem[j].a;L.elem[j].a=L.elem[j+1].a;L.elem[j+1].a=a1;n1=L.elem[j].b[0];L.elem[j].b[0]=L.elem[j+1].b[0];L.elem[j+1].b[0]=n1;n2=L.elem[j].b[1];L.elem[j].b[1]=L.elem[j+1].b[1];L.elem[j+1].b[1]=n2;}}}
}

通过switch语句等判断字符,对输入的各种字符进行分类处理,当用户选择联想汉字时,变换光标位置,将推荐内容输出

输入相应的数字

效果

最后还可以将输入的内容记录下来,存放到文件中,便于数据的存储

void Import_file()
{FILE*fp;fp=fopen("已输入的信息.txt","w");fflush(stdin);fwrite(xx,2,shu/2,fp);fclose(fp);
}

同时也可以设计一些类似与输入框之类的东西美化一下界面还可设计开始/结束界面增加体验感

以下是完整的代码,测试时运行没有太大问题

要注意"b.txt"和"CY.txt"是已经存在的文档,按照上述的规则,自己写或者复制一篇文字放在"b.txt"中,(不能有空格或英文字符)"CY.txt"注意存的是四字成语汉字量必须是4的倍数(不能有空格或英文字符)

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#define N 40
#define N1 10
#define N2 40
char a;
typedef int mytype;
typedef struct Node{mytype a;                   //存储权值char b[2];                  //汉字内容
}Node;
typedef struct sqlist{Node *elem;int length;int listsize;
}sqlist;
typedef struct Node1{sqlist address;              //将每个汉字的权值线性表存储在链表中 char d[2];int memory;                   //记录该线性表的数据量 struct Node1 *next1;
}Node1,*linklist;
typedef struct cylist{ char cy[2];char houzhui[6*N2];int cysum;struct cylist *next;
}*idm;
char cysuggest[8]={0};            //成语选项
idm cy;
linklist name;                   //总链表
linklist next1;
sqlist next;
sqlist L1;
char xx[166];                     //存储输入内容
int shu=0;
char suggest[8];                  //存储推荐选项
void Initidiom(idm &cy)
{                                   //初始化成语链表 cy=(idm)malloc(sizeof(cylist));cy->next=NULL;
}
void Creatidiom(idm &cy,char n1,char n2)
{                                    //增加一个新字的成语,创建新的成语节点 idm cy1;cy1=(idm)malloc(sizeof(cylist));cy1->cysum=1;cy1->cy[0]=n1;cy1->cy[1]=n2;cy1->next=cy->next;cy->next=cy1;
}
void Addidiom(idm &cy,char n1,char n2,char n3,char n4,char n5,char n6,char n7,char n8)
{                                       //增加成语 idm c=cy->next;int flag=0;while(c){if((c->cy[0]==n1)&&(c->cy[1]==n2)){c->houzhui[6*(c->cysum-1)]=n3;c->houzhui[6*(c->cysum-1)+1]=n4;c->houzhui[6*(c->cysum-1)+2]=n5;c->houzhui[6*(c->cysum-1)+3]=n6;c->houzhui[6*(c->cysum-1)+4]=n7;c->houzhui[6*(c->cysum-1)+5]=n8;flag=1;c->cysum=c->cysum+1;}c=c->next;}if(flag==0){Creatidiom(cy,n1,n2);Addidiom(cy,n1,n2,n3,n4,n5,n6,n7,n8);}
}
void Read_cy()
{                                        //读取成语文件 FILE* fp = NULL;fp = fopen("CY.txt", "r");if (fp == NULL){perror("my_fread fopen");return;}char *cynr;fseek(fp, 0, SEEK_END);int size = ftell(fp);fseek(fp, 0, SEEK_SET);if(size > 0){//printf("size: %d\n",size);cynr=(char *)malloc((size+1)*sizeof(char));}int ret = fread(cynr,2,size/2, fp);int size1=size;for(int i=0;i<size1;i++){if(cynr[i]=='\n'){for(int j=i;j<size1;j++){cynr[j]=cynr[j+1];size1=size1-1;}}}for(int i=0;i<size1;i=i+8){                                  //每8个字节( 四个字)进行一次增加成语 Addidiom(cy,cynr[i],cynr[i+1],cynr[i+2],cynr[i+3],cynr[i+4],cynr[i+5],cynr[i+6],cynr[i+7]);}
}
void Search_cy(idm cy,char n1,char n2,int k)
{                                       //查找成语内容 int flag=0;idm c=cy->next;while(c){if((c->cy[0]==n1)&&(c->cy[1]==n2)){cysuggest[0]=n1;cysuggest[1]=n2;flag=1;                             //循环变换选项 if(k<=(c->cysum)-1)for(int i=2;i<8;i++)cysuggest[i]=c->houzhui[6*(k-1)+i-2];if(k>(c->cysum)-1){if(!(k%((c->cysum)-1)))k=(c->cysum)-1;else{k=k%((c->cysum)-1);}for(int i=2;i<8;i++)cysuggest[i]=c->houzhui[6*(k-1)+i-2];}}c=c->next;}if(flag==0){                           //查找不到时推荐选项输出空 for(int i=0;i<8;i=i+2){cysuggest[i]=char(-65);cysuggest[i+1]=char(-43);}}
}
void Creatlist(linklist &L)
{                                              //建立新链表L=(linklist)malloc(sizeof(Node1));L->d[0]='1';L->d[1]='2';L->next1=NULL;
}
void Newlist(linklist &L,char n1,char n2,sqlist &a)
{                                                // 将线性表存储在链表中linklist s;s=(linklist)malloc(sizeof(Node1));s->address=a;s->memory=a.length;s->d[0]=n1;s->d[1]=n2;s->next1=L->next1;L->next1=s;
}
void Creat_LINEAR_table(sqlist &L,char n1,char n2)
{                                                     //创建线性表L.elem = (Node *)malloc(N*sizeof(Node));L.elem[0].b[0]=n1;L.elem[0].b[1]=n2;L.elem[0].a=1;L.length=1;L.listsize=N;Newlist(name,n1,n2,L);
}
void Addelem(sqlist &L,char n1,char n2,linklist &c)
{                                                        //增加新的汉字元素L.length=c->memory;L.elem[L.length].b[0]=n1;L.elem[L.length].b[1]=n2;L.elem[L.length].a=1;L.length++;c->memory=L.length;if(L.length==L.listsize){L.elem = (Node *)realloc(L.elem,N1*sizeof(Node));L.listsize=L.listsize+N1;}
}
void Addweight(sqlist &L,char n1,char n2,linklist &c)
{                                           //增加权值int i=0;int flag=0;while(i<c->memory){if((L.elem[i].b[0]==n1)&&(L.elem[i].b[1]==n2)){L.elem[i].a++;flag=1;}i++;}if(flag==0){Addelem(L,n1,n2,next1);}
}
void Addname(linklist &L,char n1,char n2)
{                                                   //返回需要的线性表linklist c;c=L->next1;int flag=0;while(c){if((c->d[0]==n1)&&(c->d[1]==n2)){flag=1;next=c->address;next1=c;}c=c->next1;}if(flag==0){sqlist L1;Creat_LINEAR_table(L1,n1,n2);Addname(L,n1,n2);}
}
/*
void printList(sqlist L,linklist1 c)
{int i;for(i=0;i<c->memy;i++){if(i<c->memy-1){printf("%c%c ",L.elem[i].b[0],L.elem[i].b[1]);printf("%d->",L.elem[i].a);}else{printf("%c%c ",L.elem[i].b[0],L.elem[i].b[1]);printf("%d",L.elem[i].a);}}printf("\n");
}*/
void Read_file()
{                                            //读取文件得到权值FILE* fp = NULL;fp = fopen("b.txt", "r");if (fp == NULL){perror("my_fread fopen");return;}char *hanzi;                          //汉字由两字节构成,按块读fseek(fp, 0, SEEK_END);int size = ftell(fp);fseek(fp, 0, SEEK_SET);if(size > 0){//printf("size: %d\n",size);hanzi=(char *)malloc((size+1)*sizeof(char));}int ret = fread(hanzi,2,size/2, fp);int size1=size;for(int i=0;i<size1;i++){if(hanzi[i]=='\n')             //去掉回车{for(int j=i;j<size1;j++){hanzi[j]=hanzi[j+1];size1=size1-1;}}}//hanzi[size]='\0';//printf("%s\n",hanzi);for(int i=0;i<size;i=i+2){Addname(name,hanzi[i],hanzi[i+1]);if(i<size-2){Addweight(next,hanzi[i+2],hanzi[i+3],next1);          //增加下一个汉字相比前一个汉字的权值}}//printf("ret = %d\n", ret);//sqlist q=name->next1->next1->next1->next1->address;//printList(q,name->next1->next1->next1->next1->next1);free(hanzi);if (fp != NULL){fclose(fp);fp = NULL;}
}
void Sort(sqlist &L,int num)
{                                    //权值排序int i,j;char n1,n2;int a1;for(i=0;i<num-1;i++){for(j=0;j<num-i-1;j++){if(L.elem[j].a<L.elem[j+1].a){a1=L.elem[j].a;L.elem[j].a=L.elem[j+1].a;L.elem[j+1].a=a1;n1=L.elem[j].b[0];L.elem[j].b[0]=L.elem[j+1].b[0];L.elem[j+1].b[0]=n1;n2=L.elem[j].b[1];L.elem[j].b[1]=L.elem[j+1].b[1];L.elem[j+1].b[1]=n2;}}}
}
void Set_option(char n1,char n2)
{                                       //创建选择linklist r=name->next1;int i,j,k=0,flag=0;int jilu=0;while(r){if((r->d[0]==n1)&&(r->d[1])==n2){flag=1;Sort(r->address,r->memory);for(i=0;i<8;k++){suggest[i]=r->address.elem[k].b[0];suggest[i+1]=r->address.elem[k].b[1];i=i+2;if((r->memory)<4){if(2*i==r->memory){break;}}}}r=r->next1;}if(flag==0)                                   //没有记录过选项是空{for(j=0;j<8;j=j+2){suggest[j]=char(-65);suggest[j+1]=char(-43);}}
}
void Change(int g,int p)
{                                          //变换光标位置HANDLE hOut;COORD pos={0,0};pos.X=g;pos.Y=p;hOut=GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleCursorPosition(hOut,pos);
}
void Association()
{                                         //输出联想选项int i,j=11;if(a=='1')                  //1界面 {for(i=0;i<8;i=i+2){if(i==6){Change(j,12);printf("%c%c",suggest[i],suggest[i+1]);j=j+16;}else{Change(j,12);printf("%c%c           ",suggest[i],suggest[i+1]);j=j+16;}}Change(75,12);for(i=0;i<8;i++)printf("%c",cysuggest[i]);}if(a=='0')                    //0界面 {for(i=0;i<8;i=i+2){if(i==6){Change(j,12);printf("%c%c",suggest[i],suggest[i+1]);}else{Change(j,12);printf("%c%c               ",suggest[i],suggest[i+1]);j=j+21;}}}
}
void Record(char n1,char n2)
{xx[shu]=n1;xx[shu+1]=n2;shu=shu+2;
}
void Import_file()
{FILE*fp;fp=fopen("已输入的信息.txt","w");fflush(stdin);fwrite(xx,2,shu/2,fp);fclose(fp);
}
int Set_end()
{int i=1;char ze;Change(10,21);printf("输入1  导出文件\n");Change(10,22);printf("输入2  结束并退出\n");Change(10,23);while(i){ze=getch();switch(ze){case'1':system("已输入的信息.txt");return 0;case'2':return 0;default:Change(10,23);printf("[%d]重新键入信息\n",i);Change(10,24);}i++;}
}
void Input()
{                                  //输入汉字char nr[2]={0};int i=1,g=10,p=8,flag=0,gai=1;while(i){fflush(stdin);if(i==42)                      //设置最大输入数量{p++;g=10;}if(i==83){Change(70,14);printf("已超过输入最大限制!!");break;}if(flag==0)Change(g,p);                  //判断是否退格if(flag==1){Change(g-2,p);flag=0;g=g-2;}nr[0]=getchar();if(nr[0]=='n')                      //n退出程序 {Change(10,20);printf("已退出程序\n");break;}nr[1]=getchar();if(nr[0]=='\n')continue;         //错误输入调整 if(nr[1]=='\n'){Change(g+1,p);xx[shu]=nr[0];g++;shu++;continue;}Record(nr[0],nr[1]);if((nr[0]!='5')&&(nr[0]!='6')){gai=1;Search_cy(cy,nr[0],nr[1],gai);}if(i==1){Set_option(nr[0],nr[1]);Association();g=g+2;}if(i>1){      if(nr[0]=='t'){nr[1]='t';flag=1;Change(g-2,p);printf("    ");xx[shu-4]=xx[shu-3]=xx[shu-2]=xx[shu-1]=' ';shu=shu-4;i--;continue;}if((nr[0]=='1')||(nr[0]=='2')||(nr[0]=='3')||(nr[0]=='4')||(nr[0]=='5')||(nr[0]=='6')){                                                //联想选项输出switch(nr[0]){case '1':Change(g,p);printf("%c%c",suggest[0],suggest[1]);xx[shu-2]=suggest[0];xx[shu-1]=suggest[1];Set_option(suggest[0],suggest[1]);Association();break;case '2':Change(g,p);printf("%c%c",suggest[2],suggest[3]);xx[shu-2]=suggest[2];xx[shu-1]=suggest[3];Set_option(suggest[2],suggest[3]);Association();break;case '3':Change(g,p);printf("%c%c",suggest[4],suggest[5]);xx[shu-2]=suggest[4];xx[shu-1]=suggest[5];Set_option(suggest[4],suggest[5]);Association();break;case '4':Change(g,p);printf("%c%c",suggest[6],suggest[7]);xx[shu-2]=suggest[6];xx[shu-1]=suggest[7];Set_option(suggest[6],suggest[7]);Association();break;case '5':if(a=='1'){Change(g,p);printf("%c%c%c%c%c%c",cysuggest[2],cysuggest[3],cysuggest[4],cysuggest[5],cysuggest[6],cysuggest[7]);xx[shu-2]=cysuggest[2];xx[shu-1]=cysuggest[3];xx[shu]=cysuggest[4];xx[shu+1]=cysuggest[5];xx[shu+2]=cysuggest[6];xx[shu+3]=cysuggest[7];shu=shu+4;g=g+4;i=i+2; }break;case '6':if(a=='1'){Change(g,p);printf("  ");Change(g,p);g=g-2;gai++;Search_cy(cy,cysuggest[0],cysuggest[1],gai);Association();xx[shu-2]=xx[shu-1]='0';shu=shu-2;}break;       }}else{Set_option(nr[0],nr[1]);Association(); }g=g+2;}i++;}//printf("%s",nr);
}
void Color()
{system("color f0");
}
void Set_interface()
{                                           //美化界面int i,j=1;Change(46,12);printf("欢迎来到汉字输入联想系统");Change(90,25);printf("designed by huo yuanhao");Change(0,25);Change(46,14);printf("输入版本(0/1):");while(j){Change(61,14);a=getch();if(a=='0'||a=='1')break;else{Change(46,15);printf("[%d]输入错误,重新输入",j);}j++;}system("cls");Change(45,4);printf("汉字输入联想"); Change(8,14);printf("<1>建议输入的数据是汉字或中文字符,否则无联想");Change(8,15);if(a=='1')printf("<2>退格输入t,退出程序输入n,输入66可变换成语推荐");if(a=='0')printf("<2>退格输入tt,退出程序输入n");Change(8,16);printf("<3>每次只可输入一个汉字,并需要按回车键"); Change(8,17);printf("<4>如需要联想到的汉字则输入对应的数字");Change(8,12);if(a=='1'){for(i=1;i<=5;i++){if(i==5)printf("%d%d*",i,i);else{printf("%d%d.             ",i,i);}} }if(a=='0'){for(i=1;i<=4;i++){printf("%d%d.                  ",i,i);} }for(i=6;i<96;i=i+2){Change(i,6);printf("■");Change(i,26);printf("■");}for(i=7;i<26;i++){Change(6,i);printf("■");Change(94,i);printf("■");}for(i=8;i<95;i=i+2){Change(i,18);printf("■");}for(i=8;i<=93;i++){Change(i,11);printf("*");Change(i,13);printf("*");}
}
void End()
{system("cls");Change(46,12);printf("********************\n");Change(50,13);printf("欢迎下次使用\n");Change(46,14);printf("********************\n\n\n\n\n\n\n\n\n\n\n\n");
}
int main()
{Color();Initidiom(cy);Read_cy(); Set_interface();Creatlist(name);Read_file();Input();Import_file();Set_end();End();return 0;
}

用c语言实现一个简单的输入法联想功能相关推荐

  1. 使用html 语言建立一个简单的网页,如何用记事本建立简单的网页(1).doc

    第九章 网页制作 实验一 用记事本建立简单的HTML文件 [实验目的] 学会用HTML语言建立一个简单的网页. [实验内容] 建立一个网页,布局自定,包括自我介绍.图片.自己的电子信箱地址等,要求在标 ...

  2. 用C语言实现一个简单的一元线性回归算法

    今天我们用C语言实现一个简单的线性回归算法:在代码前面我们在回顾一下线性回归. 线性回归是回归问题中的一种,线性回归假设目标值与特征是线性相关的,即满足一个多元一次方程式.通过构建损失函数,来求解损失 ...

  3. c语言编写一个简单的答题系统

    利用c语言编写一个简单的答题系统. 思路是先设计好题目和答案,再输入自己的答案,利用输入的答案与正确答案对比,从而得出你回答的对错. (一)捆绑题目和答案 我们可以利用结构体对一个题目捆绑上一个答案. ...

  4. c语言写一个简单的小游戏-推箱子

    在学习C语言之后,写了一个简单的小游戏来锻炼自己的代码以及C语言知识的掌握能力. 推箱子作为手机上最常见的简单游戏,其代码也相对简单,想法也比较简单,下面为其代码和运行图. /************ ...

  5. 用C语言实现一个简单的计算器代码

    #include <stdio.h> #include <math.h> #include <stdlib.h> //预处理指令 int main(void) {d ...

  6. C语言编写一个简单的扫雷

    C语言编写一个简单的扫雷 # include <stdio.h> # include <stdlib.h> # include <math.h> # include ...

  7. 一个简单的c 游戏编程语言,编程达人 c语言写一个简单的小游戏-推箱子

    在学习C语言之后,写了一个简单的小游戏来锻炼自己的代码以及C语言知识的掌握能力. 推箱子作为手机上最常见的简单游戏,其代码也相对简单,想法也比较简单,下面为其代码和运行图. /************ ...

  8. 如何用C语言写一个web服务器的基础功能

    我们都知道,学一门语言,只是单独看了就不写的话是很容易出现眼高手低的,所以,今天摩杜云要给大家分享的内容,就是如何用C语言写一个web服务器的基础功能,希望大家看完有所收获. 服务器架构 目标架构 以 ...

  9. 基于PHP实现一个简单的在线聊天功能(轮询ajax )

    基于PHP实现一个简单的在线聊天功能(轮询ajax ) 一.总结 1.用的轮询ajax 二.基于PHP实现一个简单的在线聊天功能 一直很想试着做一做这个有意思的功能,感觉复杂的不是数据交互和表结构,麻 ...

最新文章

  1. 正确使用硬盘的方法与维护
  2. 计算机二级考试办公室高级应用考点,2018年计算机二级Office高级应用考点:PowerPoint...
  3. 査勇:华为云在视频AI转码领域的技术实践
  4. Java基础之正则表达式
  5. 微软热门开源项目及代码库地址
  6. linux setuid函数_setuid函数解析
  7. java loadjs_Javarscript中模块(module)、加载(load)与捆绑(bundle)详解
  8. 阿里云服务器是如何计费的?有哪些计费方式
  9. 【bzoj 1102】[POI2007]山峰和山谷Grz(BFS)
  10. C语言题库 part.1
  11. web开发实现火星坐标、百度坐标、WGS84坐标互相转换
  12. OneNote网页版链接用桌面应用打开报错的解决
  13. Python实现Excel表格数据去重
  14. 如何使用Java计算闰年?
  15. 干货 | 七年留美经验,帮你省钱自助游美国
  16. 一连上网就弹出广告窗,记录删除一些顽固文件
  17. 黑色沙漠首发五职业PVP强度排行
  18. .Net Core 使用UDP协议实现即时通讯
  19. 接吻的十大忌讳及对策
  20. Linux进程KILL--Quit,INT,HUP,QUIT,和TERM、PIPE的解释

热门文章

  1. 查询快递单号需要怎么操作
  2. apollo系列之apollo2 mcu开发(基础篇)之1.3-解析编译生成的IAR中的map文件
  3. 10次机会 js 猜数_JS猜数字游戏实例讲解
  4. 三相全控tc787触发电路_教你快速看懂电子电路图
  5. java手机音乐_[JavaME]手机同时播放两个音乐 探讨一
  6. cocos2dx项目,安卓手机音效播放中断
  7. ios 关于字体样式设置
  8. windows操作系统使用
  9. 庫存管理 - 倒扣法
  10. 模拟 模拟/ 数字转换(ADC)