gpt4 book ai didi

c# - 列出 1...n 之间的 k 个整数的所有可能组合(n 选择 k)

转载 作者:可可西里 更新时间:2023-11-01 08:44:45 25 4
gpt4 key购买 nike

无缘无故,我决定寻找一种算法,该算法可以产生 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);
}
}
}
}

对于这个长问题,我深表歉意,它可能适合写一篇博文,但我确实想在这里征求社区的意见。

谢谢,
阿萨夫

最佳答案

在 C++ 中给出以下例程:

template <typename Iterator>
inline bool next_combination(const Iterator first, Iterator k, const Iterator last)
{
/* Credits: Thomas Draper */
if ((first == last) || (first == k) || (last == k))
return false;
Iterator itr1 = first;
Iterator itr2 = last;
++itr1;
if (last == itr1)
return false;
itr1 = last;
--itr1;
itr1 = k;
--itr2;
while (first != itr1)
{
if (*--itr1 < *itr2)
{
Iterator j = k;
while (!(*itr1 < *j)) ++j;
std::iter_swap(itr1,j);
++itr1;
++j;
itr2 = k;
std::rotate(itr1,j,last);
while (last != j)
{
++j;
++itr2;
}
std::rotate(k,itr2,last);
return true;
}
}
std::rotate(first,k,last);
return false;
}

然后您可以继续执行以下操作:

std::string s = "123456789";
std::size_t k = 3;
do
{
std::cout << std::string(s.begin(),s.begin() + k) << std::endl;
}
while(next_combination(s.begin(),s.begin() + k,s.end()));

关于c# - 列出 1...n 之间的 k 个整数的所有可能组合(n 选择 k),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/548402/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com