转自:http://blog.csdn.net/huangxy10/article/details/8087035
2011年题目:
Alibaba笔试题:
给 定一段产品的英文描述,包含M个英文字母,每个英文单词以空格分隔,无其他标点符号;再给定N个英文单词关键字,请说明思路并编程实现方法String extractSummary(String description,String[] key words),目标是找出此产品描述中包含N个关键字(每个关键词至少出现一次)的长度最短的子串,作为产品简介输出。(不限编程语言)20分。
人搜面试题:
1、求包含所有query的最短距离
一篇文章,切完词之后放到一个vector<string>中,一个查询切完词也放到一个vector<string>中,写一个函数找出这篇文章中包含这个查询中所有词的最小区间的i和j。只要返回第一个即可。
解答:
这道笔试题和编程之美最短摘要生成的方法类似,先来看看这些序列:
w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1
问题在于,如何一次把所有的关键词都扫描到,并且不遗漏。扫描肯定是无法避免的,但是如何把两次扫描的结果联系起来呢?这是一个值得考虑的问题。
沿用前面的扫描方法,再来看看。第一次扫描的时候,假设需要包含所有的关键词,从第一个位置w0处将扫描到w6处:
w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1
那么,下次扫描应该怎么办呢?先把第一个被扫描的位置挪到q0处。
w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1
然后把第一个被扫描的位置继续往后面移动一格,这样包含的序列中将减少了关键词q0。那么,我们便可以把第二个扫描位置往后移,这样就可以找到下一个包含所有关键词的序列。即从w4扫描到w9处,便包含了q1,q0:
w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1
这样,问题就和第一次扫描时碰到的情况一样了。依次扫描下去,在w中找出所有包含q的序列,并且找出其中的最小值,就可得到最终的结果。
1 #include <iostream> 2 #include <vector> 3 #include <string> 4 #include <set> 5 using namespace std; 6 7 bool FindShortestAbstract( const vector<string> & doc, const set<string> & query, int &a, int &b){ 8 set<string> notFind(query.begin(), query.end()); 9 a=0;b=0; 10 int i=0,j=0; 11 int shortest=0; 12 int len= doc.size(); 13 while( i<len&&j<len ){ 14 set<string>::iterator it = notFind.find( doc[j++] ); 15 if( it!=notFind.end()) { //如果找到了,则删除 16 notFind.erase( it ); 17 } //找到最后一个query元素的指向j 18 if( notFind.empty() ){ //如果全部找到 19 while( query.find(doc[i++])==query.end() ); //寻找第一个出现的query,while(1) 一直循环直到while(0)出现 20 if( i>0 ){ 21 notFind.insert( doc[i-1] ); 22 if( shortest>j-i||shortest==0 ) 23 shortest = j-i; //记录最小距离 24 a=i-1;b=j-1; 25 } 26 } 27 } 28 if( shortest==0 ) 29 return false; 30 return true; 31 } 32 33 int main(){ 34 string doc[]={"I", "love", "you", "and", "me", "do", "you", "like" , "me"}; 35 string query[]={ "you", "like", "me"}; 36 vector<string> d(doc,doc+sizeof(doc)/sizeof(string)); 37 set<string> q(query, query+sizeof(query)/sizeof(string)); 38 int a=0,b=0; 39 FindShortestAbstract( d,q,a,b); 40 cout <<a<<endl<<b<<endl; 41 return 0; 42 }