C# 从n中获得k个元素的所有组合的算法
我有一个列表,我想从2的组合开始对列表中的元素进行一些操作 下面是我的清单:C# 从n中获得k个元素的所有组合的算法,c#,algorithm,combinations,C#,Algorithm,Combinations,我有一个列表,我想从2的组合开始对列表中的元素进行一些操作 下面是我的清单: List<string> strArr = new List<string> { "A", "B", "C", "D", "E", "F", "G", "H" }; List strArr=新列表{“A”、“B”、“C”、“D”、“E”、“F”、“G”、“H”}; 如果我们一次选择2个元素,它将生成以下组合:- (A,B)(A,C)(A,D)(A,E)(A,F)(A,G)(A,H)(B,C)
List<string> strArr = new List<string> { "A", "B", "C", "D", "E", "F", "G", "H" };
List strArr=新列表{“A”、“B”、“C”、“D”、“E”、“F”、“G”、“H”};
如果我们一次选择2个元素,它将生成以下组合:-
(A,B)(A,C)(A,D)(A,E)(A,F)(A,G)(A,H)(B,C)(B,D)
等等
如果我们一次选择3个元素,它将生成以下组合:-
(A,B,C)(A,B,D)(A,B,F)(A,B,G)(A,B,G)(A,C,D)(A,C,G)(A,C,H)(A,C,H)(A,D,E)(A,D,E)(A,D,E)(A,D,G)(A,E,F)(A,F,G,G)(A,F,G,G)(B,C,D)(B,E,E,E)(B,C,E)(B,C,E)(A,F)(A,F,F)(A,F,F,F)(A,E,F,F)(A,F,F,F)(A,C,G,G,F)(A,F,F)
等等
获得这些组合非常容易。我跟着
它给了我精确的输出
但是我不能使用这个代码,因为我有另一个要求,我将继续从列表中删除元素,以防它们满足某些条件,因此组合的数量将继续减少。因此,我不想使用LINQ获得所有的组合,因为在我的情况下,它会影响性能
我想用下面的方法来做:
List<string> strArr = new List<string> { "A", "B", "C", "D", "E", "F", "G", "H" };
// Loop for selecting combination of two elements at time
for (int i = 0; i < strArr.Count; i++)
{
for (int j = i + 1; j < strArr.Count; j++)
{
// Writing on Console
// Actually do some operation to check whether these two elements in list needs to be removed or not
Console.Write(strArr[i] + strArr[j]);
Console.WriteLine();
// Check whether current combination of 2 elements need to be removed or not
if (<< condition >>)
{
// Remove both the current elements
// Remove current element of outer loop
strArr.RemoveAt(i);
// Remove current element of inner loop
// Subtracting one as list size is reduced by 1
strArr.RemoveAt(j - 1);
//
i--;
break;
}
}
}
bool isRemoved = false;
// Loop for selecting combination of three elements at time
for (int i = 0; i < strArr.Count; i++)
{
for (int j = i + 1; j < strArr.Count; j++)
{
for (int k = j + 1; k < s.Count; k++)
{
// Writing on Console
// Actually do some operation to check whether these three elements in list needs to be removed or not
Console.Write(strArr[i] + strArr[j] + strArr[k]);
Console.WriteLine();
// Check whether current combination of 3 elements need to be removed or not
if (<< condition >>)
{
// Remove all the three elements
// Remove current element of outer loop
strArr.RemoveAt(i);
// Remove current element of inner loop
// Subtracting 1 as list size is reduced by 1
strArr.RemoveAt(j - 1);
// Subtracting 2 as list size is reduced by 2
strArr.RemoveAt(k - 2);
isRemoved = true;
i--;
break;
}
// If elements are removed then exit from loop with variable j
if (isRemoved)
{
break;
}
}
}
}
// Now make loop for selecting combination of four elements at time
// and keep removing the elements depending upon condition
List strArr=新列表{“A”、“B”、“C”、“D”、“E”、“F”、“G”、“H”};
//一次选择两个元素组合的循环
for(int i=0;i)
{
//删除两个当前元素
//拆下外回路的电流元件
strArr.RemoveAt(一);
//移除内环的电流元件
//列表大小减少1时减去1
strArr.RemoveAt(j-1);
//
我--;
打破
}
}
}
bool isRemoved=false;
//一次选择三个元素组合的循环
for(int i=0;i)
{
//删除所有三个元素
//拆下外回路的电流元件
strArr.RemoveAt(一);
//移除内环的电流元件
//列表大小减少1时减去1
strArr.RemoveAt(j-1);
//列表大小减少2时减去2
strArr.RemoveAt(k-2);
isRemoved=true;
我--;
打破
}
//如果删除了元素,则使用变量j退出循环
如果(已删除)
{
打破
}
}
}
}
//现在进行循环,每次选择四个元素的组合
//并根据情况不断移除元件
删除元素将确保我获得更快的性能,我希望执行此操作,直到结束。我无法思考如何在递归中保持这些循环的深层次。有人能帮我在递归中添加这些无止境的for循环吗
谢谢你花时间为我写解决方案,但这不是我想要的。。。我将简要说明没有代码的要求
有人能帮我实现上述用例吗?不确定这是否正是您所需要的,但它可能被认为是一种方法
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
List<Tuple<Expression, Expression>> conditions = new List<Tuple<Expression, Expression>>();
// a complex condition, that the current item contains both "B" and "H"
Expression<Func<IEnumerable<string>, bool>> expression1 = item => item.Contains("B") && item.Contains("H");
// an expression which is used to exclude the elements from the list
Expression<Func<string, bool>> expression2 = j => j != "B" && j != "H";
// associate the condition with the exclusion filter
var condition = new Tuple<Expression, Expression>(expression1, expression2);
conditions.Add(condition);
List<string> strArr = new List<string> { "A", "B", "C", "D", "E", "F", "G", "H" };
IEnumerable<IEnumerable<string>> result = Process(strArr, conditions);
}
private static IEnumerable<IEnumerable<string>> Process(IEnumerable<string> strArr, List<Tuple<Expression, Expression>> conditions)
{
List<IEnumerable<string>> response = new List<IEnumerable<string>>();
int k = 0;
for (int i = 1; i <= strArr.Count(); i++)
{
k++;
var r = strArr.Combinations(Math.Min(strArr.Count(), k));
bool stop=false;
foreach (IEnumerable<string> item in r)
{
if (stop)
{
break;
}
foreach (Tuple<Expression, Expression> condition in conditions)
{
if (Enumerable.Repeat<IEnumerable<string>>(item, 1).Any(Evaluate(condition.Item1) as Func<IEnumerable<string>, bool>))
{
var initialCount = strArr.Count();
strArr = strArr.Where(Evaluate(condition.Item2) as Func<string, bool>);
i -= initialCount - strArr.Count();
stop = true;
break;
}
else
{
foreach (var item1 in r)
{
response.Add(item1);
}
}
}
}
}
return response;
}
public static object Evaluate(Expression e)
{
if (e.NodeType == ExpressionType.Constant)
return ((ConstantExpression)e).Value;
return Expression.Lambda(e).Compile().DynamicInvoke();
}
}
public static class Helper
{
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int k)
{
return k == 0 ? new[] { new T[0] } :
elements.SelectMany((e, i) =>
elements.Skip(i + 1).Combinations(k - 1).Select(c => (new[] { e }).Concat(c))
);
}
}
}
命名空间控制台应用程序
{
班级计划
{
静态void Main(字符串[]参数)
{
列表条件=新列表();
//一个复杂的条件,当前项同时包含“B”和“H”
表达式expression1=item=>item.Contains(“B”)和&item.Contains(“H”);
//用于从列表中排除元素的表达式
表达式2=j=>j!=“B”和&j!=“H”;
//将条件与排除筛选器关联
var条件=新元组(表达式1,表达式2);
条件。添加(条件);
List strArr=新列表{“A”、“B”、“C”、“D”、“E”、“F”,
public static void PermutateElements<T>(
IEnumerable<T> elements,
Predicate<IEnumerable<T>> filterGroup)
{
var chooseFrom = new LinkedList<T>(elements);
var chosen = new List<T>(chooseFrom.Count);
for (int chooseCount = 2; chooseCount < chooseFrom.Count - 1; chooseCount++)
{
Permutate(chooseFrom, chooseCount, filterGroup, chosen, 0);
}
}
static bool Permutate<T>(LinkedList<T> chooseFrom, int chooseCount,
Predicate<IEnumerable<T>> filterPermutation, IList<T> chosen, int skipLast)
{
int loopCount = chooseFrom.Count;
for (int i = 0; i < loopCount; i++)
{
var choosingNode = chooseFrom.First;
chooseFrom.RemoveFirst();
bool removeChosen = false;
if (i < loopCount - skipLast)
{
chosen.Add(choosingNode.Value);
if (chooseCount == 1)
removeChosen = filterPermutation(chosen);
else
removeChosen = Permutate(chooseFrom, chooseCount - 1, filterPermutation, chosen, skipLast + i);
chosen.RemoveAt(chosen.Count - 1);
}
if (!removeChosen)
chooseFrom.AddLast(choosingNode);
else if (chosen.Count > 0)
return true;
}
return false;
}
HashSet<char> vowels = new HashSet<char>(new char[] { 'A', 'E', 'I', 'O', 'U', 'Y' });
var results = new List<IEnumerable<char>>();
Predicate<IEnumerable<char>> processGroup = delegate(IEnumerable<char> groupElements)
{
int vowelCount = groupElements.Count(x => vowels.Contains(x));
int consonantCount = groupElements.Count(x => !vowels.Contains(x));
if (vowelCount < consonantCount && vowelCount > 0)
{
results.Add(new List<char>(groupElements));
return true;
}
else
return false;
};
var elements = new char[26];
for (int i = 0; i < elements.Length; i++)
elements[i] = (char)('A' + i);
PermutateElements(elements, processGroup);
void r_nCr(const unsigned int &startNum, const unsigned int &bitVal, const unsigned int &testNum) // Should be called with arguments (2^r)-1, 2^(r-1), 2^(n-1)
{
unsigned int n = (startNum - bitVal) << 1;
n += bitVal ? 1 : 0;
for (unsigned int i = log2(testNum) + 1; i > 0; i--) // Prints combination as a series of 1s and 0s
cout << (n >> (i - 1) & 1);
cout << endl;
if (!(n & testNum) && n != startNum)
r_nCr(n, bitVal, testNum);
if (bitVal && bitVal < testNum)
r_nCr(startNum, bitVal >> 1, testNum);
}