其中借鉴了网上的滑动窗口思想,效率比编程之美高!
#include <map>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
class current_abstract
{
public:
current_abstract(const std::vector<std::string>& key_words)
:is_contained(false)
{
std::for_each(key_words.begin(),key_words.end(),
[&](const std::string& key_word)
{
count.insert(std::make_pair(key_word,0));
}
);
}
bool is_contained_all(const std::string& word,bool sig)
{
if(count.find(word)==count.end()) //non key words
{
return is_contained;
}
if(sig)//add key_word to current_abstract //mainly for "++pend_pos"
{
++count[word];
}
else //remove key_word to current_abstract //mainly for "++pbegin_pos"
{
--count[word];
}
if([&]()->bool{ //traverse
for(auto& index:count)
{
if(index.second<=0) //not contains all
{
return false;
}
}
return true; //contains all
}()
)
{
is_contained=true; //contains all
}
else
{
is_contained=false; //not contains all
}
return is_contained;
}
private:
bool is_contained;
std::map<std::string,int> count;
};
std::vector<std::string> shortest_abstract(const std::vector<std::string> content,
std::vector<std::string> key_words)
{
//std::vector<std::string> abstract;
auto shortest_begin=content.end();
auto shortest_end=content.end();
if(content.size()==0 || key_words.size()==0)
return std::vector<std::string>();
current_abstract cur_abs(key_words);
auto pbegin_pos=content.begin();
auto pend_pos=content.begin();
int cur_min=content.size();
while(pend_pos!=content.end())
{
if(!cur_abs.is_contained_all(*pend_pos,true))
{
++pend_pos;
continue;
}
while(pbegin_pos<=pend_pos && cur_abs.is_contained_all(*pbegin_pos,false)) //remove ++pbegin_pos
{
++pbegin_pos;
}
if(pend_pos-pbegin_pos+1 < cur_min)
{
cur_min=pend_pos-pbegin_pos+1;
shortest_end=pend_pos;
shortest_begin=pbegin_pos;
}
++pbegin_pos;
++pend_pos;
}
return std::vector<std::string>(shortest_begin,shortest_end+1);
}
int main(int argc,char* argv[])
{
std::string con[]={"hello","software","hello","test","sahal",
"world","spring","sun","world","flower","hello","test"
};
std::string kws[]={"hello","world"};
std::vector<std::string> content(con,con+11);
std::vector<std::string> key_words(kws,kws+2);
//vector<string> abstract=move(shortest_abstract(content,key_words));
std::vector<std::string> abstract=shortest_abstract(content,key_words);
std::for_each(abstract.begin(),abstract.end(),
[](const std::string& str)
{
std::cout<<"==>"<<str;
}
);
std::cout<<std::endl;
return 0;
}
g++ -g -Wall -std=c++11 shortest_abstract.cpp