C# 动态嵌套循环以生成c中所有可能的数组元素组合#
我在stackoverflow和web上搜索过类似的问题,但没有找到我需要的解决方案 我正在编写一个代码列表生成器 例如,我有一个字符列表,比如C# 动态嵌套循环以生成c中所有可能的数组元素组合#,c#,.net,arrays,loops,dynamic,C#,.net,Arrays,Loops,Dynamic,我在stackoverflow和web上搜索过类似的问题,但没有找到我需要的解决方案 我正在编写一个代码列表生成器 例如,我有一个字符列表,比如List{'a',b',c'} 我有两个设置,比如(int)minLength的2和(int)maxLength的3 我想要这个输出: aa ab ac ba bb bc ca cb cc aaa aab aac aba abb abc aca acb acc baa bab bac bba bbb bbc bca bcb bcc caa cab
List{'a',b',c'}代码>
我有两个设置,比如(int)minLength
的2
和(int)maxLength
的3
我想要这个输出:
aa
ab
ac
ba
bb
bc
ca
cb
cc
aaa
aab
aac
aba
abb
abc
aca
acb
acc
baa
bab
bac
bba
bbb
bbc
bca
bcb
bcc
caa
cab
cac
cba
cbb
cbc
cca
ccb
ccc
在gereral中,我只需要创建多维循环,但由于minLength、maxLength和charList的值不同,我必须动态地创建多维循环
因此,我使用了一个“自调用函数”,如以下示例:
private void loop() {
for( int i = 0; i < num; i++ ) {
// stuff
loop();
}
}
我想我刚才犯了一个思维错误,不是吗
伙计们,你们有什么好建议吗
我还研究了笛卡尔积,但我认为它不能只使用一个数组
thx提供任何帮助。您可以使用回溯算法,代码如下。还包括输出,以证明代码有效
如果需要将参数传递给线程,请参阅
您可以使用回溯算法,代码如下。还包括输出,以证明代码有效
如果需要将参数传递给线程,请参阅
下面是一个使用递归生成它的示例
IEnumerable<string> GenerateCode(int length, int min, IEnumerable<char> chars)
{
if (length == 0)
{
yield return string.Empty;
yield break;
}
foreach (var mid in GenerateCode(length - 1, min, chars))
{
foreach (var c in chars)
{
var t = mid + c;
if (length >= min)
Console.WriteLine(t); // replace with where you want to put the results
yield return t;
}
}
}
// now call this method:
GenerateCode(3 /*max length*/, 2 /*min length*/, new [] { 'a', 'b', 'c' });
IEnumerable生成代码(int-length、int-min、IEnumerable-chars)
{
如果(长度==0)
{
返回字符串。为空;
屈服断裂;
}
foreach(生成代码中的变量中间值(长度-1,最小,字符))
{
foreach(以字符表示的变量c)
{
var t=中间+c;
如果(长度>=min)
Console.WriteLine(t);//替换为要放置结果的位置
收益率t;
}
}
}
//现在调用此方法:
生成代码(3/*最大长度*/,2/*最小长度*/,新[]{'a','b','c'});
但是,除非这是一个练习,否则为什么要生成所有可能的变化?如果您提供实际需求,可能会有更好的解决方案。下面是一个使用递归生成的示例
IEnumerable<string> GenerateCode(int length, int min, IEnumerable<char> chars)
{
if (length == 0)
{
yield return string.Empty;
yield break;
}
foreach (var mid in GenerateCode(length - 1, min, chars))
{
foreach (var c in chars)
{
var t = mid + c;
if (length >= min)
Console.WriteLine(t); // replace with where you want to put the results
yield return t;
}
}
}
// now call this method:
GenerateCode(3 /*max length*/, 2 /*min length*/, new [] { 'a', 'b', 'c' });
public static IEnumerable<IEnumerable<T>> Permutations<T>(IEnumerable<T> source)
{
if (source == null)
throw new ArgumentNullException("source");
return permutations(source.ToArray());
}
private static IEnumerable<IEnumerable<T>> permutations<T>(IEnumerable<T> source)
{
IEnumerable<T> enumerable = source as List<T> ?? source.ToList();
var c = enumerable.Count();
if (c == 1)
yield return enumerable;
else
for (int i = 0; i < c; i++)
foreach (var p in permutations(enumerable.Take(i).Concat(enumerable.Skip(i + 1))))
yield return enumerable.Skip(i).Take(1).Concat(p);
}
private static IEnumerable<string> Subsets(char[] chars)
{
List<string> subsets = new List<string>();
for (int i = 1; i < chars.Length; i++)
{
subsets.Add(chars[i - 1].ToString(CultureInfo.InvariantCulture));
int i1 = i;
List<string> newSubsets = subsets.Select(t => t + chars[i1]).ToList();
subsets.AddRange(newSubsets);
}
subsets.Add(chars[chars.Length - 1].ToString(CultureInfo.InvariantCulture));
return subsets;
}
private static void Main()
{
char[] chars = new[]{'a','b','c'};
var subsets = Subsets(chars);
List<string> allPossibleCombPerm =
subsets.SelectMany(Permutations).Select(permut => string.Join("", permut)).ToList();
allPossibleCombPerm.ForEach(Console.WriteLine);
}
IEnumerable生成代码(int-length、int-min、IEnumerable-chars)
{
如果(长度==0)
{
返回字符串。为空;
屈服断裂;
}
foreach(生成代码中的变量中间值(长度-1,最小,字符))
{
foreach(以字符表示的变量c)
{
var t=中间+c;
如果(长度>=min)
Console.WriteLine(t);//替换为要放置结果的位置
收益率t;
}
}
}
//现在调用此方法:
生成代码(3/*最大长度*/,2/*最小长度*/,新[]{'a','b','c'});
但是,除非这是一个练习,否则为什么要生成所有可能的变化?如果您提供实际需求,可能会有更好的解决方案。公共静态IEnumerable置换(IEnumerable源代码)
public static IEnumerable<IEnumerable<T>> Permutations<T>(IEnumerable<T> source)
{
if (source == null)
throw new ArgumentNullException("source");
return permutations(source.ToArray());
}
private static IEnumerable<IEnumerable<T>> permutations<T>(IEnumerable<T> source)
{
IEnumerable<T> enumerable = source as List<T> ?? source.ToList();
var c = enumerable.Count();
if (c == 1)
yield return enumerable;
else
for (int i = 0; i < c; i++)
foreach (var p in permutations(enumerable.Take(i).Concat(enumerable.Skip(i + 1))))
yield return enumerable.Skip(i).Take(1).Concat(p);
}
private static IEnumerable<string> Subsets(char[] chars)
{
List<string> subsets = new List<string>();
for (int i = 1; i < chars.Length; i++)
{
subsets.Add(chars[i - 1].ToString(CultureInfo.InvariantCulture));
int i1 = i;
List<string> newSubsets = subsets.Select(t => t + chars[i1]).ToList();
subsets.AddRange(newSubsets);
}
subsets.Add(chars[chars.Length - 1].ToString(CultureInfo.InvariantCulture));
return subsets;
}
private static void Main()
{
char[] chars = new[]{'a','b','c'};
var subsets = Subsets(chars);
List<string> allPossibleCombPerm =
subsets.SelectMany(Permutations).Select(permut => string.Join("", permut)).ToList();
allPossibleCombPerm.ForEach(Console.WriteLine);
}
{
if(source==null)
抛出新的ArgumentNullException(“源”);
返回置换(source.ToArray());
}
私有静态IEnumerable置换(IEnumerable源)
{
IEnumerable enumerable=源作为列表??source.ToList();
var c=可枚举的.Count();
如果(c==1)
收益率可枚举;
其他的
对于(int i=0;it+chars[i1]).ToList();
子集合AddRange(新子集合);
}
Add(chars[chars.Length-1].ToString(CultureInfo.InvariantCulture));
返回子集;
}
私有静态void Main()
{
char[]chars=new[]{'a','b','c'};
var子集=子集(字符);
列出所有可能的密码=
subset.SelectMany(排列).Select(排列=>string.Join(“,排列)).ToList();
AllpossibleComperm.ForEach(Console.WriteLine);
}
公共静态IEnumerable置换(IEnumerable源)
{
if(source==null)
抛出新的ArgumentNullException(“源”);
返回置换(source.ToArray());
}
私有静态IEnumerable置换(IEnumerable源)
{
IEnumerable enumerable=源作为列表??source.ToList();
var c=可枚举的.Count();
如果(c==1)
收益率可枚举;
其他的
对于(int i=0;it+chars[i1]).ToList();
子集合AddRange(新子集合);
}
Add(chars[chars.Length-1].ToString(CultureInfo.InvariantCulture));
返回子集;
}
私有静态void Main()
{
char[]chars=new[]{'a','b','c'};
var子集=子集(字符);
列出所有可能的密码=
subset.SelectMany(排列).Select(排列=>string.Join(“,排列)).ToList();
AllpossibleComperm.ForEach(Console.WriteLine);
}
您可以使用以下功能。T是将组合到字符串中的元素类型(将对每个项调用ToString()。您可以选择为表示组合的字符串使用前缀和分隔符,使它们看起来像myprefix_a_1、myprefix_a_2等,其中u将是分隔符
必须使用level=1和tmpList=null调用此函数
public static IEnumerable<string> Combine<T>(string prefix,
string separator,
List<List<T>> collections,
int level, List<string> tmpList)
{
if (separator == null)
separator = "";
if (prefix == null)
prefix = "";
List<string> nextTmpList = new List<string>();
int length = collections.Count();
if (tmpList == null || tmpList.Count == 0)
{
tmpList = new List<string>();
foreach (var ob in collections.Last())
tmpList.Add(ob.ToString());
}
if(length == level)
{
foreach (string s in tmpList)
nextTmpList.Add(prefix + separator + s.ToString());
return nextTmpList;
}
foreach (var comb in tmpList)
foreach(var ob in collections[length - level - 1])
nextTmpList.Add(ob.ToString() + separator + comb);
return Combine(prefix, separator, collections, level + 1, nextTmpList);
}
你可以帮助我们
public static IEnumerable<IEnumerable<T>> Permutations<T>(IEnumerable<T> source)
{
if (source == null)
throw new ArgumentNullException("source");
return permutations(source.ToArray());
}
private static IEnumerable<IEnumerable<T>> permutations<T>(IEnumerable<T> source)
{
IEnumerable<T> enumerable = source as List<T> ?? source.ToList();
var c = enumerable.Count();
if (c == 1)
yield return enumerable;
else
for (int i = 0; i < c; i++)
foreach (var p in permutations(enumerable.Take(i).Concat(enumerable.Skip(i + 1))))
yield return enumerable.Skip(i).Take(1).Concat(p);
}
private static IEnumerable<string> Subsets(char[] chars)
{
List<string> subsets = new List<string>();
for (int i = 1; i < chars.Length; i++)
{
subsets.Add(chars[i - 1].ToString(CultureInfo.InvariantCulture));
int i1 = i;
List<string> newSubsets = subsets.Select(t => t + chars[i1]).ToList();
subsets.AddRange(newSubsets);
}
subsets.Add(chars[chars.Length - 1].ToString(CultureInfo.InvariantCulture));
return subsets;
}
private static void Main()
{
char[] chars = new[]{'a','b','c'};
var subsets = Subsets(chars);
List<string> allPossibleCombPerm =
subsets.SelectMany(Permutations).Select(permut => string.Join("", permut)).ToList();
allPossibleCombPerm.ForEach(Console.WriteLine);
}
public static IEnumerable<string> Combine<T>(string prefix,
string separator,
List<List<T>> collections,
int level, List<string> tmpList)
{
if (separator == null)
separator = "";
if (prefix == null)
prefix = "";
List<string> nextTmpList = new List<string>();
int length = collections.Count();
if (tmpList == null || tmpList.Count == 0)
{
tmpList = new List<string>();
foreach (var ob in collections.Last())
tmpList.Add(ob.ToString());
}
if(length == level)
{
foreach (string s in tmpList)
nextTmpList.Add(prefix + separator + s.ToString());
return nextTmpList;
}
foreach (var comb in tmpList)
foreach(var ob in collections[length - level - 1])
nextTmpList.Add(ob.ToString() + separator + comb);
return Combine(prefix, separator, collections, level + 1, nextTmpList);
}
Combine<int>("G1", "_", new List<List<int>>() { new List<int>() { 1, 3}, new List<int>() {2, 4 } }, 1, null);
G1_1_2 G1_3_2 G1_1_4 G1_3_4