distance.c
2016-03-01 22:50
239 查看
#include "stdio.h" #include "string.h" #include "math.h" #include "malloc.h" const long long Max_size = 2000;//输入字符串的最大长度,可以由单个词条和多个词条组成 const long long N = 40;//输出与某个单词最接近的N个词 const long long Max_w = 50;//单个词条的最大长度 int main(int argc,char **argv) { FILE *f;//读取的文件指针 char stemp[Max_size];//中间变量 char *bestw ;//存储与某个词最接近N个词条 char ch; float *M;//存储所有词条的距离相关信息 char *vocab;//存储所有词条的字符信息 /* *file_name[Max_size];存放要读取内容的文件名; *st[100][Max_size];//二维数组,中间变量 *dist:距离;len:长度;bestd :存储与某个词最接近的N个词的距离 *vec[Max_size]:存储Max_size个词与某个指定词的距离 *words:词条的总数目;size:词条表示的维数; *key[100],存储某个词条在总词条中的位置下标 */ char file_name[Max_size],st[100][Max_size]; float dist,len,bestd ,vec[Max_size]; long long words,size,i,j,k,l,num,key[100]; if(argc<2)//打印程序所在路径 { printf("Usage:./distance<FILE>\nwhere FILE contains word projections in the BINARY FORMAIN\n"); return 0; } strcpy(file_name,argv[1]);//argv[1]中存放的文件名赋给file_name f = fopen(file_name,"rb"); if(f == NULL)//文件打开失败 { printf("Input file not found\n"); return -1; } fscanf(f,"lld",&words);//输入总词条数组 fscanf(f,"lld",&size);//输入用来表示每个词条的维数大小 vocab = (char *)malloc((long long)words * Max_w *sizeof(char)); //根据实际的维数分配存储块大小 for(i = 0; i < N; i++)bestw[i] = (char *)malloc(Max_size * sizeof(char)); M = (float *)malloc((long long)words * (long long)size *sizeof(float)); if(M==NULL)//不能分配所需要大小的内存 { printf("Cannot allocate memory:%lld MB %lld %lld\n",(long long )words *size*sizeof(float)/1024/1024,words,size); return -1; } for(j = 0; j < words; j++)//words个词条每个词条坐标进行归一化 { i = 0; while(true) { vocab[j*Max_w + i] = fgetc(f); if(feof(f) || vocab[j * Max_w + i] == ' ')break; if((i <Max_w)&&(vocab[j * Max_w + i] !='\n'))i++; } vocab[j * Max_w + i] = 0; for(i = 0;i < size ; i++ ) fread(&M[j * size + i],sizeof(float),1,f); len = 0; for(i = 0 ; i < size ; i++ ) len += M[j * size + i]*M[j * size + i]; len = sqrt(len); for(i = 0 ; i < size ; i++ ) M[j * size + i] = M[j * size + i] / len; //坐标归一化 } fclose(f); while(true) { for(i = 0 ; i < N ; i++ ) { bestd[i] = 0;//N个词条距离初始为0 bestw[i][0] = 0 ;//初始化 } printf("Entor word or sentence(EXIT to break:)"); i = 0; while(true)//键盘读入单个词条或多个词条 ;当字符数组超过Max_size -1 或者遇到回车符结束 { stemp[i] = fgetc(stdin); if((stemp[i] == '\n')||(i >=Max_size -1)) { stemp[i] = 0; break; } } if(!strcmp(stemp,"EXIT"))break;//如果输入的是"EXIT",则退出 num = 0 ;//用来统计键盘输入词条的数目 j = 0; k = 0; while(true) { st[num][j++] = stemp[k++]; st[num][j] = 0; if(stemp[k] ==0)break;//读完结束 if(stemp[k++] == ' ')//遇到空格 词条数目+1 { num++;//词条数目+1 j = 0; } } num++;//词条的总数目 //找出每个词条 最接近的N个词条 for(i = 0 ; i < num ; i++) { for(j = 0 ; j < words ;j++)if(!strcmp(&vocab[j * Max_w],st[j]))break;//在总词条中找到这个词条,获得这个词条在总词条中的位置 if(j == words) j = -1;//这个词条不存在 key[i] = j; printf("\nWord:%s Position in vocabulary: %lld\n",st[i],key[i]); if(j == -1)//这个词条不在这个词汇表中 { printf("Out of dictionary word!\n"); break;//终止循环 } } if(j==-1)continue;//继续执行 printf("\n Word Cosine distance\n"); printf("------------------------------------------------------------------------\n"); for(i = 0 ; i < size ; i++ ) vec[i] = 0;//距离初始化为0 for(j = 0 ; j < num ; j++ ) //遍历每个词,如果输入多个词向量vec[i]是各个词向量的累加和 { if(key[j] == -1)continue; for(i = 0 ; i < size ; i++ ) vec[i] += M[i + key[j]*size]; } len = 0; for(i = 0 ; i< size ; i++) len +=vec[i] * vec[i]; len = sqrt(len); for(i = 0; i < size ; i++) vec[i] = vec[i] / len;//将vec归一化,当只输入一个词时,不起作用 for(i = 0 ; i < N ; i++) { bestd[i] = -1; bestw[i][0] = 0; } //由于查询词和词汇表都做了归一化,所以余弦相似度等价于向量的内积,内机越大越相似 for(k = 0 ; k < words ; k++)//遍历词汇表 { i = 0; for(j = 0 ; j < num ; j++)//i的作用;如果遍历词和查询词相同,则跳过此词 { if(key[j] == k) i =1; } if(i == 1) continue; dist = 0; for(i = 0 ; i < N ; i++ ) { dist += vec[i] * M[k * size + i] ; } for(i = 0 ; i < N ; i++ ) { if(dist > bestd[i]) { for(j = N-1 ; j > i ; j--) { bestd[j] = bestd[j - 1 ]; strcpy(bestw[j],bestw[j-1]); } bestd[j] = dist; strcpy(bestw[i] , &vocab[k * Max_size]); break; } } } for(i = 0 ; i < N ; i++ )printf("%50s\t\t%f\n",bestw[i],bestd[i]); } return 0; }
相关文章推荐
- bzoj 1070: [SCOI2007]修车
- 正则表达式
- 6. 策略模式
- Android中Log日志的使用
- CSS-微信开放UI样式
- 6.2.3字符串String
- IOS 调用苹果地图
- iOS推送机制
- iOS开发设计模式之代理
- iOS----ARC(自动内存管理)
- final 关键字
- cocos2d-x之xml文件读取初试
- 解决Sublime Text 2中文显示乱码问题
- windows下配置环境java环境变量
- UVA 437 DAG最长路
- 简单的三种排序
- iCloud服务与应用
- bootstrap双日期选择插件
- Nginx负载均衡配置
- linux Hadoop 探索-hadoop单机模式