Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2150580
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: Android平台

2016-04-06 15:09:30

1. 信息检索导论中的倒排索引
P7
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4. #include <stdlib.h>
  5. using namespace std;

  6. typedef struct node
  7. {
  8.     char *data;//结点的数据域,为一个字符串
  9.     int freq; //单词的出现的频率
  10.     int index; //一位代表一个index
  11.     struct node *next;//结点的指针域
  12. }linknode;//定义单链表结点结构

  13. linknode* initlink()
  14. {
  15.     //建立单链表
  16.     linknode *p;
  17.     p=(linknode *)malloc(sizeof(linknode));
  18.     //建立一个只含头结点的空链表,头指针为head
  19.     p->next=NULL;
  20.     return p;
  21. }

  22. void insertlink(linknode* head, char* str, int index)
  23. {
  24.     linknode *p;
  25.     p=head;//在建好的单链表中,以p为扫描指针,从头开始查找有无数据域与t相同的结点
  26.     while ((p->next)&&(strcmp(str,p->next->data)))
  27.         p=p->next;
  28.     if (p->next)//如果存在数据域与t相同的结点,则输出存在信息
  29.     {
  30.         printf("\nstring %s existed\r\n",str);
  31.         p->next->freq++;
  32.         p->next->index |= 1<<(index-1);
  33.     }
  34.     else{//若不存在数据域与t相同结点,则做以下操作
  35.         p->next=(linknode *)malloc(sizeof(linknode));
  36.         //在单链表表尾申请一个新结点
  37.         p=p->next;//p指针指向新的表尾结点
  38.         p->data = (char*)malloc(sizeof(char)*strlen(str));
  39.         strcpy(p->data,str);//将str的值复制到*p结点的数据域中
  40.         p->freq = 1;
  41.         p->index |= 1<<(index-1);
  42.         p->next=NULL;//将单链表的表尾结点的next指针置为空
  43.     }
  44. }

  45. void sort_strings(char *strs[],int count)
  46. {
  47.     char *p;
  48.     int i,j,k;
  49.     for(i=0;i<count;i++){
  50.         for(j=i+1; j<count; j++)
  51.         {
  52.             if(strcmp(strs[i],strs[j])>0)
  53.             {
  54.                 p=strs[i];
  55.                 strs[i]=strs[j];
  56.                 strs[j]=p;
  57.             }
  58.         }
  59.     }
  60. }
  61. void swap( linknode *s1, linknode *s2 ) //字符串交换
  62. {
  63.     linknode temp1,temp2;
  64.     temp1 = *s1;
  65.     temp1.next = s2->next;
  66.     temp2 = *s2;
  67.     temp2.next = s1->next;
  68.     *s1 = temp2;
  69.     *s2 = temp1;
  70. }

  71. void sort_link(linknode* head)
  72. {
  73.     linknode* p1, *p2;
  74.     p1 = head->next;
  75.     while(p1 != NULL)
  76.     {
  77.         p2 = p1->next;
  78.         while(p2 != NULL)
  79.         {
  80.             if(strcmp(p1->data, p2->data) > 0 )
  81.             {
  82.                 swap(p1, p2); //字符串交换
  83.             }
  84.             p2 = p2->next;
  85.         }
  86.         p1 = p1->next;
  87.     }
  88. }

  89. void printing(linknode* head){
  90.     //输出head单链表
  91.     linknode *p;
  92.     p=head->next;
  93.     while(p){
  94.         printf("%s,%d, %d\r\n",p->data, p->freq, p->index);//输出结点的数据——字符串
  95.         p=p->next;
  96.     }
  97. }//end of printing

  98. void deletenode(linknode* head,char *t){
  99.     //若head单链表中有数据为t的结点,删除之
  100.     linknode *p,*s;
  101.     p=head;
  102.     while ((p->next)&&(strcmp(p->next->data,t)))
  103.         //以p为扫描指针对head链表进行查找数据域值为*t结点,
  104.         //为了能方便删除操作,p指向待查结点的前趋
  105.         p=p->next;
  106.     if (p->next){//若查找到有,则做删除操作
  107.         s=p->next;
  108.         p->next=s->next;
  109.         free(s);
  110.         printf("\ndelete successful!");
  111.     }
  112.     else//若head链表中没有数据域的值为*t的结点,则输出删除失败的信息
  113.         printf("\ndelete failure!");
  114. }

  115. int upwords2low(char* str, int len)
  116. {
  117.     int i;
  118.     for(i=0;i<len;i++)
  119.         str[i]=tolower(str[i]);
  120. }

  121. char delete_char(char* str, char del)
  122. {
  123.     int i;
  124.     for (i=0; i<strlen(str); i++) {
  125.         if (str[i] == del) {
  126.             str[i] = ' ';
  127.         }
  128.     }
  129.     return del;
  130. }

  131. int process_string(char* str, int len)
  132. {
  133.     int words1_num;
  134.     //1. turn upercase to lowercase and then remove specail characters
  135.     upwords2low(str, len);
  136.     delete_char(str, ',');
  137.     delete_char(str, '.');
  138.     delete_char(str, ';');
  139.     delete_char(str, ':');
  140.     delete_char(str, '\'');
  141. }
  142. int get_words(char *sentence,char *words[])
  143. {
  144.     int i=0;
  145.     char *p;
  146.     p=strtok(sentence," ,.");
  147.     while(p!=NULL)
  148.     {
  149.         words[i]=p;
  150.         i++;
  151.         p=strtok(NULL," ,.");

  152.     }
  153.     return i;
  154. }

  155. int main ( int argc, char *argv[] )
  156. {
  157.     char str1[]= "I did enact Julius Caesar: I was killed i' the Capitol; Brutus killed me.";
  158.     char str2[]="So let it be with Caesar. The nobel Brutus hath told you Caesar was ambitions:";
  159.     int words1_num = 0;
  160.     int words2_num = 0;
  161.     char *words1[20];
  162.     char *words2[20];
  163.     int i;
  164.     //建立数据域为字符串类型,且结点无重复的单链表。对单链表做删除结点操作
  165.     linknode* head = initlink();//建立单链表
  166.     //1. process string
  167.     process_string(str1, strlen(str1));
  168.     process_string(str2, strlen(str2));
  169.     printf("process1: %s\n", str1);
  170.     printf("process2: %s\n", str2);
  171.     //2. splite words form article
  172.     words1_num = get_words(str1, words1);
  173.     words2_num = get_words(str2, words2);
  174.     printf("words1_num=%d\n",words1_num);
  175.     printf("words2_num=%d\n",words2_num);
  176.     //3. insert words to list
  177.     for(i=0; i<words1_num; i++)
  178.     {
  179.         insertlink(head, words1[i], 1);
  180.     }
  181.     for(i=0; i<words2_num; i++)
  182.     {
  183.         insertlink(head, words2[i], 2);
  184.     }
  185.     printing(head);//输出单链表
  186.     printf("\r\n");
  187.     //4. sort the list
  188.     sort_link(head);
  189.     printing(head);//输出单链表
  190.     printf("\r\n");

  191.     //5.
  192.     printf("output1:\r\n");
  193.     for(i=0; i<words1_num; i++)
  194.     {
  195.         printf("%s ",words1[i]);
  196.     }
  197.     printf("\r\n");
  198.     printf("output2: \r\n");
  199.     for(i=0; i<words2_num; i++)
  200.     {
  201.         printf("%s ",words2[i]);
  202.     }
  203.     printf("\r\n");
  204.     return 0;
  205. }
