java最短摘要_【字符串】最短摘要问题

给定一段产品的英文描述,包含M个英文单词,每个单词以空格分隔。无其他标点符号; 再给定N个英文单词做关键词。

编程实现方法,目标是按照此产品的描述包含N个关键字的长度最短的子串,作为产品简介输出。 每个关键词至少出现一次。

方法1:暴力法

利用双层循环,从头遍历M个英文单词,如果N个关键词均包含在keyFound[i,j]中,且如果这段距离是最短的,就更新begin,end,直至扫描完全部M个英文单词。打印最短的产品简介。

方法2:尺取法

尺取法通常是指对数组保存一对下标(起点,终点),然后根据实际情况交替推进两个端点直到得出答案的方法。

扫描M个英文单词,二叉搜索查找该处单词是否在关键词中,如果不在就continue,如果在,且右边界大于i且全部找到就更新最短距离,再继续走循环直到结束。

第一次右边界从i+1走,查找接下来未找到的关键词,同上。需要考虑在关键词有重复的情况。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 private static voidsolve1(String[] src, String[] keys) {2

3 int minlength =Integer.MAX_VALUE;4 int begin = -1;5 int end = -1;6 for (int i = 0; i < src.length; i++) {7 for (int j = i + 1; j < src.length; j++) {8

9 if (containsAll(src, keys, i, j)) {//如果该段包含全部的关键词

10

11 if (j - i + 1 < minlength) {//且为距离最短的一段

12 minlength = j - i + 1;13 begin =i;14 end =j;15 }16 break;17 }18 }19 }20 print(src, begin, end);21 }

暴力法

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public static voidsolve2(String[] src, String[] keys) {2 Arrays.sort(keys);3 int j=-1;4 int begin=-1;5 int end=-1;6 int minlength=Integer.MAX_VALUE;7 for (int i = 0; i < src.length; i++) {8 String word=src[i];9 int index=Arrays.binarySearch(keys, word);10 if(index==-1){11 continue;12 }else{//i处是一个关键字

13 if(j=i &&containsAll(src, keys, i, j)){//所有关键词全部找到

14 if(minlength>j-i+1){15 minlength=j-i+1;16 begin=i;17 end=j;18 }19 continue;20 }21

22 }23 if(j==-1)24 j=i+1;25 while(j

31 if(containsAll(src, keys, i, j)){//所有关键词全部找到

32 if(minlength>j-i+1){33 minlength=j-i+1;34 begin=i;35 end=j;36 }37 break;//退出while循环

38 }else{//还没找到左右,j继续走

39 j++;40 }41 }42

43 }44 }45 print(src, begin, end);46 }

尺取法

判断该段是否包含全部关键词 思路:

利用hash映射,将关键词keys的数组加入如果之前没出现过,就将其加入map,如果出现过就将其value+1;

然后在利用第二个map2,扫描src[i,j]段单词数组,同上操作;

最后扫描关键词的map,如果map2的那段中不包含关键词中,或者包含关键词的个数不相等 就return false;

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 /**

2 *3 *@paramsrc4 *@paramkeys5 *@parami6 *@paramj7 *@return

8 */

9 private static boolean containsAll(String[] src, String[] keys, int i, intj) {10 Map map = new HashMap<>();11 for (int k = 0; k < keys.length; k++) {12 String key =keys[k];13 if (map.get(key) == null) {14 map.put(key, 1);15 } else {//如果已经存在,就将value+1

16 map.put(key, map.get(key) + 1);17 }18

19 }20 Map map2 = new HashMap<>();21 for (int k = i; k <= j; k++) {22 String key =src[k];23 if (map2.get(key) == null) {24 map2.put(key, 1);25 } else {//如果已经存在,就将value+1

26 map2.put(key, map2.get(key) + 1);27 }28

29 }30 for (Map.Entrye : map.entrySet()) {31 if (map2.get(e.getKey()) == null

32 || map2.get(e.getKey())

36 }37

38 return true;39 }

辅助方法containsAll

打印结果数组

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 private static void print(String[] src, int begin, intend) {2

3 System.out.println(begin + " " +end);4 for (int i = begin; i <= end; i++) {5 System.out.print(src[i] + " ");6 }7 //System.out.println();

8

9 }

print

测试代码

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public static voidmain(String[] args) {2 String[] s1 = { "a", "b", "c", "seed", "h", "e", "f", "c", "c", "seed",3 "e", "f", "seed", "c"};4 String[] s2 = { "c", "e","c"};5 //solve1(s1, s2);

6 solve2(s1,s2);7 }

测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值