编程之美--最短摘要

其中借鉴了网上的滑动窗口思想,效率比编程之美高!

#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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值