java最短摘要_编程之美--3.5最短摘要生成

Alibaba笔试题:给定一段产品的英文描述,包含M个英文字母,每个英文单词以空格分隔,无其他标点符号;再给定N个英文单词关键字,请说明思路并编程实现方法String extractSummary(String description,String[] key words),目标是找出此产品描述中包含N个关键字(每个关键词至少出现一次)的长度最短的子串,作为产品简介输出。(不限编程语言)20分。

这道笔试题和编程之美最短摘要生成的方法类似,我用java实现了这个方法。

先来看看这些序列:

w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1

问题在于,如何一次把所有的关键词都扫描到,并且不遗漏。扫描肯定是无法避免的,但是如何把两次扫描的结果联系起来呢?这是一个值得考虑的问题。

沿用前面的扫描方法,再来看看。第一次扫描的时候,假设需要包含所有的关键词,从第一个位置w0处将扫描到w6处:

w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1

那么,下次扫描应该怎么办呢?先把第一个被扫描的位置挪到q0处。

w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1

然后把第一个被扫描的位置继续往后面移动一格,这样包含的序列中将减少了关键词q0。那么,我们便可以把第二个扫描位置往后移,这样就可以找到下一个包含所有关键词的序列。即从w4扫描到w9处,便包含了q1,q0:

w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1

这样,问题就和第一次扫描时碰到的情况一样了。依次扫描下去,在w中找出所有包含q的序列,并且找出其中的最小值,就可得到最终的结果。

编程之美上给出了如下参考代码:

int nTargetLen = N + 1; //设置目标长度为总长度+1int pBegin = 0; //初始指针int pEnd = 0; //结束指针int nLen = N; //目标数组的长度为Nint nAbstractBegin = 0; //目标摘要的起始地址int nAbstractEnd = 0; //目标摘要的结束地址

while(true)

{

//假设未包含所有的关键词,并且后面的指针没有越界,往后移动指针 while(!isAllExisted() && pEnd < nLen)

{

pEnd++;

}

//假设找到一段包含所有关键词信息的字符串 while(isAllExisted())

{

if(pEnd – pBegin < nTargetLen)

{

nTargetLen = pEnd – pBegin;

nAbstractBegin = pBegin;

nAbstractEnd = pEnd – 1;

}

pBegin++;

}

if(pEnd >= N)

Break;

}

以下是我写的java实现代码。

使用HashMap将关键字映射到数字,减少字符串比较,能进一步提高效率。使用数组保存关键字被访问到的次数,用来判断是否包含全部关键字。

package com.flyoung;

import java.util.HashMap;

import java.util.Map;

public class Abstract {

/** 编程之美 最短摘要生成

**/

private int[] keywordsArray; //记录关键字被访问次数的数组 private int pBegin=0;//查找起始点 private int pEnd=0;//查找终点 private int abstractBegin=0;//摘要起始点 private int abstractEnd=0;//摘要终点 private int targetLen;//摘要最小长度 private Map map;//将关键字映射成数字

public Abstract(String[] keywords){

int len = keywords.length;

this.keywordsArray = new int[len];

this.map = keywordsMap(keywords);

}

public String extractSummary(String description,String[] keywords){

String[] array = description.split(" ");//将字符串转化为数组 return extract(array,keywords);

}

//实际的抽取函数 public String extract(String[] description,String[] keywords){

String summary = "";

int nLen = description.length;

targetLen = nLen+1;

while(true){

while(!isAllExisted()&&pEnd

if(this.map.get(description[pEnd])!=null){

setKeywordsArray(keywordsArray,this.map.get(description[pEnd]),0);

}

pEnd++;

}

while(isAllExisted()){

if(pEnd-pBegin

targetLen = pEnd-pBegin;

abstractBegin = pBegin;

abstractEnd = pEnd-1;

}

if(map.get(description[pBegin])!=null){

setKeywordsArray(keywordsArray,map.get(description[pBegin]),1);

}

pBegin++;

}

if(pEnd>=nLen){

break;

}

}

for(int j=abstractBegin;j<=abstractEnd;j++){

if(j!=abstractEnd){

summary = summary+description[j]+" ";

}else{

summary +=description[j];

}

}

return summary;

}

public Map keywordsMap(String[] keywords){

Map map = new HashMap();

int len = keywords.length;

for(int i=0;i

map.put(keywords[i], i);

}

return map;

}

//设置关键字被访问到的次数 public void setKeywordsArray(int[] keywordsArray,int i,int flag){ //flag:0 add flag:1 sub if(flag==0){

keywordsArray[i]++;

}else{

keywordsArray[i]--;

}

}

//检查是否包含全部关键字 public boolean isAllExisted(){

boolean result = true;

for(int a:keywordsArray){

if(a==0){

result=false;

break;

}

}

return result;

}

public static void main(String[] args) {

String description="hello software hello test world spring sun flower hello";

String[] keywords = {"hello","world"};

Abstract nAbstract = new Abstract(keywords);

System.out.println(nAbstract.extractSummary(description, keywords));

}

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值