[sprc_lcl(cool一生) ]先生的一段代码:从n个数字中取m个数的所有组合

1.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace ebcnc.testpage
{
/// <summary>
/// testpage 的摘要说明。
/// </summary>
public class testpage : System.Web.UI.Page
{
protected System.Web.UI.WebControls.TextBox TextBox1;
protected System.Web.UI.WebControls.Button Button1;
protected System.Web.UI.WebControls.Button Button2;
protected System.Web.UI.WebControls.Button Button3;
protected System.Web.UI.WebControls.TextBox tb_getlength;
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.CheckBox CheckBox1;
protected System.Web.UI.HtmlControls.HtmlTable t_copy;
protected Microsoft.Web.UI.WebControls.TreeView TreeView1;

private static ArrayList ccc = new ArrayList();

private void Page_Load(object sender, System.EventArgs e)
{
ccc.Clear();
}

#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{   
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Button2.Click += new System.EventHandler(this.Button2_Click);
this.Button3.Click += new System.EventHandler(this.Button3_Click);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

 

private void bbbb(int temp,int length,char[] aa,int[] bb)
{
while(temp<=length)
{
for(int i=0;i<length;i++)
{
bb[temp-1] = i;
if(temp<length)
{
bbbb(temp+1,length,aa,bb);
}
if(temp == length)
{
string zz = "";
for(int j=0;j<length;j++)
{
zz += aa[bb[j]].ToString();
}
ccc.Add(zz);
}
}
break;
}
}

private void dddd(int temp,int length,char[] aa,int[] bb)
{
while(temp<=length)
{
for(int i=0;i<length;i++)
{
bb[temp-1] = i;
if(temp<length)
{
dddd(temp+1,length,aa,bb);
}
if(temp == length)
{
string zz = "";
bool flag = true;
for(int j=0;j<length;j++)
{
for(int k=j+1;k<length;k++)
{
if(bb[k] == bb[j])
{
flag = false;
break;
}
}
if(!flag) break;
zz += aa[bb[j]].ToString();
}
if(flag) ccc.Add(zz);
}
}
break;
}
}

private void eeee(int temp,int length,char[] aa,int[] bb,int getlength)
{
while(temp<=getlength)
{
for(int i=0;i<length;i++)
{
bb[temp-1] = i;
if(temp<getlength)
{
eeee(temp+1,length,aa,bb,getlength);
}
if(temp == getlength)
{
string zz = "";
bool flag = true;
for(int j=0;j<getlength;j++)
{
for(int k=j+1;k<getlength;k++)
{
if(bb[k] == bb[j])
{
flag = false;
break;
}
}
if(!flag) break;
zz += aa[bb[j]].ToString();
}
if(flag) ccc.Add(zz);
}
}
break;
}
}


private void Button1_Click(object sender, System.EventArgs e)
{
string trystr = TextBox1.Text;
char[] aa = trystr.ToCharArray();
int length = aa.Length;
int[] bb = new int[length];
for(int i=0;i<length;i++)
{
bb[i] = i;
}
bbbb(1,length,aa,bb);
getoutstr(ccc);
}

private void Button2_Click(object sender, System.EventArgs e)
{
string trystr = TextBox1.Text;
char[] aa = trystr.ToCharArray();
int length = aa.Length;
int[] bb = new int[length];
for(int i=0;i<length;i++)
{
bb[i] = i;
}
dddd(1,length,aa,bb);
getoutstr(ccc);
}

private void Button3_Click(object sender, System.EventArgs e)
{
string trystr = TextBox1.Text;
char[] aa = trystr.ToCharArray();
int length = aa.Length;
int[] bb = new int[length];
for(int i=0;i<length;i++)
{
bb[i] = i;
}
int getlength = length;
try
{
getlength = Convert.ToInt32(tb_getlength.Text.Trim());
if(getlength > length) getlength = length;
}
catch{}
eeee(1,length,aa,bb,getlength);
getoutstr(ccc);
}

private void getoutstr(ArrayList ddd)
{
string outstr = "共有"+ddd.Count.ToString()+"个结果如下:<br/>";
for(int i=0;i<ddd.Count;i++)
{
if(ddd[i].ToString() != "")
{
outstr += ddd[i].ToString() +"<br/>";
}
}
Label1.Text = outstr;
}
}
}

 

2.copine() 先生的解释

哈这个问题有点意思,我自认为小学的时候数学还可以哈哈,来讨论一下。
可以模拟手算的算法:
先简化问题,从2/3问题开始
先排序1.2.3
取出1然后还需要再取一个数字可以是2.可以是3这样我们得到[1.2][1.3]所有含有1的二元组已经取到。
然后我们列举所有含2的二元组,取出2还要再取一个数字,注意这里有一个要点我们只可以向后取不可以向前取,这是为了不产生重复的二元组,理解这个要点对解决这个问题很重要。所以这里只可以取3得到[2.3]
下面我们取所有含有3的组合,取出3根据向后取的原则,我们发现已经没有可以取到的数字了。这样这个问题就结束了我们得到结果[1.2][1.3][2.3]
下面我们把这个问题扩展一下变成3/4问题
排序:1.2.3.4
先列举含有1的三元组,取出1,这里另外一个要点来了,我们的任务转化成为要在2.3.4中取出所有的2元组然后和1组成三元组这样这里转化为2/3问题,之后我们取所有含2的三元组,注意只能向后取的原则,问题转化为在3.4中取2元组的2/2问题

看到这里我们应该可以理解手算的操作方法了。
要把这个操作改写成计算机算法并不复杂。
result_array fn(source_array,start,end,n)
实现这样一个递归函数就可以了
result_array 是一个list内容是所有要求的n元组,source_array是原始的元素集合,start,end表明了区间,n是n元组的n,这样做是为了节省空间,免得每次递归都要复制出一个array作为取值元素集合。
方法里面的内容:
哈哈大家补充,不复杂的。
基本上是一个循环
先判断n是否=1 是就把所有元素放到一个list中返回,如果不是的话
对每一个元素如果他右面的元素>=n-1那么就对右面的元素调用fn(source_array,当前位置+1,末尾,n-1)那返回结果和元素组合放进一个list中,如果小于n-1了那么跳出循环返回这个list。
就这样了。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值