三色旗排序问题

本文介绍了经典的三色旗排序问题及其解决方案,并进一步探讨了如何将该算法应用于四色旗子的排序。提供了完整的C++代码实现。

转自:http://blog.youkuaiyun.com/andamajing/article/details/7545078

 

  三色旗的问题最早由E.W.Dijkstra所提出,他所使用的用语为Dutch Nation Flag(Dijkstra为荷兰人),而多数的作者则使用Three-Color Flag来称之。
       假设有一条绳子,上面有红、白、蓝三种颜色的旗子,起初绳子上的旗子颜色并没有顺序,您希望将之分类,并排列为蓝、白、红的顺序,要如何移动次数才会最少,注意您只能在绳子上进行这个动作,而且一次只能调换两个旗子。


解法
       在一条绳子上移动,在程式中也就意味只能使用一个阵列,而不使用其它的阵列来作辅助,问题的解法很简单,您可以自己想像一下在移动旗子,从绳子开头进行,遇到蓝色往前移,遇到白色留在中间,遇到红色往后移。

 

程序编写如下:

       首先输入您需要排序的旗子总数,然后输入相应的旗子,字符b代表蓝色,w代表白色,r代表红色。输入的字符数不能超过原先设定的旗子总数。

  1. #include "stdafx.h"   
  2. #include<iostream>   
  3. #include<string>   
  4. using namespace std;  
  5.   
  6. #define BLUE 'b'   
  7. #define WHITE 'w'   
  8. #define RED 'r'   
  9. #define swap(x,y) {char temp;temp=*(point+x);*(point+x)=*(point+y);*(point+y)=temp;}   
  10.   
  11. int _tmain(int argc, _TCHAR* argv[])  
  12. {  
  13.     int N;  
  14.     int bflag=0,wflag=0,rflag;  
  15.     cout<<"please input number of characters:"<<endl;  
  16.     cin>>N;  
  17.     char *point=new char[N];  
  18.     cout<<"please input the string:"<<endl;  
  19.     cin>>point;  
  20.     rflag=strlen(point)-1;  
  21.     cout<<"the origin string is :"<<endl;  
  22.     cout<<point<<endl;  
  23.     while(wflag<=rflag)  
  24.     {  
  25.         if(point[wflag]==WHITE)  
  26.         {  
  27.             wflag++;  
  28.         }  
  29.         else if(point[wflag]==BLUE)  
  30.         {  
  31.             swap(wflag,bflag);  
  32.             wflag++;bflag++;  
  33.         }  
  34.         else  
  35.         {  
  36.             while(wflag<rflag&&point[rflag]==RED)  
  37.                 rflag--;  
  38.             swap(wflag,rflag);  
  39.             rflag--;  
  40.         }  
  41.     }  
  42.     cout<<"the ordered string is :"<<endl;  
  43.     cout<<point<<endl;  
  44.     return 0;  
  45. }  
#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;

#define BLUE 'b'
#define WHITE 'w'
#define RED 'r'
#define swap(x,y) {char temp;temp=*(point+x);*(point+x)=*(point+y);*(point+y)=temp;}

int _tmain(int argc, _TCHAR* argv[])
{
	int N;
	int bflag=0,wflag=0,rflag;
	cout<<"please input number of characters:"<<endl;
	cin>>N;
	char *point=new char[N];
	cout<<"please input the string:"<<endl;
	cin>>point;
	rflag=strlen(point)-1;
	cout<<"the origin string is :"<<endl;
	cout<<point<<endl;
	while(wflag<=rflag)
	{
		if(point[wflag]==WHITE)
		{
			wflag++;
		}
		else if(point[wflag]==BLUE)
		{
			swap(wflag,bflag);
			wflag++;bflag++;
		}
		else
		{
			while(wflag<rflag&&point[rflag]==RED)
				rflag--;
			swap(wflag,rflag);
			rflag--;
		}
	}
	cout<<"the ordered string is :"<<endl;
	cout<<point<<endl;
	return 0;
}


运行结果如下所示:

       输入wwwbbrwbwr之后运行结果为:

 

          上述问题是典型的三色排序问题,再学习了之后,我考虑是否可以对四色的旗子进行排序,感觉应该也是可以的。假设绳子上系有四种颜色的旗子,红,黄,白,蓝,在排序过程中遇到红色的旗子就将它往前移动,遇到蓝色的就往后移动,遇到白色的旗子,也往后移动,只是通过检查将该白色旗子放置在蓝色旗子的前面。

程序编写如下:

  1. #include "stdafx.h"   
  2. #include<iostream>   
  3. #include<string>   
  4. using namespace std;  
  5.   
  6. #define BLUE 'b'   
  7. #define WHITE 'w'   
  8. #define RED 'r'   
  9. #define YELLOW 'y'   
  10. #define swap(x,y) {char temp;temp=*(point+x);*(point+x)=*(point+y);*(point+y)=temp;}   
  11.   
  12. int _tmain(int argc, _TCHAR* argv[])  
  13. {  
  14.     int N;  
  15.     int rflag=0,yflag=0,wflag,bflag;  
  16.     cout<<"please input number of characters:"<<endl;  
  17.     cin>>N;  
  18.     char *point=new char[N];  
  19.     cout<<"please input the string:"<<endl;  
  20.     cin>>point;  
  21.     bflag=strlen(point)-1;  
  22.     wflag=bflag;  
  23.     cout<<"the origin string is :"<<endl;  
  24.     cout<<point<<endl;  
  25.     while(yflag<wflag)  
  26.     {  
  27.         if(point[yflag]==YELLOW)  
  28.         {  
  29.             yflag++;  
  30.         }  
  31.         else if(point[yflag]==RED)  
  32.         {  
  33.             swap(yflag,rflag);  
  34.             yflag++;rflag++;  
  35.         }  
  36.         else if(point[yflag]==WHITE)  
  37.         {  
  38.             while((yflag<wflag)&&(point[wflag]==WHITE))  
  39.                 wflag--;  
  40.             swap(wflag,yflag);  
  41.         }  
  42.         else  
  43.         {  
  44.             while(yflag<=wflag&&point[bflag]==BLUE)  
  45.                 bflag--;  
  46.             swap(yflag,bflag);  
  47.             bflag--;  
  48.             wflag=bflag;  
  49.         }  
  50.     }  
  51.     cout<<"the ordered string is :"<<endl;  
  52.     cout<<point<<endl;  
  53.     return 0;  
  54. }  
#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;

#define BLUE 'b'
#define WHITE 'w'
#define RED 'r'
#define YELLOW 'y'
#define swap(x,y) {char temp;temp=*(point+x);*(point+x)=*(point+y);*(point+y)=temp;}

int _tmain(int argc, _TCHAR* argv[])
{
	int N;
	int rflag=0,yflag=0,wflag,bflag;
	cout<<"please input number of characters:"<<endl;
	cin>>N;
	char *point=new char[N];
	cout<<"please input the string:"<<endl;
	cin>>point;
	bflag=strlen(point)-1;
	wflag=bflag;
	cout<<"the origin string is :"<<endl;
	cout<<point<<endl;
	while(yflag<wflag)
	{
		if(point[yflag]==YELLOW)
		{
			yflag++;
		}
		else if(point[yflag]==RED)
		{
			swap(yflag,rflag);
			yflag++;rflag++;
		}
		else if(point[yflag]==WHITE)
		{
			while((yflag<wflag)&&(point[wflag]==WHITE))
				wflag--;
			swap(wflag,yflag);
		}
		else
		{
			while(yflag<=wflag&&point[bflag]==BLUE)
				bflag--;
			swap(yflag,bflag);
			bflag--;
			wflag=bflag;
		}
	}
	cout<<"the ordered string is :"<<endl;
	cout<<point<<endl;
	return 0;
}


运行结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值