三色旗的问题最早由E.W.Dijkstra所提出,他所使用的用语为Dutch Nation Flag(Dijkstra为荷兰人),而多数的作者则使用Three-Color Flag来称之。
假设有一条绳子,上面有红、白、蓝三种颜色的旗子,起初绳子上的旗子颜色并没有顺序,您希望将之分类,并排列为蓝、白、红的顺序,要如何移动次数才会最少,注意您只能在绳子上进行这个动作,而且一次只能调换两个旗子。
//#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <iomanip.h>
//using namespace std;
char * generateArr(int n);
void showArray(char * a,int n);
void adjustArray(char * a,int n);
void swapEle(char &a,char &b);
int main()
{
int n;
cout<<"Please input the length of the Array:";
cin>>n;
char * pArr=generateArr(n);
cout<<"the Init Array:"<<endl;
showArray(pArr,n);
adjustArray(pArr,n);
cout<<"we have adjust it:"<<endl;
showArray(pArr,n);
return 0;
}
char * generateArr(int n)
{
srand((int)time(NULL));
char * a=new char[n];
for(int i=0;i<n;i++)
{
int key=rand()%3;
switch (key)
{
case 0:
a[i]='w';
break;
case 1:
a[i]='b';
break;
case 2:
a[i]='r';
break;
}
}
return a;
}
void showArray(char *a,int n)
{
for(int i=1;i<=n;i++)
{
cout<<setw(3)<<a[i-1];
if(i%10==0)
{
cout<<endl;
}
}
}
void adjustArray(char * a,int n)
{
int w,b,r;
r=n-1;
w=b=0;
int i=0;
for(;i<=r;i++)//r后面元素均为红色
{
switch (a[i])
{
case 'w':
break;
case 'r':
while (a[r]=='r')
{
r--;
}//找到第一个不是r的位置
if (i<r)//防止最后一次交换出问题的情况
{
swapEle(a[i],a[r--]);
i--;//如果后面换回来的b则少了一次检验的机会
}
break;
case 'b':
while (a[b]=='b')
{
b++;
}//找到第一个不是r的位置
if(b<i)
{
swapEle(a[i],a[b++]);
}
w=b;//记录当前白色的起始位置
break;
}
}
}
void swapEle(char &a,char &b)
{
char tmp=a;
a=b;
b=tmp;
}