三色旗的問題最早由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;}
運行結果如下: