关于深搜。。

最近参加了一些实习的考试,发现其实很多企业对实习生的要求就是基础吗。基础就包括程序设计、算法、数据结构、操作系统之类的。

所以现在对自己学习过的东西进行一个汇总吧。

今天讲的深搜。

今天看了编程之美的一个题目:计算字符串的相似度。

比如说aabbc 和aabb吧,这两个字符串的距离就是1,因为只要将第一个字符的最后一个字符删除掉了(或者给第二个字符串添加一个字符),就跟第二个字符串相同,因此距离是1.

另外,abc和adc,这两个字符串的距离也是1,因为只有中间的字符是不同的。因此,总结,通过添加、删除、更换,就能够将两个字符串变成相同的。所以我们可以将这个问题抽象成一个模型:每一轮迭代中,我们判断两个字符串的当前字符是否相同,如果相同,则字符串的距离不需要加1,然后比较下一个字符;如果不相同,则可以通过上述三个操作操作两个字符串咯。而我们可以看出来,其实删除和添加是一对逆过程,所以就只需要做一个就好了,这里就做删除操作,因为具体操作起来比较方便。但是删除的话就有分删哪一个字符串的问题,因此,在下一论迭代中,就有三种情况。

1:同时删掉当前两个字符串不相同的字符。

2:删掉第一个字符串的字符,用剩下的和第二个字符串比较。

3:删掉第二个字符串的字符,用剩下的和第一个字符串比较。

那么现在很清楚啦,整个遍历就是一棵树,遍历树的方法无非就是广搜和深搜,而本题不需要求最短路径什么的,就直接用深搜,然后记录每次的距离,再求出最短距离即可。

但现在有一个问题,在上面我们可以看出,这个算法的时间的复杂度是3^n次方,n由两个字符串的长度决定。所以这是一个很吓人的现实,那么有没有办法能够降低这个开销呢?答案是有的。如果我们深入一点考虑,就会发现整个遍历的过程有很多地方是重复的,这怎么说呢?比如说我们现在剩下需要比较的字符串是ab和ba,而到达这个状况可能的路径就有好几条:比如说2+3或者是1+1,所以我们能够预先记录起来暂时计算出来的结果,则可以直接使用了。用数组就能够做到鸟!!


上代码:

#include<iostream>
#include<string>
#include<cstring>
using namespace std;

const int maxLength = 100;
int visited[maxLength][maxLength];
int calculate(string a, string b, int head1, int head2);
int minValue(int t1, int t2, int t3);

int main(){
	string s1, s2;
	while(cin >> s1 >> s2){
		memset(visited, -1, sizeof(visited));
		cout << calculate(s1, s2, 0, 0) << endl;
	}
}

int minValue(int t1, int t2, int t3){
	int temp = t1 < t2 ? t1 : t2;
	return temp < t3 ? temp : t3;
}

int calculate(string a, string b, int head1, int head2){
	if(head1 == a.length()){
		if(head2 < b.length())
			visited[head1][head2] = b.length() - head2;
		else
			visited[head1][head2] = 0;
		return visited[head1][head2];
	}
	if(head2 == b.length()){
		if(head1 < a.length())
			visited[head1][head2] = a.length() - head1;
		else
			visited[head1][head2] = 0;
		return visited[head1][head2];
	}
	if(a[head1] == b[head2])
		return visited[head1][head2] == -1 ? calculate(a, b, head1+1, head2+1) : visited[head1][head2];
	else{
		int d1, d2, d3;
		d1 = visited[head1+1][head2] == -1 ? calculate(a, b, head1+1, head2) : visited[head1+1][head2];
		d2 = visited[head1][head2+1] == -1 ? calculate(a, b, head1, head2+1) : visited[head1][head2+1];
		d3 = visited[head1+1][head2+1] == -1 ? calculate(a, b, head1+1, head2+1) : visited[head1+1][head2+1];
		return minValue(d1, d2, d3) + 1;
	}
}

思考完这个问题以后,我想到http://soj.me/1176,这个问题跟上述问题很相像,都可以通过深搜+数组记录中间过程来解决。

加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值