最短摘要生成

題目:抽象點說,就是在一個字符串中,找一些目標字符串,找到包含所有目標字符串的最小字符串。題目雖然叫做最短摘要生成,但和實際的搜索snippet的計算還是有比較大的差距的。

解法:文獻[1]給出了一種比較好的解法,策略還是使用雙指針,雙指針對於很多算法設計很有價值,算法的思想是採用兩個指針,開始兩個指針都指向緩衝區的頭部,尾指針向後掃描,直到頭指針和尾指針中間包含了全部的關鍵字,那麼頭指針向後移動,直到包含全部關鍵字這個條件失敗,這時截取字串並和已取得的最小字串比較,如果小則替換。頭指針、尾指針都向後一個位置(這點很重要,開始就忘記了移動頭指針,導致程序出錯),繼續掃描。另外,由於一個關鍵字可能重複多次,因此在判斷是否包含全部關鍵字時要採用計數機制,才能保證查看的準確。這樣只要頭指針和尾指針掃描兩次字符串就可以完成生成算法。

具體代碼如下:

#include <stdio.h>
#include <string>
#include <map>
class KeyWordChecker {
 public:
  KeyWordChecker() : current_state_(false) {}
  void AddKeyWord(const std::string& word) {
    if (keywords_.find(word) == keywords_.end()) {      
      keywords_[word] = 0;
    }
  }
  bool IsContainAllKeyWord(const std::string& word, bool add) {
    if (keywords_.find(word) == keywords_.end()) {
      return current_state_;
    }
    if (add) {
      keywords_[word]++;
    } else {
      keywords_[word]--;
    }
    std::map<std::string, int>::iterator begin = keywords_.begin();
    int counter = 0;
    while (begin != keywords_.end()) {
      if (begin->second > 0) {
        counter++;
      } else {
        break;
      }
      begin++;
    }
    if (counter == keywords_.size()) {
      current_state_ = true;
      return true;
    } else {
      current_state_ = false;
      return false;
    }
  }
 private:
  std::map<std::string, int> keywords_;
  bool current_state_;
};

std::string GenerateSnippet(const std::string& content, KeyWordChecker* keyword_checker) {
  int begin = 0;
  int end = 0;
  std::string snippet;
  int min_length = content.size();
  while (end < content.size()) {
    if (!keyword_checker->IsContainAllKeyWord(std::string(1, content[end]), true)) {
       end++;
       continue;
    }
    while (begin <= end && keyword_checker->IsContainAllKeyWord(std::string(1, content[begin]), false)) {
      begin++;
    }
    if (end - begin + 1 < min_length) {
      snippet = content.substr(begin, end - begin + 1);
      min_length = end - begin + 1;
    }
    end++;
    begin++;
  }  
  return snippet;
}
int main(int argc, char** argv) {
  std::string content = "abbbbbcaaadebmmmmdcfg";
  KeyWordChecker keyword_checker;
  keyword_checker.AddKeyWord("b");
  keyword_checker.AddKeyWord("d");
  std::string snippet = GenerateSnippet(content, &keyword_checker);
  printf("snippet:%s\n", snippet.c_str());
}



參考文獻:

編程之美3.5

發佈了82 篇原創文章 · 獲贊 3 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章