最短摘要的生成

最近在读《编程之美》,学习的过程中难免情不自禁的想coding一下,验证一下。

书上关于“最短摘要的生成”问题给出了两种解决办法。算法一实在是没什么技术含量,就不多说了。算法二中通过改变查找的起始地址减少了查找的次数,有效的降低了算法的时间复杂度。书中关于这部分的描述可以参见http://www.cnblogs.com/flyoung2008/archive/2012/04/08/2437489.html

从书中的代码参考可知:

isAllExisted()算法是在w[pBegin]-w[pEnd]区间对摘要q[]进行查找的。
pEnd起始为0,然后自增,因为pEnd一开始较小,可能小于q数组的长度,所以isAllExisted()必然返回false。如果去除pEnd的限制就可以减少isAllExisted()调用次数。
下面是我用C++实现的算法:
 
 

#include <iostream>
#include <string.h>
using namespace std;

char w[][15]=  //words数组
{
	"we",
	"are",
	"chinese",
	"we",
	"love",
	"china",
	"because",
	"china",
	"is",
	"our",
	"motherland",
	"and",
	"we",
	"live",
	"there",
	"too"
};

char k[][15]= //摘要单词数组
{
	"we",
	"love",
	"china"
};

//返回1说明找到所有摘要单词,返回0表示失败
//参数s,e为引用,用于返回找到的摘要位置,s表示最靠前的摘要单词下标,e表示最后一个摘要单词下标
//wlen为words数组长度,klen为keys数组长度
int find_summary(char w[][15],char k[][15],int wlen,int klen,int low,int &s,int &e)
{
	int i,j;

	e=low;
	s=wlen-1;

	for(i=0;i<klen;i++)
	{
		for(j=low;j<wlen;j++)
		{
			if(0==strcmp(k[i],w[j]))
			{
				s=j<s? j:s;
				e=j>e? j:e;
				break; //找到当前的摘要单词,继续查找下一个摘要单词
			}
		}
		if(j>=wlen)  //找不到当前的摘要单词,查找失败
			return 0;
	}
	return 1;  //找到所有的摘要单词,查找成功
}

int main()
{
	int wlen=sizeof(w)/sizeof(w[0]);
	int klen=sizeof(k)/sizeof(k[0]);
	

	cout<<"Words:"<<endl<<"\t";
	for(int i=0;i<wlen;i++)
			cout<<w[i]<<" ";
	cout<<endl;

	cout<<"Kyes:"<<endl<<"\t";
	for(i=0;i<klen;i++)
			cout<<k[i]<<" ";
	cout<<endl;

	cout<<"find:"<<endl;
	int targetLen = wlen+1;  //用于保存最短摘要长度
	int targetStart = -1;	 //用于保存最短摘要起始位置
	int targetEnd = -1;		 //用于保存最短摘要结束位置

	int s,e;
	int low=0;
	while(find_summary(w,k,wlen,klen,low,s,e))   //从low位置开始查找摘要
	{
		cout<<"\t";
		for(i=s;i<=e;i++)
			cout<<w[i]<<" ";
		cout<<endl;

		if(e-s+1<targetLen)
		{
			targetLen = e-s+1;
			targetStart = s;
			targetEnd = e;
		}
		low = s+1;  //下一次查找的起始位置为s+1
	}

	cout<<"Best:"<<endl;
	cout<<"\tLength: "<<targetLen<<"\tStart: "<<targetStart<<"\tEnd:"<<targetEnd<<endl;
	return 0;
}

输出结果:


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值