尺取法之最短摘要的问题(暴力破解)

1. 问题描述:

给定一段产品的英文描述,包含M个单词,每个英文单词以空格分隔,无其他的标点符号
再给定N个英文单词关键字,要找出此产品描述中的包含的N个关键字(每个关键字至少出现一次)的长度最短的子串,作为产品简介输出,请说明思路并变成实现方法

2. 使用两层循环依次扫描,第一层循环变量为i,第二层循环变量为j,那么每一次从i到j,判断i到j之间是否包含所有关键字,这里判断的处理交给一个函数来处理,并且把所有要寻找的关键字放入到map中,其中关键字可能有重复,所以这里要处理单词重复的问题,在整个函数中扫描所有放进map的关键字,看i到j之间的单词是否全部在里面

3. 具体的代码实现如下:

import java.util.HashMap;
import java.util.Map;
public class Main {
	public static void main(String[] args) {
		solve(new String[]{"a","ab","a","a","b","c","d","h","e","f","f","c","c","d","e","f","d","h","q"},
		new String[]{"ab","a"});
	}

	private static void solve(String[] words, String[] keys) {
		int begin = 0,end = 0;
		int len = Integer.MAX_VALUE;
		for(int j = 1;j<words.length;j++){
			for(int i = j-1;i>=0;i--){
				if(containsAll(words,keys,i,j)){
					if(j-i+1<len){
						len = j-i+1;
						begin = i; 
						end = j;
					}
				}
			}
		}
		print(words,begin,end);
	}

	private static void print(String[] words, int begin, int end) {
		System.out.println(begin+" "+end);
		for(int i = begin;i<=end;i++){
			System.out.print(words[i]+" ");
		}
	}

	private static boolean containsAll(String[] words, String[] keys, int i, int j) {
		Map<String,Integer> map1 = new HashMap<String,Integer>();
		for(int k = 0;k<keys.length;k++){
			String key = keys[k];
			if(map1.get(key)==null)map1.put(key, 1);
			else{
				//假如关键字有两个重复的字,那么在上一次的基础上加1
				map1.put(key, map1.get(key)+1);
			}	
		}
		Map<String,Integer> map2 = new HashMap<String,Integer>();
		for(int k = i;k<=j;k++){
			String key = words[k];
			if(map2.get(key)==null)map2.put(key, 1);
			else{
				//假如关键字有两个重复的字,那么在上一次的基础上加1
				map2.put(key, map2.get(key)+1);
			}	
		}
		//循环遍历关键在看看i到j是否全部包含
		for(Map.Entry<String, Integer>e:map1.entrySet()){
			if(map2.get(e.getKey())==null||map2.get(e.getKey())<e.getValue()){
				return false;
			}
		}
		return true;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值