2. 输出结果
  1. ambitions,1, 2
  2. be,1, 2
  3. brutus,2, 3
  4. caesar,3, 3
  5. capitol,1, 1
  6. did,1, 1
  7. enact,1, 1
  8. hath,1, 2
  9. i,3, 1
  10. it,1, 2
  11. julius,1, 1
  12. killed,2, 1
  13. let,1, 2
  14. me,1, 1
  15. nobel,1, 2
  16. so,1, 2
  17. the,2, 3
  18. told,1, 2
  19. was,2, 3
  20. with,1, 2
  21. you,1, 2
3.思路
a. 处理字符串,把其中的 , 。! :等这样不属于单词的特殊字符去掉
b. 将字符串中的大写字母转为小写字母
c. 从字符串中分离出一个个单词
d. 把这一个个的单词插入到链表中,插入时有重复的单词时freq++

docID在数据结构中用index表示, index是一个32位数,其每一位代表一个docID,
例: did只在doc1中出现,则其index=1
例: it 只在doc1中出现,则其index=2
例如: brutus既在doc1也在doc2中出现index=3
这就是代码中:
p->index |= 1<<(index-1); 
则第三篇文章呢?
如abc只在doc3中出现,则index=4
如abc在doc3与doc2中出现,则index=6
以此类推
但是由于index是一个32位的数,所以最大只能表示32篇文章

阅读(1391) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~