HOJ 2551 Zoogle 题解

题目大意:

     有标签式的数据描述,每组数据由<case> </case>标签隔开。

     每组数据中有若干个<page></page>隔开的页面描述,每个page中<url> </url>之间是这个page的url地址,<text></text>之间是正文,保证正文每个单词用空格隔开,没有标点,每个正文最多512个词,每个page中还有<link></link>标记的链接描述,<link></link>之间可能出现别的页面的url,在别的页面中外部链接中出现的次数为页面的权值。

     请求由<query></query>标记,最多有4096个,请求就是可能在page正文中出现的单词,对于每个请求按权值排序列出在正文中出现过这个单词的page的url。

解题思路:

     先囧一下,因为在样例输入里面第一个page的正文里面写着“Maybe you can use inverted index to speed up the process”,于是搜索了一下这个inverted index,也就是倒排索引,简单概括就是按照要检索的内容将地址储存下来,具体到这个题目来说把正文当做关键字,储存url,这个用map就非常合适,数据结构是map<string,set<string> >,第二元素是url组成的集合。

     想到这里思路就很明显了,对于每个query,直接查找这个单词所在的url,按照权值排序输出就可以了。

     STL中用到了map、set。

 

下面附上代码

#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <cstring>
#include <string>
#include <cstdio>

using namespace std;

struct URL
{
    char s[2000];
    int w;
    friend bool operator< (const URL &a, const URL &b)
    {
        return a.w>b.w || (a.w == b.w && strcmp(a.s,b.s) == -1);
    }
}urls[2000],turl;

int main()
{
    int T = 0;
    char s[2000],url[2000];
    while (scanf("%s", s) != EOF)
    {
        map<string,set<string> > word_index;
        map<string,int> url_value;

        if (T++) printf("\n");
        while(scanf("%s",s) && strcmp(s,"<query>") != 0)
        {
            scanf("%*s %s %*s %*s",url);
            while(scanf("%s",s) && strcmp(s,"</text>") != 0)
                word_index[s].insert(url);
            scanf("%s",s);
            while(scanf("%s",s) && strcmp(s,"</link>") != 0)
                 url_value[s]++;
            scanf("%s",s);
        }
        printf("<case>\n");
        while(scanf("%s",s) && strcmp(s,"</query>") != 0)
        {
            printf("  <reply query=\"%s\">\n",s);
            if(word_index.find(s) == word_index.end())
            {
                printf("    Sorry, not found...\n  </reply>\n");
                continue;
            }
            set<string> st = word_index[s];
            int tot = 0;
            for (set<string>::iterator it = st.begin(); it != st.end(); it++)
            {
                turl.w = url_value[*it];
                strcpy(turl.s,(*it).c_str());
                urls[tot++] = turl;
            }
            sort(urls,urls+tot);
            for (int i = 0; i < tot; i++)
                printf("    %s\n",urls[i].s);
            printf("  </reply>\n");
        }
        printf("</case>\n");
        scanf("%s",s);
    }
    return 0;
}
posted @ 2012-07-24 20:58  Ijingo  阅读(245)  评论(0编辑  收藏  举报