最短摘要生成

题目:抽象点说,就是在一个字符串中,找一些目标字符串,找到包含所有目标字符串的最小字符串。题目虽然叫做最短摘要生成,但和实际的搜索snippet的计算还是有比较大的差距的。

解法:使用双指针,双指针对于很多算法设计很有价值。

算法的思想是采用两个指针,开始两个指针都指向缓冲区的头部,尾指针向后扫描,直到头指针和尾指针中间包含了全部的关键字,那么头指针向后移动,直到包含全部关键字这个条件失败,这时截取字串并和已取得的最小字串比较,如果小则替换。头指针、尾指针都向后一个位置(这点很重要,开始就忘记了移动头指针,导致程序出错),继续扫描。

另外,由于一个关键字可能重复多次,因此在判断是否包含全部关键字时要采用计数机制,才能保证查看的准确。这样只要头指针和尾指针扫描两次字符串就可以完成生成算法。

具体代码如下:

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <string>  
  3. #include <map>  
  4. class KeyWordChecker {  
  5.  public:  
  6.   KeyWordChecker() : current_state_(false) {}  
  7.   void AddKeyWord(const std::string& word) {  
  8.     if (keywords_.find(word) == keywords_.end()) {        
  9.       keywords_[word] = 0;  
  10.     }  
  11.   }  
  12.   bool IsContainAllKeyWord(const std::string& word, bool add) {  
  13.     if (keywords_.find(word) == keywords_.end()) {  
  14.       return current_state_;  
  15.     }  
  16.     if (add) {  
  17.       keywords_[word]++;  
  18.     } else {  
  19.       keywords_[word]--;  
  20.     }  
  21.     std::map<std::string, int>::iterator begin = keywords_.begin();  
  22.     int counter = 0;  
  23.     while (begin != keywords_.end()) {  
  24.       if (begin->second > 0) {  
  25.         counter++;  
  26.       } else {  
  27.         break;  
  28.       }  
  29.       begin++;  
  30.     }  
  31.     if (counter == keywords_.size()) {  
  32.       current_state_ = true;  
  33.       return true;  
  34.     } else {  
  35.       current_state_ = false;  
  36.       return false;  
  37.     }  
  38.   }  
  39.  private:  
  40.   std::map<std::string, int> keywords_;  
  41.   bool current_state_;  
  42. };  
  43.   
  44. std::string GenerateSnippet(const std::string& content, KeyWordChecker* keyword_checker) {  
  45.   int begin = 0;  
  46.   int end = 0;  
  47.   std::string snippet;  
  48.   int min_length = content.size();  
  49.   while (end < content.size()) {  
  50.     if (!keyword_checker->IsContainAllKeyWord(std::string(1, content[end]), true)) {  
  51.        end++;  
  52.        continue;  
  53.     }  
  54.     while (begin <= end && keyword_checker->IsContainAllKeyWord(std::string(1, content[begin]), false)) {  
  55.       begin++;  
  56.     }  
  57.     if (end - begin + 1 < min_length) {  
  58.       snippet = content.substr(begin, end - begin + 1);  
  59.       min_length = end - begin + 1;  
  60.     }  
  61.     end++;  
  62.     begin++;  
  63.   }    
  64.   return snippet;  
  65. }  
  66. int main(int argc, char** argv) {  
  67.   std::string content = "abbbbbcaaadebmmmmdcfg";  
  68.   KeyWordChecker keyword_checker;  
  69.   keyword_checker.AddKeyWord("b");  
  70.   keyword_checker.AddKeyWord("d");  
  71.   std::string snippet = GenerateSnippet(content, &keyword_checker);  
  72.   printf("snippet:%s\n", snippet.c_str());  
  73. }  


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值