#include <stdio.h>
#include <string.h>
#include <ctype.h>
typedef struct
{
int quote;
char title[251];
}Title;
typedef struct
{
char keyword[21];
int numOfadd;
int address[1001];
}Key;
void AddKey(Key* keyContain,int *n,char *keyword,int address);
void Addaddress(Key* keyContain,int n,int address);
int IsContain(Key* keyContain,int n,char *keyword);
int FindoneKey(Key* keyContain,int n,int *list,int *nl,char *keyword);
int FindtwoKey(Key* keyContain,int n,int *list,int *nl,char *keyword);
Key keyContain[101];
Title paper[1000];
int main()
{
char letter[21];
char title[251];
int quote,nl,first,flag;
int list[1001];
char *pt,*p,temp;
int numOfkeyword,N,M,i,j,k;
while(scanf("%d",&N)&&N!=0)
{
getchar();
numOfkeyword=0;
memset(paper,0,sizeof(paper));
i=0;
while(i<N)
{
gets(title);
scanf("%d","e);
getchar();
for(j=0;quote<=paper[j].quote;j++);
for(k=i;k>=j;k--)
{
paper[k+1].quote=paper[k].quote;
strcpy(paper[k+1].title,paper[k].title);
}
paper[j].quote=quote;
strcpy(paper[j].title,title);
i++;
}
for(i=0;i<N;i++)
{
memset(title,0,sizeof(title));
strcpy(title,paper[i].title);
pt=title;
while(*pt!='\0')
{
if(isalpha(*pt))
{
p=pt;
while(isalpha(*pt))
pt++;
*pt='\0';
strcpy(letter,strlwr(p));
//printf("%s\n",letter);
temp=IsContain(keyContain,numOfkeyword,letter);
if(-1==temp)
AddKey(keyContain,&numOfkeyword,letter,i+1);
else
Addaddress(keyContain,temp,i+1);
}
pt++;
}
}
/**接下来开始查找**/
scanf("%d",&M);
getchar();
while(M--)
{
memset(title,0,sizeof(title));
gets(title);
pt=title;
flag=1;
first=1;
while(*pt!='\0'&&flag==1)
{
if(isalpha(*pt))
{
p=pt;
while(isalpha(*pt))
pt++;
*pt='\0';
strcpy(letter,strlwr(p));
if(first==1)
{
flag=FindoneKey(keyContain,numOfkeyword,list,&nl,letter);
first=0;
}
else
flag=FindtwoKey(keyContain,numOfkeyword,list,&nl,letter);
}
pt++;
}
if(flag==1)
{
for(i=0;list[i]!=-1;i++)
printf("%s\n",paper[list[i]-1].title);
}
printf("***\n");
}
printf("---\n");
}
return 0;
}
/******************************************/
/**功能:在key容器中添加新关键词***********/
/******************************************/
void AddKey(Key* keyContain,int *n,char *keyword,int address)
{
strcpy(keyContain[*n].keyword,keyword);
keyContain[*n].address[0]=address;
keyContain[*n].numOfadd=1;
(*n)++;
}
/******************************************/
/**功能:添加某个关键词在文章中出现的位置**/
/******************************************/
void Addaddress(Key* keyContain,int n,int address)
{
keyContain[n].address[keyContain[n].numOfadd]=address;
keyContain[n].numOfadd++;
}
/******************************************/
/**功能:判断keyword单词是否在key容器中**/
/*参数:
key:容器
n:容器内关键词数量;
keyword:单词 ****/
/*返回值:不包含返回-1,包含返回单词的位置*/
/******************************************/
int IsContain(Key* keyContain,int n,char *keyword)
{
int i;
for(i=0;i<n;i++)
{
if(!strcmp(keyContain[i].keyword,keyword))
return i;
}
return -1;
}
/*******************************************/
/*功能:在list列表所指的索引中寻找keyword*/
/*若找到,则更新list,以便下一个关键词查找*/
/*****返回值:找到了返回1,否则返回0******/
/*******************************************/
int FindoneKey(Key* keyContain,int n,int *list,int *nl,char *keyword)
{
int i,j;
for(i=0;i<n;i++)
{
if(!strcmp(keyContain[i].keyword,keyword))
{
j=i;
for(i=0;i<keyContain[j].numOfadd;i++)
list[i]=keyContain[j].address[i];
list[i]=-1;
*nl=i;
return 1;
}
}
return 0;
}
int FindtwoKey(Key* keyContain,int n,int *list,int *nl,char *keyword)
{
int i,j,k,temp=0,flag=0;
for(i=0;i<n;i++)
{
if(!strcmp(keyContain[i].keyword,keyword))
{
j=i;
for(i=0;i<keyContain[j].numOfadd;i++)
for(k=0;k<*nl;k++)
{
if(keyContain[j].address[i]==list[k])
{
list[temp]=keyContain[j].address[i];
temp++;
flag=1;
}
}
list[temp]=-1;
*nl=temp;
break;
}
}
return flag;
}
Description
谷歌、百度等搜索引擎已经成为了互连网中不可或缺的一部分。在本题中,你的任务也是设计一个搜索论文的搜索引擎,当然,本题的要求比起实际的需求要少了许多。
本题的输入将首先给出一系列的论文,对于每篇论文首先给出标题,然后给出它被引用的次数。然后会有一系列的搜索询问,询问标题中包含特定关键词的论文有哪些。
每一个询问可能包含多个关键词,你需要找出标题包含所有关键词的论文。
“包含”必须是标题中有一个词正好是给定的关键词,不区分大小写。
对每个询问,都按被引用的次数从多到少输出满足条件的论文的标题。如果有被引用的次数相同的论文,则按照论文在输入中的顺序排列,先给出的论文排在前面。
Input
输入包含多组数据。
每组数据首先有一行包含一个整数N(1<=N<=1000),表示论文的数目,N=0表示输入结束。每组论文的信息第一行是论文的标题,由字母(大小写均可)和空格组成,不超过10个词,每个词不超过20个字符,标题总共不超过250个字符。第二行是一个整数K(0<=K<=10^8),表示它被引用的次数。在论文信息结束以后,有一行包含一个整数M(1<=M<=100),表示询问的数目。接下来有M行,每行是一个询问,由L(1<=L<=10)个空格分开的词构成,每个词不超过20个字符。
Output
对每个询问,按照题目给定的顺序输出满足条件的论文的标题;如果没有满足条件的论文,就不输出。在每组询问的输出之后输出一行”***”,在每组数据的输出之后输出一行”---”。
Sample Input
6
Finding the Shortest Path
120
Finding the k Shortest Path
80
Find Augmenting Path in General Graph
80
Matching in Bipartite Graph
200
Finding kth Shortest Path
50
Graph Theory and its Applications
40
6
shortest path
k shortest path
graph
path
find
application
0
Sample Output
Finding the Shortest Path
Finding the k Shortest Path
Finding kth Shortest Path
***
Finding the k Shortest Path
***
Matching in Bipartite Graph
Find Augmenting Path in General Graph
Graph Theory and its Applications
***
Finding the Shortest Path
Finding the k Shortest Path
Find Augmenting Path in General Graph
Finding kth Shortest Path
***
Find Augmenting Path in General Graph
***
***
---