最短摘要生成(优化时间复杂度O(N))Java实现

问题简要描述:在一段文字中找到蕴含题目中所给关键词的最短摘要。

分析:网上大多使用的双指针(start和end),这里我觉得没有必要,我用的是Map和ArrayList来做的。 用Map记录每一个关键词的下标,同时用Arraylist辅助记录,只要Arraylist的长度小于关键词的长度就一直遍历,相同则计算总长度与之前计算的长度进行比较。

step1:只要没有找到所有的关键词则一直往下遍历

step2:只要出现来重复的关键词就替换下标(Map和Arraylist)。

step3:找到所有的关键词则计算长度,同时返回arraylist中的最小值和最大值(当然也可以只返回最小值)。

step4:比较min的值,小于则更新。

step5:删除arraylist中的最小值,继续重复step1,2,3,4。

/**
 * Created by mac on 2019/4/13.
 */

import java.util.*;

import static java.util.Collections.*;

public class 最短摘要 {
    private static void solve(String[] w, String[] q) {
        Map<String,Integer> mark = new HashMap<>();
        ArrayList<Integer> storeIndex = new ArrayList<>();
        int min = 1000000;
        int minStart = -1;
        int minEnd = -1;
        for (int i = 0; i < q.length; i++) {// 初始将每一个关键词的下标计作-1;
            mark.put(q[i],-1);
        }
        for (int i = 0; i < w.length; i++) {// 对于目标数组进行查询
            if (mark.containsKey(w[i])){ // 如果包含这个key, 更新这个key的下标;
                int k = mark.get(w[i]);
                if (storeIndex.contains(k))
                    storeIndex.remove(storeIndex.indexOf(k));
                storeIndex.add(i);
                mark.put(w[i],i);
                // 更新完下标之后判断关键词是否全部都囊括。
                if (storeIndex.size() == q.length){
                    int[] temp = getLength(storeIndex);
                    if (temp[0] < min){
                        min = temp[0];
                        minStart = temp[1];
                        minEnd = temp[2];
                    }
                    storeIndex.remove(storeIndex.indexOf(temp[1]));
                    continue;
                }

            }
        }
        for (int i = minStart; i <= minEnd; i++) {
            System.out.print(w[i]);
        }
    }
    private static int[] getLength(ArrayList<Integer> storeIndex) {
        sort(storeIndex);
        int start = storeIndex.get(0);
        int end = storeIndex.get(storeIndex.size()-1);
        int[] res = new int[]{end-start+1,start,end};
        return res;
    }
    public static void main(String[] args) {
        solve(new String[]{"a","b","c","d","c","e","f","g","e","h","c","g"},new String[]{"c","e","h"});
        System.out.println();
        String keyword[] = { "微软", "计算机", "亚洲" ,"交流"};
        String description[] = {
                "微软", "亚洲", "研究院", "成立", "于", "1998", "年", ",", "我们", "的", "使命",
                "是", "使", "未来", "的", "计算机", "能够", "看", "、", "听", "、", "学", ",",
                "能", "用", "自然语言", "与", "人类", "进行", "交流", "。", "在", "此", "基础", "上",
                ",", "微软", "亚洲", "研究院", "还", "将", "促进", "计算机", "在", "亚太", "地区",
                "的", "普及", ",", "改善", "亚太", "用户", "的", "计算", "体验", "。", "”"};
        solve(description,keyword);
    }
}

测试结果:

大家可以自己先理解下,如果不懂,可以私信我。

猜你喜欢

转载自blog.csdn.net/Night__owl/article/details/89282788