阿里巴巴笔试题:给定一段产品的英文描述,包含M个英文字母,每个英文单词以空格分隔,无其他标点符号;再给定N个英文关键词,请说明思路并变成实现方法。
String extractSummary(String description , String[] keyWords)
目标:找出此产品描述中包含N个关键字的长度最短的子串(20分)
W0 W1 W2 W3 Q0 W4 W5 Q1 W6 W7 W8 Q0 W9 Q1
P335 《编程之美》上的参考代码:
int nTarget = N + 1;
int pBegin = 0;
int pEnd = 0;
int nLen = N;
int nAbstractBegin = 0;
int nAbstractEnd = 0;
while(true)
{
while(!isAllExisted() && pEnd < nLen)
pEnd++;
while(isAllExisted())
{
if(pEnd - pBegin < nTargetLen)
{
nTarget = pEnd - pBegin;
nAbstractBegin = pBegin;
nAbstractEnd = pEnd - 1;
}
pBegin++;
}
if(pEnd >= N)
break;
}
1.将传入的keyWords[]生成哈希表,以便字符串比较 P337
struct keyWords{
int cnt;
char key[];
int hash;
}
2.struct keyWord{当前扫描到的一个关键词
int start;
KeyHash* key;
KeyWord* next;
KeyWord* prev;
}
3.全局变量
KeyWord* head;
KeyWord* tail;
int minLen;
int minStartPos;
int needKeyCnt;
4.扫描文章,每扫描到一个关键字时,就建立一个KeyWord,并连入双向链表中。
更新head,tail
对应KeyHash结构中的cnt+1
若cnt 0 - 1,则needKeyCnt - 1;
5.needKeyCnt = 0时,扫描到了全部关键字
链表头优化
若cnt大于1,说明摘要中还有相同;
跳过,cnt-1
直至某个链表头对应KeyHash中的cnt为1,此事该结构不能少了。
6.如果找到更短的minLength,更新minLength和minStartPos;
7.开始新一轮搜索
摘除链表第一个节点
needKeyCnt + 1;
下一节点 - 链表头,开始优化。
*搜索从上一次搜索结束处开始,不用回溯,一直沿文章向下。
7.实际意义:摘要应该包含完整的句子
struct Sentence
{
int start;
int end;
KeyWord* StartKey;
KeyWord* endKey;
Sentence* prev;
Sentence* next;
}
扫描到一个完整句子的结束
Sentence头结点优化
句子全部key的cnt-1;才去掉句子
更新HashKey
直至句子包含只出现一次的关键字
扩展问题:
如何判断两个页面相似。