问题描述和解题思路见此:http://www.cnblogs.com/flyinghearts/archive/2011/03/24/1994453.html。关于此问题我没什么好说的,值得一提的是请注意下面我的代码里那两个辅助函数:C++返回数组的长度;同时查找数组中的最大者和最小者。
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<string>
#include<utility> //pair
using namespace std;
const string message[]={ "微软","亚洲","研究院","成立","于","1998","年",",","我们","的","使命",
"是","使","未来","的","计算机","能够","看","、","听","、","学",",",
"能","用","自然语言","与","人类","进行","交流","。","在","此","基础","上",
",","微软","亚洲","研究院","还","将","促进","计算机","在","亚太","地区",
"的","普及",",","改善","亚太","用户","的","计算","体验","。","”"};
const int MAX=65535;
//返回数组的长度
template<typename T,size_t N>
inline size_t getsz(T (&arr)[N]){ //当参数是数组的引用时,数组长度对编译器是可见的
return N;
}
//同时找出最小者和最大者
template<typename T>
inline pair<T,T> findMinAndMax(vector<T> arr){
T min=MAX;
T max=-1;
int i=0;
int N=arr.size();
for(;i<N-1;i+=2){
//一次读入两个数,小者与min比较,大者与max比较
if(arr[i]<arr[i+1]){
if(arr[i]<min)
min=arr[i];
if(arr[i+1]>max)
max=arr[i+1];
}else{
if(arr[i+1]<min)
min=arr[i+1];
if(arr[i]>max)
max=arr[i];
}
}
if(i+1==N){
if(arr[i]<min)
min=arr[i];
if(arr[i]>max)
max=arr[i];
}
pair<T,T> p(min,max);
return p;
}
int main(int argc,char *argv[]){
//用户命令行输入关键字,存入map
map<string,int> keywords;
for(int i=1;i<argc;i++){
keywords[argv[i]]=i;
}
//创建一个数组,记录每个关键词最近一次在消息中出现的位置
vector<int> pos(argc-1);
vector<int> spos(argc-1); //记录最短摘要对应的关键词在消息中出现的位置(下标从1开始)
int slen=MAX; //记录最短摘要的长度
bool accur=false; //标记所有关键词是否已经在消息中出现过
//开始遍历消息
int len=getsz(message);
for(int i=0;i<len;i++){
int p=keywords[message[i]];
if(p==0)
continue;
pos[p-1]=i+1;
if(accur==false){
int mul=1;
for(int j=0;j<argc-1;j++){
mul*=pos[j];
if(mul==0)
break;
}
if(mul!=0)
accur=true;
}
if(accur==true){
pair<int,int> p=findMinAndMax(pos);
int ll=p.second=p.first;
if(ll<slen){
slen=ll;
spos=pos;
}
}
}
//输出结果
if(accur==false){
cout<<"没有找到包含所有关键词的消息摘要"<<endl;
return 0;
}
pair<int,int> p=findMinAndMax(spos);
for(int i=p.first-1;i<=p.second-1;i++)
cout<<message[i]<<" ";
cout<<endl;
return 0;
}