Alibaba笔试题:给定一段产品的英文描述,包含M个英文字母,每个英文单词以空格分隔,无其他标点符号;
再给定N个英文单词关键 字,请说明思路并编程实现方法String extractSummary(String description,String[] key words),
目标是找出此产品描述中包含N个关键字(每个关键词至少出现一次)的长度最短的子串,作为产品简介输出。(不限编程语言)20分。
运用尺取法求解
import java.util.Arrays;
public class 最短生成摘要 {
public static void main(String[] args) {
solve(new String[]{"t","a","b","v","r","s","e","a","b","e","v"},new String[]{"t","a","r"});
}
/**
* word在q的第几位
*
* @param q
* @param word
* @return
*/
private static int indextOf(String[] q, String word) {
for (int i = 0; i < q.length; i++) {
if (q[i].equals(word))
return i;
}
return -1;
}
/**
* 求所找到关键字个数之和
* @param keyFound
* @return
*/
private static int sum(int []keyFound){
int sum = 0;
for(int e:keyFound){
sum+=e;
}
return sum;
}
public static void solve(String[] w, String[] keys) {
// begin和end用于在找到更短的包含全部关键字数组时更新
int begin = -1;
int end = -1;
int p2 = -1;// 记录上一次囊括了所有关键字的右边界
int minlen = Integer.MAX_VALUE;
int[] keyFound = new int[keys.length];
for (int i = 0; i < w.length; i++) {
Arrays.fill(keyFound, 0);
// 如果i位是关键字,求以i开头包含所有关键字的序列
String word1 = w[i];
int index = indextOf(keys, word1);
if (-1==index) {
continue;
} else {
keyFound[index] = 1;// 标记关键字
}
int j;
if (p2 != -1) {
j = p2;
} else {
j = i + 1;
}
for(;j<w.length;j++){
String word2 = w[j];//文章单词
int index1 = indextOf(keys, word2);
if(index1==-1||keyFound[index1]==1){
//如果不属于关键字,或者已经找到过这个关键字
continue;
}else{//找到没有标记过的关键字
keyFound[index1]=1;//进行标记
if(sum(keyFound)==keys.length){
p2=j;//记录这一段的右边界,同时也是下一右边界的起点
if(j - i+1<minlen){//更新
minlen = j-i+1;
begin = i;
end = j;
}
break;
}
}
}
}
print(w,begin,end);
}
/**
* 打印
*/
private static void print(String[]w,int begin,int end){
System.out.println(begin+" "+end);
for(int i = begin;i<=end;i++){
System.out.print(w[i]+" ");
}
System.out.println();
}
}