组合算法(三种实现方式)

命题:从N个不同元素中取K个元素形成的组合:

/// <summary>
/// 递归法
/// </summary>
/// <param name="n">N个不同元素</param>
/// <param name="k">取K个组合</param>
/// <param name="initN">开始N</param>
/// <param name="initK">开始K</param>
/// <param name="a">参数数组</param>
private void CombNK(int n, int k,int initN,int initK,int[] a)
{

int i, j;
for (i = n; i >= k; i--)
{
a[k] = i;
if (k > 1)
{
CombNK(i - 1, k - 1,initN,initK,a);
}
else
{
string s = "";
for (j = 1; j <= initK; j++)
{
s += a[j] + " ";
}
theCount++;
this.richTextBox1.AppendText(s + "\r\n");
}
}
}
/// <summary>
/// 循环加1法
/// </summary>
/// <param name="n"></param>
/// <param name="k"></param>
private void ComboNKEx(int n, int k)
{
List<int> theRets = new List<int>();
string s = "";
//第1个组合是123...K
for (var b = 1; b <= k; b++)
{
theRets.Add(b);
s += b + " ";
}
this.richTextBox1.AppendText(s + "\r\n");
while(theRets[0]<=(n-k+1))
{
theRets[k-1]++;

for (var j = k; j > 1; j--)
{
theCount++;
if (theRets[j-1] > n - (k-j))
{

theRets[j - 2]++;
theRets[j - 1] = theRets[j - 2];
theCount++;
}
}
OutPut(theRets, n, k);

}
}
private void OutPut(List<int> a,int n,int k)
{
bool ok = true;
int tmp = a[0];
string s = a[0].ToString();
for (int i = 2; i <= k;i++)
{
if (a[i - 1] <= tmp || a[i - 1]>n)
{
ok = false;
break;
}
s += " " + a[i-1].ToString();
tmp = a[i-1];
}
if (ok)
{
this.richTextBox1.AppendText(s + "\r\n");
//theCount++;
}

}
/// <summary>
/// 回溯法
/// </summary>
/// <param name="n"></param>
/// <param name="k"></param>
private void ComboNK1(int n, int k)
{
int i, j;
int[] a = new int[k];
a[0] = 1;
i = 0;
while (1 == 1)
{

//如果a[i]满足,则继续,如果不满足,则回溯
if (a[i] - i <= n - k + 1)
{
if (i == k - 1)
{
string s = "";
for (j = 1; j <= k; j++)
{
s += a[j - 1] + " ";
}
this.richTextBox1.AppendText(s + "\r\n");
theCount++;
}
else
{
//试探
i++;
if (i - 1 >= 0)
{
a[i] = a[i - 1];
}

}
a[i]++;
}
else
{
if (i == 0)
{
break;
}
//回溯
i--;
a[i]++;
//a[i + 1] = a[i]+1;

}

}
}

=============================

平时弄弄这些算法,主要的目的是活动一下脑子,防止痴呆....

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值