广度优先搜索——字符串替换

经典的字符串转换问题:http://codevs.cn/problem/1099/

昨天刚学了广度搜索,今天就用上了,一开始百度了一下,看到所有人都是在用双向广度搜索,现在还是很不明白双向的原理,居然不需要判重!!!速度快这个容易理解,好吧,骚年加油,今天ccf认证考试,明天再来学双向的!

首先说说这个吧,广度搜索最关键的还是这两个点:

1. 如何建立搜索树?

2. 如何判断状态重复?

第一,每个结点的状态如何延伸呢?在这个问题里,当然是字符串的查找,每找到一个可以被替换的位置,那么就是一个可延伸的状态了。一开始我逗比,每次只查找了一次,后来wa了一下,定睛一看,原来是忽略了串中有多个可以被替换的情况,这些可替换的位置,也是需要被延伸的状态,所以就加了一个while循环,一切搞定!!!

第二,如何判断结点重复呢?字符串hash化我怕会出错,所以就用了一个set来存储状态!set就不用多说了吧……

一些细节:

1. 要注意题中的规则输入的可能是多个目标,比如abc->def,abd->123之类的,我一开始用map存储这些规则,然后当然就出错啦,解决办法简单的就是使用multimap,multimap的插入,删除和查找都与map相似,都又有所不同,比如插入不可以用下标来做,而是需要用insert成员函数!删除则是删除所有关键字相同的元素,查找时若找到,只返回同个关键字中的第一个的迭代器……

2. state数组是用来存储状态的(因为set会自动排序,会打乱要计算的状态的顺序,所以得用多一个数组来存储)。那么数组的大小怎么确定呢?我还不会计算……最后第二次提交时爆了,,,,改大一点就好了……哎,数学方面也得跟上来呀,不能只学算法思想!

#include <iostream>
#include <string>
#include <map>
#include <set>
using namespace std;

string goal;
multimap<string, string> M;
map<string, int> N;
set<string> col;
const int Max = 900000;	//?how many
string state[Max];

void Init();
int bfs();

int main(){
	Init();
	int ans = bfs();
	if(ans == -1) cout << "NO ANSWER!" << endl;
	else cout << ans << endl;

	return 0;
}

void Init(){
	cin >> state[0] >> goal;
	string p, q;
	while(cin >> p >> q)
		M.insert(make_pair(p, q));
}
int bfs(){
	int head = 0, tail = 1;
	size_t pos;
	N[state[head]] = 0;
	map<string, string>::iterator it;

	while(head < tail){
		if(N[state[head]] > 10){
			++head;
			continue;
		}
		if(state[head] == goal){
			if(N[goal] > 10) return -1;
			return N[goal];
		}

		for(it=M.begin(); it!=M.end(); ++it){
			state[tail] = state[head];
			pos = state[tail].find(it->first);
			while(pos != string::npos){
				state[tail].replace(pos, it->first.size(), it->second);
				if(col.find(state[tail]) == col.end()){
					col.insert(state[tail]);
					N[state[tail]] = N[state[head]] + 1;
					++tail;
				}
				state[tail] = state[head];
				pos = state[tail].find(it->first, pos+it->first.size());
			}
		}
		++head;
	}
	return -1;
}
时间: 2024-10-11 15:40:42

广度优先搜索——字符串替换的相关文章

JS使用replace()方法和正则表达式进行字符串的搜索与替换实例

1.JS字符串的替换及replace()方法的使用 replace(regexp,replacement)方法有两个参数,第一参数可以是一个纯文本字符串或是一个RegExp对象,具体请看RegExp对象的使用:第二个参数可是一个字符串也可以是一个函数. 以下是JS字符串替换的举例: 例1: var str="Hello world!"; document.write(str.replace(/world/, "phper")); 例2: var reg=new Re

字符串忽略大小写的搜索和替换

需求:字符串忽略大小写搜索和替换 解决: 使用re.IGNORECASE import re text = 'UPPER PYTHON, lower python, Mixed Python' f = re.findall("python", text, flags=re.IGNORECASE) print(f) s, n = re.subn("python","snake",text, flags=re.IGNORECASE) print(s)

43 正则中用sub和subn函数搜索与替换 使用split函数分隔字符串 练习题

第10课 正则中用sub和subn函数搜索与替换 # 使用sub和subn函数搜索和替换 ''' sub(正则表达式,要替换的字符串,母字符串) ''' import re result = re.sub('Bill','Mike', 'Bill is my son.') print(result) # Mike is my son. 把Bill 替换成 Mike result = re.subn('Bill', 'Mike', 'Bill is my son, I like Bill') pr

str_replace字符串替换

字符串替换, src 源字符串, buf_size 缓冲大小, search搜索的字符串大小, repstr 需要替换成的字符串 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

ACM题目————图的广度优先搜索

题目描述 图的广度优先搜索类似于树的按层次遍历,即从某个结点开始,先访问该结点,然后访问该结点的所有邻接点,再依次访问各邻接 点的邻接点.如此进行下去,直到所有的结点都访问为止.在该题中,假定所有的结点以“A”--“Z”中的若干字符表示,且要求结点的访问顺序要求根据由 “A”至“Z”的字典顺序进行访问. 输入 输入只包含一个测试用例,第一行为一个自然数n,表示顶点的个数,第二行为n个大写字母构成的字符串,表示顶点,接下来是为一个n*n大小的矩阵,表示图的邻接关系.数字为0表示不邻接,否则为相应的

[C++]广度优先搜索(BFS)(附例题)

广度优先搜索(BFS)(附例题) 问题产生: Isenbaev是国外的一个大牛. 现在有许多人要参加ACM ICPC. 一共有n个组,每组3个人.同组的3个人都是队友. 大家都想知道自己与大牛的最小距离是多少. 大牛与自己的最小距离当然是0.大牛的队友和大牛的最小距离是1.大牛的队友的队友和大牛的最小距离是2--以此类推. 如果实在和大牛没有关系的只好输出undefined了. 第一行读入n.表示有n个组.1 ≤ n ≤ 100 接下来n行,每行有3个名字,名字之间用空格隔开.每个名字的开头都是

【java解惑】java字符串替换方法使用

    如下代码: public class Example020 { public static void main(String[] args) { String separator = File.separator; String clazzName = Example020.class.getName(); String rs1 = clazzName.replace(".", separator); // 方法1 String rs2 = clazzName.replaceA

基于深度及广度优先搜索的迷宫问题的演示

1 时间复杂度分析 由于该图采用邻接矩阵存储,整个算法遍历的过程所花费的时间复杂度为该矩阵的N(row*col).而由于其需要分别访问已经定位,需要进行分别2次操作,如下: visited = new bool[col*row];//访问标记 for (i=0; i<row; i++) for (j=0; j<col; j++) visited[i*col+j] = false;//初始为未访问状态 position = new POSITION[col*row]; for (i=0; i&l

【转载】vim字符串替换

转自http://bbs.chinaunix.net/thread-2045191-1-1.html vi/vim 中可以使用 :s 命令来替换字符串.以前只会使用一种格式来全文替换,今天发现该命令有很多种写法(vi 真是强大啊,还有很多需要学习),记录几种在此,方便以后查询. :s/vivian/sky/ 替换当前行第一个 vivian 为 sky :s/vivian/sky/g 替换当前行所有 vivian 为 sky :n,$s/vivian/sky/ 替换第 n 行开始到最后一行中每一行