编程之美读书笔记-最短摘要的生成

原创 2016年08月31日 11:16:20

题目:给定一段产品的英文描述,包含M个英文字母,每个英文单词以空格分隔,无其他标点符号;再给定N个英文单词关键字,请说明思路并编程实现方法string ExtractSummary(string description, string keywords[]),目标是找出此产品描述中包含N个关键字(每个关键词至少出现一次)的长度最短的子串,作为产品简介输出。
解析:假设关键词序列为q0,q1,……,其它词序列为w0,w1,……。那么我们可以看看这样一个序列:
w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1
对于这个序列,符合条件的产品简介就是最后几个位置的词q0,w9,q1,最短的长度为3。
我们可以从W数组的第一个位置开始查找一段所有包含关键词数组Q的序列,再从第二个位置查找……这样复杂度很高。为了降低复杂度,我们需要把前后两次扫描的结果联系起来。沿用前面的扫描方法,再来看看。第一次扫描的时候,假设需要包含所有的关键词,将得到如下的结果。
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。那么,我们便可以把第二个扫描位置往后移,这样就可以找到下一个包含所有关键词的序列。
w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1
这样,问题就和第一次扫描时碰到的情况一样了。依次扫描下去,在w中找出所有包含q的序列,并且找出其中的最小值,就可得到最终的结果。

#include <string> 
#include <iostream> 
#include <algorithm>  
using namespace std;
#define KeyWordNumber 3

bool isAllExisted(string s1, string s2[])
{
	for (int i = 0; i < KeyWordNumber; ++i)
	{
		if (s1.find(s2[i]) == string::npos) return 0;
	}
	return 1;
}

string ExtractSummary(string description, string keywords[])
{
	int nTargetLen = description.length();
	//设置最大目标长度
	int pBegin = 0;
	//初始指针
	int pEnd = 0;
	//结束指针
	int nAbstractBegin = 0;
	//目标摘要的起始地址
	int nAbstractEnd = 0;
	//目标摘要的结束地址
	while (1)
	{
		//假设没有包含所有的关键词,并且后面的指针没有越界,往后移动指针
		while (pEnd < description.length()-1 && !isAllExisted(description.substr(pBegin, pEnd - pBegin + 1), keywords))
		{
			pEnd++;
		}
		//假设找到一段包含所有关键信息的字符串
		while (isAllExisted(description.substr(pBegin, pEnd - pBegin + 1), keywords))
		{
			if (pEnd - pBegin + 1 <= nTargetLen)
			{
				nTargetLen = pEnd - pBegin + 1;
				nAbstractBegin = pBegin;
				nAbstractEnd = pEnd;
			}
			pBegin++;
		}
		if (pEnd >= description.length()-1) break;
	}
	return description.substr(nAbstractBegin, nAbstractEnd - nAbstractBegin + 1);
}

int main()
{
	string text = "money is important than knife and money is can buy garden";
	string abstract[3];
	abstract[0] = "money";
	abstract[1] = "and";
	abstract[2] = "garden";
	string res = ExtractSummary(text, abstract);
	cout << res << endl;
	return 0;
}






编程之美读书笔记-买书问题

题目:在节假日的时候,书店一般都会做促销活动。由于《哈利波特》系列相当畅销,店长决定通过促销活动来回馈读者。上柜的《哈利波特》平装书系列中,一共有五卷。假设每一卷单独销售均需8欧元。如果读者一次购买不...
  • qq_32400847
  • qq_32400847
  • 2016年09月09日 20:01
  • 452

编程之美读书笔记 汇总

(1)编程之美读书笔记(1)二进制数中1的个数 (2)编程之美读书笔记(2)大数问题(高精度运算) (3)编程之美读书笔记(3) 统计在从1到n的正整数中1出现的次数 (4)编程之美...
  • SJF0115
  • SJF0115
  • 2013年02月25日 16:54
  • 1301

[算法系列之二十一]最短摘要的生成

题目描述你我在百度或谷歌搜索框中敲入本博客名称的前4个字“结构之法”,便能在第一个选项看到本博客的链接,如下图2所示: 图2 谷歌中搜索关键字“结构之法”在上面所示的图2中,搜索结果“结构之法算...
  • SunnyYoona
  • SunnyYoona
  • 2015年02月23日 16:36
  • 1342

对称、非对称加密算法、消息摘要算法、数字证书详解

消息摘要算法 消息摘要算法包括MD(Message Digest 消息摘要算法),SHA(Secure Hash Agorithm 安全散列算法),MAC(Message Authenticat...
  • woshichengchaoa
  • woshichengchaoa
  • 2014年01月14日 09:52
  • 3961

【java】《java编程思想》 读书笔记

之前主要用的C++的比较多,之前花了快2个月的实际认真系统全面的学习了以下java的基础语法,《java编程思想》这本书翻译水平确实不是很好,很多话读着会比较拗口。推荐读之前,先去网上搜索 “java...
  • a2888409
  • a2888409
  • 2015年10月15日 10:07
  • 1941

编程之美--最短摘要的生成

题目:抽象点说,就是在一个字符串中,找一些目标字符串,找到包含所有目标字符串的最小字符串。题目虽然叫做最短摘要生成,但和实际的搜索snippet的计算还是有比较大的差距的。 解法:一种比较好...
  • woshibendangao
  • woshibendangao
  • 2014年08月18日 14:38
  • 457

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

看了下《编程之美》这本书,记录下3.5节的理解。 1.题意是什么? 题目含义就是在已知字符串S1中搜索含有字符串S2的最小字符串,例如,S1="ABCDEMKFDC",S2="...
  • wxd_zswx
  • wxd_zswx
  • 2015年08月19日 16:14
  • 449

编程之美: 第三章 结构之法 3.5最短摘要的生成

/* 最短摘要的生成; 输入一些关键词之后,搜索引擎会返回许多结果,每个结果都包含一段概括网页内容的还要。标题和URL之间的内容就是我们所说的摘要 假设给定的已经是网页分词之后的结果,词语序列数组为...
  • qingyuanluofeng
  • qingyuanluofeng
  • 2015年08月04日 00:53
  • 379

编程之美最短摘要生成

本来以为这个会很难的,因为自己不是很了解这方面的东西。 看了下解释 大致明白了,就是用最少的句子 ,包含所有的关键词。 ok~看了编程之美的code后 感觉很好,类似kmp算法,跳过已经比对过的字...
  • hiphopmattshi
  • hiphopmattshi
  • 2012年09月27日 22:54
  • 4132

编程之美--最短摘要的生成

package structure; import java.util.Arrays; import java.util.HashMap; import java.util.Map; /** *...
  • jiang_bing
  • jiang_bing
  • 2012年10月26日 11:19
  • 747
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:编程之美读书笔记-最短摘要的生成
举报原因:
原因补充:

(最多只允许输入30个字)