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

题意:假设给定的已经是经过网页分词之后的结果,词语序列数组为W。其中W[0], W[1], ... , W[N]为一些已经分好的词语。假设用户输入的搜索关键词为数组Q。其中Q[0], Q[1], ... Q[m]为所有输入的搜索关键词。

例如,我们可以看到这样一个序列:

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

解法思路:

  第一次扫描时,假设包含所有关键词,将得到如下的结果(用 a 这种形式表示指向位置)

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

  保持第二个指针不变,将第一个指针指向往后移动,只要包含所有关键词,更新最小摘要序列。直到缺少一个关键词为止。

  第二次扫描就成了下面的结果:

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

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

代码示例如下:

 1 #include <stdio.h>
 2 #include<map>
 3 #include<string>
 4
 5 using namespace std;
 6
 7 int main()
 8 {
 9
10     char keyword[][3] = {"q0", "q1"};
11     char description[][3] = {"w0","w1","w2","w3","q0","w4","w5",
12                         "q1","w6","w7","w8","q0","w9","q1"};
13
14     int kLen = sizeof(keyword)/sizeof(keyword[0]);
15     int dLen = sizeof(description)/sizeof(description[0]);
16     int N = dLen;
17
18     int nTargetLen = N + 1; //设置目标长度为总长度加1
19     int pBegin = 0;         //初始指针
20     int pEnd = 0;           //结束指针
21     int nLen = N;           //目标数组的长度为N
22     int nAbstractBegin = 0; //目标摘要的起始地址
23     int nAbstractEnd = 0;   //目标摘要的结束地址
24     int cnt = 0;            //记录出现关键词的
25
26     map<string, int> times; //记录各个关键词出现的次数
27     for(int i = 0; i < kLen; i++)
28     {
29         times[string(keyword[i])] = 0;
30     }
31
32     while(1)
33     {
34         //假设包含所有的关键词,并且后面的指针没有越界,往后移动指针
35         while(cnt != kLen && pEnd < nLen)
36         {
37             if(times.count(description[pEnd]))
38             {
39                 if(times[description[pEnd]] == 0)
40                 {
41                     cnt++;
42                 }
43                 times[description[pEnd]]++;
44             }
45             pEnd++;
46         }
47
48         while(cnt == kLen)
49         {
50             if(pEnd - pBegin < nTargetLen)
51             {
52                 nTargetLen = pEnd - pBegin;
53                 nAbstractBegin = pBegin;
54                 nAbstractEnd = pEnd - 1;//此处减一是因为45行多加了一个1
55             }
56
57             if(times.count(description[pBegin]))
58             {
59                 if(--times[description[pBegin]] == 0)
60                 {
61                     cnt--;
62                 }
63             }
64             pBegin++;
65         }
66
67         if(pEnd >= N)
68             break;
69     }
70
71     for(int i = nAbstractBegin; i <= nAbstractEnd; i++)
72     {
73         printf("%s ",description[i]);
74     }
75     return 0;
76 }

参考:https://blog.csdn.net/heart_love/article/details/51576640

原文地址:https://www.cnblogs.com/fenghualong/p/9557433.html

时间: 2024-08-05 09:28:01

编程之美----最短摘要的生成的相关文章

编程之美-最短摘要

这个主要注意几点:首先,str[i]-str[j]包含keyword里面的所有词语,但是不要求顺序相同,然后,str[i]-str[j]是所有满足这样要求的最短子串. 主要方法是:deque<index> store: 记录当前摘要的所有单词在str中的下标,map<string, int> record记录所有当前摘要中出现的次数.min_len:当前最短摘要的长度.min_index_first:当前最短摘要的第一个词语在str中的下标,min_index_last:当前最短摘

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

题目:有搜索后的网页分词序列 数组W 其中W[0].W[1]....W[N]为分好的词. 用户输入的关键词为数组 Q 其中Q[0].Q[1]...Q[M]为搜索的关键词. 找到W中最小的范围W[i]~W[j]让其包括所有的Q. 思路: 最想当然的思路就是从W[0]开始,对每个Q遍历判断有没有一样的,截取出第一个包含Q中元素的W[i]到最后一个包括Q中元素的W[j].需要O(MN)次比较. 如果前提能够肯定W中包含所有的Q那就,先从W[0]开始找到第一个包含Q的,再从W[N-1]向前找第一个包含Q

