本文为joshua317原创文章,转载请注明:转载自joshua317博客 https://www.joshua317.com/article/161
一、问题
三色旗的问题最早由E.W.Dijkstra所提出,大致意思如下:
有一条绳子上面挂有白、红、蓝三种颜色的多面旗子,这些旗子的排列是无序的。现在要将绳子上的旗子按蓝、白、红三种颜色进行归类排列,但是只能在绳子上进行旗子的移动,并且每次只能调换两个旗子。问如何采用最少的步骤来完成三色旗的排列呢?
二、分析
我们来分析一下三色旗问题。假设绳子上共有10面旗子,蓝色旗子用符号b表示,白色旗子用符号w表示,红色旗子用符号r表示,然后排成一列
定义3个变量(Blue、Write、Red)来指示三种颜色的旗
在0~(Blue-1)之间放蓝色旗;
Blue~(Write-1)放白色旗;
剩余的位置放红色旗。
三个变量的初始位置
每一次都处理变量Write指向位置的元素,可分如下3种情况处理:
- 如果Write所在位置的元素是红旗r,表示需将红旗与Red变量的元素对调,然后将Red--,继续处理下一个位置
- 如果White所在位置的元素是白旗w,表示该位置的元素应该在此,然后将White++,继续处理下一个位置
- 如果White所在位置的元素是蓝旗b,表示需将蓝旗与Blue变量所在位置的元素对调,然后将Blue++、White++
最终结果:
三、编程
package com.joshua317;
import java.util.Arrays;
public class Main {
static int count;
static char color[] = "brwwrbrbwr".toCharArray();
static int Blue, White, Red;
public static void main(String[] args) {
int i;
Blue = 0;
White = 0;
Red = color.length - 1;
count = 0;
System.out.println("三色旗问题求解");
System.out.println("三色旗最初排列:");
for (i = 0; i < color.length; i++) {
System.out.printf(" %c", color[i]);
}
System.out.println();
threeFlags();
System.out.printf("通过%d次完成对调后,结果如下:", count);
for (i = 0; i < color.length; i++) {
System.out.printf(" %c", color[i]);
}
}
/**
* 调换顺序
* @param c
* @param x
* @param y
*/
static void swap(char[] c, int x, int y)
{
int i;
char temp;
temp = c[x];
c[x] = c[y];
c[y] = temp;
count++;
System.out.printf("第%d次对调后:", count);
for (i = 0; i < color.length; i++) {
System.out.printf(" %c", color[i]);
}
System.out.println();
}
/**
* 三色旗算法
*/
static void threeFlags()
{
//如果开头已经是蓝旗,直接将Blue++、White++
while (color[White] == 'b') {
Blue++;
White++;
}
//如果结尾已经是红旗,直接将Red--
while (color[Red] == 'r') {
Red--;
}
//剩下未处理的元素继续处理
while (White <= Red) {
//如果White所在位置的元素是红旗r,表示需将红旗与Red变量的元素对调,然后将Red--,,继续处理下一个位置
if (color[White] == 'r') {
swap(color, White, Red);
Red--;
//如果Red所在位置的元素是红旗r,继续向前移动Red位置,即Red--
while (color[Red] == 'r') {
Red--;
}
}
//如果White所在位置的元素是白旗w,表示该位置的元素应该在此,然后将White++,继续处理下一个位置
while (color[White] == 'w') {
White++;
}
//如果White所在位置的元素是蓝旗b,表示需将蓝旗与Blue变量所在位置的元素对调,然后将Blue++、White++
if (color[White] == 'b') {
swap(color, White, Blue);
Blue++;
White++;
}
}
}
}
本文为joshua317原创文章,转载请注明:转载自joshua317博客 https://www.joshua317.com/article/161