[CareerCup 8.4] 求一个字符串的全排列

Write a method to compute all permutations of a string.

翻译:写一个计算一个字符串所有排列的算法。

 

[方法1] 递归的方法

首先字符串分为a[0,1,...,n-2]和a[n-1]两部分,
然后将递归求解a[0,1,...,n-2]的所有排列,
最后将a[n-1]插入到a[0,1,...,n-2]的所有排列中去(注意一共有n个插入点)

代码如下:

/**
递归解法
首先字符串分为a[0,1,...,n-2]和a[n-1]两部分,
然后将递归求解a[0,1,...,n-2]的所有排列,
最后将a[n-1]插入到a[0,1,...,n-2]的所有排列中去(注意一共有n个插入点)
**/
vector permutate(string s)
{
	vector v;
	if (s.size() == 1)
		v.push_back(s);
	else
	{
		string a = s.substr(s.size() - 1, 1);
		string t = s.substr(0, s.size() - 1);
		vector vt = permutate(t);
		for (vector::iterator it = vt.begin(); it != vt.end(); it++)
		{
			for (int i = 0; i <= it->size(); i++)
			{
				string tmp = *it;
				tmp.insert(i, a);
				v.push_back(tmp);
			}
		}
	}
	return v;
}

[方法2] 迭代的方法

首先将首字符加入到集合中,然后将后边的字符一个一个加入
每个字符加入时,插入到每个已经在集合中的字符串中,并将插入得到的字符串加入到集合中
没插入完一个字符串后,将其删除
但没有当前大小的字符串时,进入下一轮循环

代码如下:

/**
循环解法
首先将首字符加入到集合中,然后将后边的字符一个一个加入
每个字符加入时,插入到每个已经在集合中的字符串中,并将插入得到的字符串加入到集合中
没插入完一个字符串后,将其删除
但没有当前大小的字符串时,进入下一轮循环
**/
vector permutate_loop(string s)
{
	vector v;
	for (int i = 0; i < s.size(); i++)
	{
		string a = s.substr(i, 1);
		if (v.empty())
			v.push_back(a);
		else
		{
			while (v.begin()->size() < i + 1)
			{
				string fr = *v.begin();
				for (int j = 0; j <= fr.size(); j++)
				{
					string tmp(fr);
					tmp.insert(j, a);
					v.push_back(tmp);
				}
				v.erase(v.begin());
			}
		}
	}
	return v;
}

测试代码:

/**
测试代码
**/
int main()
{
	string s;
	while (cin>>s)
	{
		cout< v = permutate_loop(s);
		for (vector::iterator it = v.begin(); it != v.end(); it++)
			cout << *it << endl;
		cout << endl;
	}
	return 0;
}

posted on 2011-12-22 22:41  小橋流水  阅读(249)  评论(0编辑  收藏  举报

导航