给定一段产品的英文描述,每个英文单词以空格分隔,无其他标点符号;再给定N个英文单词关键字,请编程实现一个方法,目标是找出此产品描述中包含N个关键字(每个关键词至少出现一次)的长度最短的子串,作为产品简介输出
代码如下:
/*
算法思想:从头扫描输入字符串,找到第一个在关键字中出现的单词
记录其偏移量,继续往后扫描得到出现在关键字中的第二个单词(可以
和第一个相同),一直到此子串包含所有的关键字,此时也需要记录
其偏移量,计算其大小;接下来继续从以上子串中的第二个被找到的关键字
开始扫描.....一直到结束,最后选出距离最小的子串。重要数据结构是:
record 结构
*/
#include <iostream>
#include <cstring>
using namespace std;
const int size = 30;
const int INF = 100000;
struct record{
int begin; // 摘要开始的偏移值
int end; // 摘要结尾的偏移值
int dis; // 摘要的长度
int second; // 摘要中第二个关键词的偏移
}rec[size]; // 记录获得的每个摘要的信息
// 子例程,判断两个单词是否相同
bool isEqual(char* f, char* s){
while(*f != '\0' && *s != '\0'){
if(*f++ != *s++)
break;
}
if(*f == '\0' && *s == '\0')
return true;
else
return false;
}
// 子例程,检查查找到了多少个关键字
int check(int* trace, int len){
int count = 0;
for(int i = 0; i < len; i++){
if(trace[i] == 1)
count++;
}
return count;
}
// cont: 字符串内容
// key: 关键字数组
// len: 关键字个数
void summary(char* cont, char* key[], int len){
// 临时存放读入的每个单词
char tmp[size];
// 跟踪摘要是否包含了所有关键字
int trace[size] = {0};
int i = 0, t = 0, count = 0, k;
bool flag = false;
while(true){
if(!flag){
memset(tmp, '\0', sizeof(tmp));
for(k = 0 ; *(cont+i) != ' ' && *(cont+i) != '\0'; i++){
tmp[k++] = *(cont+i);
}
for(int j = 0; j < len; j++){
if(isEqual(tmp, key[j])){
trace[j] = 1;
// 记录找到关键字的个数 ,注意:这里的个数包括
// 重复的关键字;要想得到不包括重复的已找到关键字
// 个数需要用 check()函数
count++;
if(count == 1){
rec[t].begin = i - k;
}
if(count == 2){
rec[t].second = i - k; // 使寻找第二个摘要时提高效率
}
if(check(trace, len) == len){
rec[t].end = i;
rec[t].dis = rec[t].end - rec[t].begin;
++t;
flag = true;
}
}
}
if(*(cont+i) == '\0')
break;
// 跳过空格
++i;
}
else{
count = 0;
memset(trace, 0, sizeof(trace));
i = rec[t-1].second;
flag = false;
}
}
int min = INF;
int indx;
for(i = 0; i < t; i++){
if(rec[i].dis < min){
min = rec[i].dis;
indx = i;
}
}
for(i = rec[indx].begin; i <= rec[indx].begin +rec[indx].dis; i++){
cout << *(cont+i);
}
cout << endl;
}
int main(int argc, char* argv[])
{
char* cont = "my love love shi zhang see lk yes she very love ta my zhang";
char* key[] = {"love", "zhang", "my"};
summary(cont, key, 3);
return 0;
}