【编程之美】目录

第1章  游戏之乐——游戏中碰到的题目 1.1 让CPU占用率听你的指挥 1.2 中国象棋将帅问题 1.3 一摞烙饼的排序 1.4 买书问题 第2章  数字之魅——数字中的技巧 2.1 求二进制中1的个数 2.2 不要被阶乘吓倒 2.3 寻找发帖"水王" 2.4 1的数目 2.5 寻找最大的K个数 2.6 精确表达浮点数 2.7 最大公约数问题 2.8 找符合条件的整数 2.9 斐波那契(Fibonacci)数列 2.10 寻找数组中的最大值和最小值 2.11 寻找最近点对 2.12

编程之美之最短摘要生成

书上给出了最短摘要的描述即算法,简单来说就是: 扫描过程始终保持一个[pBegin,pEnd]的range,初始化确保[pBegin,pEnd]的range里包含所有关键字 .然后每次迭代,尝试调整pBegin和pEnd: 1.pBegin递增,直到range无法包含所有关键字 2.pEnd递增,直到range重新包含所有关键字 计算新的range,与旧的range相比,看是否缩短了,如果是,则更新 不考虑关键字的先后顺序 .这里给出最短摘要算法的几个应用,首先是leetcode上面的两题: M

最短摘要生成

题目: Alibaba笔试题:给定一段产品的英文描述,包含M个英文字母,每个英文单词以空格分隔,无其他标点符号: 再给定N个英文单词关键 字,请说明思路并编程实现方法String extractSummary(String description,String[] key words), 目标是找出此产品描述中包含N个关键字(每个关键词至少出现一次)的长度最短的子串,作为产品简介输出.(不限编程语言)20分. 在网上看到一种用链表实现的方法,时间复杂度可以达到O(m+n).在这里实现一下. 分析

字符串----最短摘要生成

题目:Alibaba笔试题,给定一段产品的英文描述,包含M个英文单词,每个英文单词以空格分隔,无其他标点符号:再给定N个英文单词关键字,请说明思路并编程实现方法.String extractSummary(String description,String[] key words)目标是找出此产品描述中包含N个关键字(每个关键词至少出现一次)的长度最短的子串,作为产品简介输出.(不限编程语言)20分. 思路一: 直接暴力解法,循环暴力破解,每次判断关键字是否全部包含,然后不断更新边界. 思路二:

《编程之美-读书笔记》-1 中国象棋将帅问题

时间:2014.05.27 地点:基地 ---------------------------------------------------------------------------------------- 一.指针和引用的区别 1.指针可以为空,引用不可以不空. 引用是一个对象的别用,定义一个引用时必须初始化,而声名指针时可以不指向任何对象,故使用指针时也常要做空的判断,而引用无需,因为引用总是绑定着一个对象. 2.指针可以改变指向,而引用不可以重新绑定新对象.(指针变异思迁,引用从

编程之美-求二进制1的个数

一个在常见的题目,但是看到编程之美的时候才发现,方法真多,今天来总结一下: 解法一 可以举出一个八位的二进制例子来进行分析.对于一个二进制操作,我们知道,除以一个2,原来的数字将会减少一个0,如果除的过程中有余,那么就表示当前位置有一个1. 以10 100 010为例: 第一次除以2时,商为 1 010 001,余为 0. 第二次除以2时,商为 101 000,余为1. 因此可以根据整型除法的特点求解,代码如下: public int countBit1(int n) { int num = 0

编程之美-分层遍历二叉树

问题:给定一个二叉树,要求按分层遍历该二叉树,即从上到下按层次访问该二叉树(每一层将单独输出一行),每一层要求访问的顺序为从左到右,并将节点依次编号.那么分层遍历如图的二叉树,正确的输出应该为: <span style="font-size:14px;">1 2 3 4 5 6 7 8</span> 书中还给出了问题2:打印二叉树中的某层次的节点(从左到右),其中根结点为第0层,成功返回true,失败返回false 分析与解法 关于二叉树的问题,由于其本身固有的