排列组合(二)

关于排列组合算法有个总结的链接是http://blog.csdn.net/gningh/article/details/8209481这是对前面交换法和字典序法的实现。交换法的非递归实现目前还有些问题,自己没有找到,希望高手路过的可以纠正下。

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;

typedef int T;
class FullArray
{
public:
	typedef   vector<T>::iterator    Iter;
	typedef   vector<T>::reverse_iterator   R_Iter;

	FullArray(void)  {};
  ~FullArray(void) {};
  int intial( const T*, const size_t);  //使用数组初始化vector
  void DictionaryOrder();  //字典序法
  void ExchangeOrder();   //换位法
  void print();    
  void reverse( Iter, Iter );  //翻转位置

private:
	int  Factorial(int );   //求一个自然数的阶乘,为ExchangeOrder调用
	void Swap( R_Iter , R_Iter  );   //交换反向迭代器指向的数
	void Swap( Iter, Iter);         //重载Swap,交换正向迭代器指向的数

private:
	vector<T> m_vSque;    //将要进行全排列的序列,用vector保存
};

int FullArray::Factorial(int a)
{
	if ( a < 2 ) return 1;
	else return a*Factorial( a-1 );
}
void FullArray::reverse( Iter iterBeg, Iter iterEnd)
{
	while(iterBeg < iterEnd)  
		Swap(iterBeg++ , iterEnd--);
	
}
int FullArray::intial(const T *arr, const size_t arr_size)
{
	if ( !arr || !arr_size) return 1;
	
	for ( size_t i = 0; i < arr_size; ++i )
	{
		m_vSque.push_back(arr[i]);
	}

	return 0;
}

void FullArray::Swap( R_Iter iter1, R_Iter iter2 )
{
	T tmp;
	tmp = *iter1;
	*iter1 = *iter2;
	*iter2 = tmp;
}

void FullArray::Swap( Iter iter1, Iter iter2 )
{
	T tmp;
	tmp = *iter1;
	*iter1 = *iter2;
	*iter2 = tmp;
}

void FullArray::print()
{
	Iter iterBeg = m_vSque.begin(),
		    iterEnd = m_vSque.end();
	while (iterBeg != iterEnd)
	{
		cout<<*iterBeg<<" ";
		++iterBeg;
	}
	cout<<endl;
}

void FullArray::DictionaryOrder()
{
	bool flag = false;  // 判断是否结束
	Iter tempI ;    //交换位置
	Iter tempH;   //比交换位置大的最小数

	 Iter  iterEnd = m_vSque.end();

	 while( flag== false)
	{
		print();
		Iter iterBeg = m_vSque.begin();

	    while( ( iterBeg +1 )!= iterEnd)
		{
			if (*iterBeg< *(iterBeg+1))
		   {
			   flag = true;
			   tempI = iterBeg;
		   }
		   ++iterBeg;
	   }


	if ( flag == false)  return;

	Iter tmp = tempI;
	int tmpMax = 10000;   //假设为最大的值

	while ( tmp != iterEnd )
	{
		if ( *tempI < *tmp &&  *tmp < tmpMax )
		{
			tmpMax = *tmp;
			tempH = tmp;
		}

		++tmp;	
	}

		Swap( tempH, tempI );

		reverse(tempI+1,iterEnd-1);
	
	   flag = false;
	}//while
    
}
 
void FullArray::ExchangeOrder()
{
	bool flag=0;   //判断前面交换,还是后面交换
	
	for ( int i = 0, loopTimes=Factorial(m_vSque.size()-1);   //假如是4个数的全排列,每个循环输出4个,那么需要3!个循环
		          i < loopTimes; ++i  )
	{
		if ( flag == 0)
		{
			print();
		
		    R_Iter r_iterBeg = m_vSque.rbegin(),
			            r_iterEnd = m_vSque.rend();

		     for ( R_Iter iter1 = r_iterBeg, iter2 = ++r_iterBeg ; iter2 != r_iterEnd ; ++iter1,++iter2 )
		    {
		    	Swap( iter1, iter2 );
			    print();
		     }

			 Swap( m_vSque.rbegin(), ++m_vSque.rbegin());
			 flag=1;
		}//if

		else if ( flag == 1 )
		{
			print();

			Iter iterBeg = m_vSque.begin(),
				   iterEnd = m_vSque.end();

			for ( Iter iter1 = iterBeg, iter2 = ++iterBeg ; iter2 != iterEnd ; ++iter1,++iter2 )
			{
				Swap( iter1, iter2 );
				print();
			}

			Swap( m_vSque.begin(), ++m_vSque.begin());
			flag=0;
		}//else if
	}
}






	

int main()
{
	int arr[5]={1,2,3,4,5};
	FullArray fa;
	fa.intial(arr,4);
	fa.ExchangeOrder();
	
	return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值