您的位置:首页 > 其它

每日一题(66) - 字符串的排列

2013-08-08 20:47 169 查看
题目来自剑指offer

题目(1):集合元素的全排列,只处理数字全不同的情况



思路:全排列属于线性递归,递归一次确定一个位置的数据,直到所有位置全被处理为止。

注意:

(1)在确定一个位置时,由于该位置的数据有多种,因此需要使用for循环。

(2)程序里面没有使用临时数组,而是通过数组元素交换的方式获得该位置的数据的。

(3)在确定一个位置时,待交换数据的起点是从该位置开始,一直到数组结束。

代码:

#include <iostream>
using namespace std;

void Swap(int& a,int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

void Perm(int nArr[],int nLen,int nStart)
{
	if (nStart == nLen)
	{
		for (int i = 0;i < nLen;i++)
		{
			cout<<nArr[i];
		}
		cout<<endl;
	}
	for (int i = nStart;i < nLen;i++)
	{
		Swap(nArr[i],nArr[nStart]);		
		Perm(nArr,nLen,nStart + 1);
		Swap(nArr[i],nArr[nStart]);
	}
}

int main()
{
	int nLen = 3;
	int nArr[3] = {1,2,3};
	Perm(nArr,nLen,0);
	system("pause");
	return 1;
}


题目(2):集合元素的组合,只处理数字全不同的情况



思路(1):

代码:

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

void Swap(int& a,int &b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

void Combine(int nArr[],int nLen,int nStart,int nNext,int nCount)
{
	if (nCount == nStart)
	{
		for (int i = 0;i < nStart;i++)
		{
			cout<<nArr[i];
		}
		cout<<endl;
		return;
	}
	for (int i = nNext;i < nLen;i++)
	{
		Swap(nArr[nStart],nArr[i]); //第nStart个位置放第i个数
		Combine(nArr,nLen,nStart + 1,i + 1,nCount);//第nStart + 1 就从第i+1个数开始取。
		Swap(nArr[nStart],nArr[i]);
	}
}

void Combine(int nArr[],int nLen)
{
	for (int nCount = 1;nCount <= nLen;nCount++)
	{
		Combine(nArr,nLen,0,0,nCount);
	}
}

int main()
{
	int nLen = 3;
	int nArr[3] = {1,2,3};
	Combine(nArr,nLen);
	system("pause");
	return 1;
}

思路(2):

代码:

#include <iostream>
#include <vector>
using namespace std;

void Print(vector<int>& nVector)
{
	vector<int>::iterator itCur;
	for (itCur = nVector.begin();itCur != nVector.end();itCur++)
	{
		cout<<*itCur;
	}
	cout<<endl;
}

void Combine(int nArr[],int nLen,int nStart,vector<int>& nResult,int nCount)
{
	if (nStart >= nLen && nResult.size() != nCount)
	{
		return;
	}

	if (nCount == nResult.size())
	{
		Print(nResult);
		return;
	}
		
	nResult.push_back(nArr[nStart]);
	Combine(nArr,nLen,nStart + 1,nResult,nCount);
	nResult.pop_back();
	Combine(nArr,nLen,nStart + 1,nResult,nCount);
}

void Combine(int nArr[],int nLen)
{
	vector<int> nResult;
	for (int nCount = 1;nCount <= nLen;nCount++)
	{
		Combine(nArr,nLen,0,nResult,nCount);
	}
}

int main()
{
	int nLen = 3;
	int nArr[3] = {1,2,3};
	Combine(nArr,nLen);
	system("pause");
	return 1;
}
思路(3):

代码:

#include <iostream>
using namespace std;

void Swap(int& a,int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

void Combine(int nArr[],int nLen,int nStart,int nNext)
{
	if (nStart > 0)
	{
		for (int i = 0;i < nStart;i++)
		{
			cout<<nArr[i];
		}
		cout<<endl;
	}
	for (int i = nNext;i < nLen;i++)
	{
		Swap(nArr[nStart],nArr[i]);
		Combine(nArr,nLen,nStart + 1,i + 1);//此次,确定第nStart个位置使用的第i个元素,之后确定下一个元素时,使用的元素区间是[i + 1,nLen - 1];
		Swap(nArr[nStart],nArr[i]);
	}
}

int main()
{
	int nLen = 3;
	int nArr[3] = {1,2,3};
	Combine(nArr,nLen,0,0);
	system("pause");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: