三色旗的问题最早由E.W.Dijkstra所提出,他所使用的用语为Dutch Nation Flag(Dijkstra为荷兰人),而多数的作者则使用Three-Color Flag来称之。
假设有一条绳子,上面有红、白、蓝三种颜色的旗子,起初绳子上的旗子颜色并没有顺序,您希望将之分类,并排列为蓝、白、红的顺序,要如何移动次数才会最少,注意您只能在绳子上进行这个动作,而且一次只能调换两个旗子。
解法
在一条绳子上移动,在程式中也就意味只能使用一个阵列,而不使用其它的阵列来作辅助,问题的解法很简单,您可以自己想像一下在移动旗子,从绳子开头进行,遇到蓝色往前移,遇到白色留在中间,遇到红色往后移。
程序编写如下:
首先输入您需要排序的旗子总数,然后输入相应的旗子,字符b代表蓝色,w代表白色,r代表红色。输入的字符数不能超过原先设定的旗子总数。
#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之后运行结果为:
上述问题是典型的三色排序问题,再学习了之后,我考虑是否可以对四色的旗子进行排序,感觉应该也是可以的。假设绳子上系有四种颜色的旗子,红,黄,白,蓝,在排序过程中遇到红色的旗子就将它往前移动,遇到蓝色的就往后移动,遇到白色的旗子,也往后移动,只是通过检查将该白色旗子放置在蓝色旗子的前面。
程序编写如下:
#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;
}
运行结果如下: