3.5 最短摘要的声成

题目:

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

这题跟书上3.5差不多意思的题目。

思路解法:

  先来看看这些序列:

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的序列,并且找出其中的最小值,就可得到最终的结果。

代码:

#include <iostream>
#include <string>
#include <set>

using namespace std;

string context;
string query;
int targetBegin = 0;        //最后目标摘要的首指针
int targetEnd = 0;          //最后目标摘要的尾指针
int pBegin = 0, pEnd = 0;     //首尾循环指针

bool isAllExist(int &pBegin, int &pEnd) {
    set<char> s;
    for(int i = pBegin; i < pEnd; ++i) {
        s.insert(context[i]);
    }
    int length_of_query = query.length();
    for(int i = 0; i < length_of_query; ++i) {
        if(s.find(query[i]) == s.end()) return false;
    }
    return true;
}

int main() {
    cin >> context >> query;
    int n = context.length();
    int targetLength = n+1;       //最后目标摘要的总长度
    while(true) {
        while(!isAllExist(pBegin, pEnd) && pEnd < n) pEnd++;
        while(isAllExist(pBegin, pEnd)) {
            if(pEnd - pBegin < targetLength) {
                targetLength = pEnd - pBegin;
                targetBegin = pBegin;
                targetEnd = pEnd - 1;
            }
            pBegin++;
        }
        if(pEnd >= n) break;
    }
    for(int i = targetBegin; i <= targetEnd; ++i) cout << context[i];
    cout << endl;
    return 0;
}
时间: 2024-07-29 23:37:13

3.5 最短摘要的声成的相关文章

编程之美-最短摘要

这个主要注意几点:首先,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:当前最短摘

最短摘要生成

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

最短摘要问题

/* 最短摘要问题,给一定字符串序列 wo,w1,w2,w3,op1,w4,op2,w5,op1,w6,w7,op1,op2,指定关键字符串为op1,op2,求包含关键字的最小字符串序列. 常见于搜索引擎的分词,op1,op2这里没有顺序,否则就更复杂了,最短序列为op1,op2. 思路: (1)第一次扫描要包含全部关键词,送wo扫描到op2,即w0,w1,w2,w3,op1,w4,op2,随后左边逐渐缩小,知道第一次不全包含关键字为止(在扫描时候 就记录最短的),即w4,op2.此时移动右面知

编程之美之最短摘要生成

书上给出了最短摘要的描述即算法,简单来说就是: 扫描过程始终保持一个[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分. 思路一: 直接暴力解法,循环暴力破解,每次判断关键字是否全部包含,然后不断更新边界. 思路二:

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

题意:假设给定的已经是经过网页分词之后的结果,词语序列数组为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

【编程之美】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

MD5摘要(Java实现)

消息摘要算法又成散列算法,其核心在于散列函数的单向性.即通过散列函数可获得对应的散列值,但不可以通过散列值反推其原始信息. 消息摘要算法分为以下三大类: MD(Message Digest ,消息摘要) SHA(Secure Hash Algorithm ,安全散列算法) MAC(Message Authentication Code ,消息认证码) 本篇文章仅说明MD5算法 MD系列算法包括MD2.MD4.MD5这三种算法 MD系统的消息摘要算法都产生128位的消息摘要,转换成16进制之后就是

c++面试题【转】

语言部分: 虚函数,多态.这个概念几乎是必问. STL的使用和背后数据结构,vector string map set 和hash_map,hash_set 实现一个栈类,类似STL中的栈.这个题目初看非常简单,当时我还有点不屑,怎么出这么简单的题.但写过c++和没有写过c++的人写出的代码是一眼就能看出差别的.譬如三大函数有没有写,引用的使用,都非常的关键.如果这方面没有经验,建议阅读下http://book.douban.com/subject/1971825/ 这本书中简单数据结构的实现,