C#用链式方法表达循环嵌套

2019-12-30 12:31:30王振洲
易采站长站为您分析C#用链式方法表达循环嵌套的相关资料,非常不错具有参考借鉴价值,需要的朋友可以参考下  

一.起缘

故事缘于一位朋友的一道题:

朋友四人玩LOL游戏。第一局,分别选择位置:中单,上单,ADC,辅助;第二局新加入的伙伴要选上单,四人可选位置变为:中单,打野,ADC,辅助;要求,第二局四人每人不得选择和第一局相同的位置,请问两局综合考虑有多少种位置选择方式?

对于像我这边不懂游戏的人来讲,看不懂。于是有了这个版本:

有4个人,4只椅子,第一局每人坐一只椅子,第二局去掉第2只椅子,增加第5只椅子,每人坐一只椅子,而且每个人不能与第一局坐相同的椅子。问两局综合考虑,共有多少种可能的情况?

我一开始的想法是这样的,4个人就叫ABCD:第1局可能数是4*3*2*1=24,如果A第1局选了第2张椅,则A有4种可能,否则A有3种可能。对B来讲,如果A选了B第一局的椅,则B有3种可能,否则B有2种可能(排队自己第一局和A第二局已选)……想到这里我就晕了,情况越分越多。

二.原始的for嵌套

本来是一道数学题,应该由知识算出来有多少种,但我突然有个想法,不如用计算机穷举出出来。一来可以为各种猜测提供一个正确的答案,二来或许可以从答案反推出(数学上的)计算方法。然后就写了第1版:


static Seat data = new Seat();
public static void Run()
{
for (int a = 0; a < 4; a++)
{
if (data.IsSelected(0, a)) //第1局编号0。如果已经被人坐了。
continue;
data.Selected(0, a, "A"); //第1局编号0。A坐a椅。
for (int b = 0; b < 4; b++)
{
if (data.IsSelected(0, b))
continue;
data.Selected(0, b, "B");
for (int c = 0; c < 4; c++)
{
if (data.IsSelected(0, c))
continue;
data.Selected(0, c, "C");
for (int d = 0; d < 4; d++)
{
if (data.IsSelected(0, d))
continue;
data.Selected(0, d, "D");
for (int a2 = 0; a2 < 5; a2++)
{
if (a2 == 1)
continue;
if (data.IsSelected(1, a2)) //第2局编号1
continue;
if (data.IsSelected(0, a2, "A")) //如果第1局A坐了a2椅
continue;
data.Selected(1, a2, "A");
for (int b2 = 0; b2 < 5; b2++)
{
if (b2 == 1)
continue;
if (data.IsSelected(1, b2))
continue;
if (data.IsSelected(0, b2, "B"))
continue;
data.Selected(1, b2, "B");
for (int c2 = 0; c2 < 5; c2++)
{
if (c2 == 1)
continue;
if (data.IsSelected(1, c2))
continue;
if (data.IsSelected(0, c2, "C"))
continue;
data.Selected(1, c2, "C");
for (int d2 = 0; d2 < 5; d2++)
{
if (d2 == 1)
continue;
if (data.IsSelected(1, d2))
continue;
if (data.IsSelected(0, d2, "D"))
continue;
data.Selected(1, d2, "D");
data.Count++; //可能的情况数加1
Console.WriteLine("{0,5} {1}", data.Count, data.Current);
data.UnSelected(1, d2);
}
data.UnSelected(1, c2);
}
data.UnSelected(1, b2);
}
data.UnSelected(1, a2);
}
data.UnSelected(0, d);
}
data.UnSelected(0, c);
}
data.UnSelected(0, b);
}
data.UnSelected(0, a); //A起身(释放坐椅)
}
}