出于没有特别的原因,我决定寻找一种算法,该算法可以产生 1...n 之间的所有可能的 k 整数选择,其中 k 整数之间的顺序无关紧要(n 选择 k 事物)。
出于完全相同的原因,这根本不是原因,我也在 C# 中实现了它。我的问题是:
您在我的算法或代码中看到任何错误吗?而且,更重要的是,你能推荐一个更好的算法吗?
请更多地关注算法而不是代码本身。这不是我写过的最漂亮的代码,但如果你看到错误,请告诉我。
编辑: Alogirthm 解释-
- 我们持有 k 个指数。
- 这会创建 k 个嵌套的 for循环,其中循环 i 的索引是 indices[i]。
- 它模拟 k for循环,其中 indices[i+1] 属于嵌套在 indices[i] 循环中的循环。
- indices[i] 从 indices[i - 1] + 1 运行到 n - k + i + 1。
代码:
public class AllPossibleCombination
{
int n, k;
int[] indices;
List<int[]> combinations = null;
public AllPossibleCombination(int n_, int k_)
{
if (n_ <= 0)
{
throw new ArgumentException("n_ must be in N+");
}
if (k_ <= 0)
{
throw new ArgumentException("k_ must be in N+");
}
if (k_ > n_)
{
throw new ArgumentException("k_ can be at most n_");
}
n = n_;
k = k_;
indices = new int[k];
indices[0] = 1;
}
/// <summary>
/// Returns all possible k combination of 0..n-1
/// </summary>
/// <returns></returns>
public List<int[]> GetCombinations()
{
if (combinations == null)
{
combinations = new List<int[]>();
Iterate(0);
}
return combinations;
}
private void Iterate(int ii)
{
//
// Initialize
//
if (ii > 0)
{
indices[ii] = indices[ii - 1] + 1;
}
for (; indices[ii] <= (n - k + ii + 1); indices[ii]++)
{
if (ii < k - 1)
{
Iterate(ii + 1);
}
else
{
int[] combination = new int[k];
indices.CopyTo(combination, 0);
combinations.Add(combination);
}
}
}
}
我为这个冗长的问题道歉,它可能适合博客文章,但我确实希望社区的意见在这里。
谢谢,
阿萨夫