排列3D的全排列组合

           上午看见有c写的全排列,我也想用C#来实现一下,买过彩票的朋友应该都熟悉3d吧,那么我简单实现一个3d彩票的全排列,3D是从0-9(可能是1-9)这些数字,然后从中选3个数,可以有全排列的买法,也有组合的买法,那么下面贴代码了(vs2008)。

代码
//-------------------- 全排列和组合排列
class B_Test
{

/// <summary>

/// 对数组进行组合操作,选取selectCount个元素进行组合

/// </summary>

/// <param name="lsArray">即将进行组合操作的数组</param>

/// <param name="selectCount">选取的元素的个数</param>

public static void C(List<string> lsArray, int selectCount)

{

int totolcount = lsArray.Count;

int[] currectselect = new int[selectCount];

int last = selectCount - 1;



for (int i = 0; i < selectCount; i++)

{

currectselect[i]
= i;

}



while (true)

{

for (int i = 0; i < selectCount; i++)

{

Console.Write(
" {0} ", lsArray[currectselect[i]]);

}

Console.WriteLine();



if (currectselect[last] < totolcount - 1)

{

currectselect[last]
++;

}

else

{

int pos = last;

while (pos > 0 && currectselect[pos - 1] == currectselect[pos] - 1)

{

pos
--;

}

if (pos == 0) return;

currectselect[pos
- 1]++;

for (int i = pos; i < selectCount; i++)

{

currectselect[i]
= currectselect[i - 1] + 1;

}

}

}

}

#region

/// <summary>

/// 返回组合值(思想是用currectselect记录取的lsArray的每个数对应数组的位置,先把currectselect最后一数加到isarry.cout,接着是倒数第二个加到小于倒数第一个,依次类推知道第0位)

/// </summary>

/// <param name="lsArray">即将进行组合操作的数组</param>

/// <param name="selectCount">选取的元素的个数</param>

public static List<string> D(List<string> lsArray, int selectCount)
{

List
<string> list_return=new List<string>();
int totolcount = lsArray.Count;

int[] currectselect = new int[selectCount];

int last = selectCount - 1;



for (int i = 0; i < selectCount; i++)
{

currectselect[i]
= i;

}



while (true)
{

for (int i = 0; i < selectCount; i++)
{
list_return.Add(lsArray[currectselect[i]]);
//Console.Write(" {0} ", lsArray[currectselect[i]]);

}

//Console.WriteLine();



if (currectselect[last] < totolcount - 1)
{

currectselect[last]
++;

}

else
{

int pos = last;

while (pos > 0 && currectselect[pos - 1] == currectselect[pos] - 1)
{

pos
--;

}

if (pos == 0) break;

currectselect[pos
- 1]++;

for (int i = pos; i < selectCount; i++)
{

currectselect[i]
= currectselect[i - 1] + 1;

}

}

}

return list_return;

}

/// <summary>

/// list 排列的数组的次序

/// </summary>
/// <param name="list">排列数组</param>
/// <param name="selectCount">全排列的个数</param>
public static void PN(Func<List<string>, int, List<string>> list,List<string> list_input, int selectCount)
{
List
<string> list_get = new List<string>();
list_get
= list(list_input,selectCount);
List
<string> sub_list = new List<string>();
foreach (string lis in list_get)
{
sub_list.Add(lis);
if(sub_list.Count==selectCount)
{
A(sub_list,
0,selectCount-1);
sub_list.Clear();
}
}
Console.Write(
"----------p/n--------");
Console.WriteLine();


}
#endregion
/// <summary>

/// 对数组进行全排列(用全排列的递归思想)

/// </summary>

/// <param name="lsArray">要进行全排列的数组</param>

/// <param name="begin">进行全排列的开始下标</param>

/// <param name="end">进行全排列的结束下标</param>

public static void A(List<string> lsArray, int begin, int end)

{

if (begin == end)

{

for (int i = 0; i <= end; i++)

Console.Write(
" {0} ", lsArray[i]);

Console.WriteLine();

}

for (int i = begin; i <= end; i++)

{

Swap(lsArray, begin, i);

A(lsArray, begin
+ 1, end);

Swap(lsArray, begin, i);

}

}



/// <summary>

/// 交换数组中的下标为x,y的值

/// </summary>

/// <param name="lsArray">该数组</param>

/// <param name="x"></param>

/// <param name="y"></param>

public static void Swap(List<string> lsArray, int x, int y)

{

string t = lsArray[x];

lsArray[x]
= lsArray[y];

lsArray[y]
= t;

}
}

对排列3进行操作:

代码



static void Main(string[] args)
{

//B_Test b_test = new B_Test();
List<string> list = new List<string>();
for (int i = 1; i < 10; i++)
{

list.Add(i.ToString());
}

// B_Test.PN(B_Test.D(list,3),list,3);
//从数组p中任意选n个数进行全排列p(n)即排列三
B_Test.PN((a, b) => B_Test.D(a,b), list, 3);
//排列3组合
B_Test.C(list, 3);

//Console.WriteLine("---------------------");

//数组前n个数的全排列(0,1,2)的全排列
B_Test.A(list, 0, 3);
Console.Read();
}

 

有错误的地方欢迎大家拍砖,希望交流和共享。

posted on 2010-03-19 13:44 MR_ke 阅读(1712) 评论(12) 编辑 收藏

评论

#1楼 2010-03-19 13:50 Sevendays      

呵呵,支持,学习学习。看来全排列算法还是有些感兴趣的嘛~  回复 引用 查看   

#2楼[楼主] 2010-03-19 13:53 MR_ke      

@Sevendays
是啊,不过做b/s很少能用上这些,特别做增删改查的时候。
 回复 引用 查看   

#3楼 2010-03-19 13:57 Sevendays      

@MR_ke
呵呵,兴趣使然。我也是一时兴起实现了这个算法,然后大家纷纷写出自己的版本,呵呵,可以相互学习学习~
 回复 引用 查看   

#4楼[楼主] 2010-03-19 14:05 MR_ke      

@Sevendays
对啊,有时间可以练练自己的思维,大学那会天天弄个c,一开始是汉诺塔,后来是什么合并排序,什么减治算法,分治算法,贪婪算法法,记得最后是算法的极限,现在想想都差不多都又还给老师了,拿起那些算法书还不知道有几个能写出来。
 回复 引用 查看   

#5楼 2010-03-19 15:22 紫色永恒      

此3D非彼3D啊。。。  回复 引用 查看   

#6楼[楼主] 2010-03-19 15:46 MR_ke      

@紫色永恒
这里3D实现的是全排列,没有计算重复的情况,那么可以截取数据从0到999,不足三位前面全补零,最后得到就是我们想要的,比如98补零为0、9、8;0就是0、0、0,不过这只适合数据小于10的数字排列。
 回复 引用 查看   

#7楼[楼主] 2010-03-19 15:49 MR_ke      

@紫色永恒
看来老兄对博彩也有过兴趣。
 回复 引用 查看   

#8楼 2010-03-19 18:28 Sevendays      

@MR_ke
呵呵,我们大家可以不定期的发些复杂点的算法题,一起练练大脑,呵呵~
 回复 引用 查看   

#9楼[楼主] 2010-03-20 11:20 MR_ke      

@Sevendays
你这想法不错,我支持。
 回复 引用 查看   

#10楼 2011-08-10 09:38 Ringgo.Yao      

B_Test.PN((a, b) => B_Test.D(a,b), list, 3);
这个不知道你有没有看过结果,我看结果连0,1这2个数字都没有出现,算法还需要改进.
 回复 引用 查看   

#11楼[楼主] 2011-08-10 15:14 MR_ke      

@Ringgo.Yao
0,1是没有的 list里面就没有加入0,1。
如果list里面有,排列结果就有的。
for (int i = 1; i < 10; i++) { list.Add(i.ToString()); }
 回复 引用 查看   

#12楼 2011-08-10 16:29 Ringgo.Yao      

1是在里面的,问题是这样.我检测了下,0~9一共10个数字,取3个进行排列组合,结果应该为720,但是你的打印出来的会少.不知道为什么,我看了别人的版本,也是这问题.  回复 引用 查看   

公告

昵称:MR_ke
园龄:2年4个月
粉丝:79
关注:8

导航

<2010年3月>
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910

统计

  • 随笔 - 38
  • 文章 - 1
  • 评论 - 230
  • 引用 - 0

搜索

 
 

常用链接

随笔分类

随笔档案

最新评论

阅读排行榜

评论排行榜

推荐排行榜