如果您能找到更好的标题,请编辑。
我首先要说的是,我已经查看了有关此主题的几个q& a,主要是this one和this article,但没有找到办法:
鉴于“HALLOWEEN”这个词,我想找到所有长度的所有排列和组合。我尝试的第一件事是迭代下面的代码,给出长度1开始并继续直到达到单词的长度(9)。
public static IEnumerable<IEnumerable<T>>
GetPermutations<T>(IEnumerable<T> list, int length)
{
if (length == 1) return list.Select(t => new T[] {t});
return GetPermutations(list, length - 1)
.SelectMany(t => list.Where(e => !t.Contains(e)),
(t1, t2) => t1.Concat(new T[] {t2}));
}
这给了我意想不到的结果,因为双'E'和'L'被省略,最后的设置很短。
一个更简单的例子可能是'妈妈'{M,O,M},其中最终结果将是:
中号
0
MO
OM
MM
妈妈
MMO
OMM
请注意,我希望看到两个'M'可用,但我不希望看到“MMM”。由于离开原始顺序(1,2,3),“MOM”将在结果中出现两次,并且交换位置1和3(3,2,1)将导致'M','O','M'但这个字符序列只出现一次是结果列表(可以通过字符串比较完成)
再次,使用set {1,1,2,3},我希望看到:
{1,1}
但不是{2,2}或{3,3}
答案 0 :(得分:1)
这是另一个应该清晰且易于理解的解决方案:
public static IEnumerable<string> GetPermutations(string input)
{
if (string.IsNullOrEmpty(input))
{
return new List<string>();
}
var length = input.Length;
var indices = Enumerable.Range(0, length).ToList();
var permutationsOfIndices = GetNumericalPermutations(indices, length);
var permutationsOfInput = permutationsOfIndices.Select(x => new string(x.Select(y => input[y]).ToArray()))
.Distinct();
return permutationsOfInput;
}
private static List<List<int>> GetNumericalPermutations(List<int> values, int maxLength)
{
if (maxLength == 1)
{
return values.Select(x => new List<int>{x}).ToList();
}
else
{
var permutations = GetNumericalPermutations(values, maxLength - 1);
foreach (var index in values)
{
var newPermutations = permutations.Where(x => !x.Contains(index))
.Select(x => x.Concat(new List<int> { index }))
.Where(x => !permutations.Any(y => y.SequenceEqual(x)))
.Select(x => x.ToList())
.ToList();
permutations.AddRange(newPermutations);
}
return permutations;
}
}
例如,&#34; MOM&#34;的输出是:
M
O
OM
MM
MO
MMO
OMM
MOM
答案 1 :(得分:0)
我建议查看字母位置0,1,2,3,4等的排列,将它们映射到字母,然后消除重复。
在不更改GetPermutations函数的情况下,我添加了另一个函数来获取字母位置的排列,将这些结果映射到字符串,然后消除重复项。
cordova plugin add cordova-plugin-whitelist --save
答案 2 :(得分:0)
这很好用:
Func<string, IEnumerable<string>> getAllSubsets = null;
getAllSubsets = x =>
(x == null || !x.Any())
? Enumerable.Empty<string>()
: (x.Length > 1
? getAllSubsets(x.Substring(1))
.SelectMany(y => new [] { y, x.Substring(0, 1) + y })
: new [] { "", x.Substring(0, 1) });
所以给定getAllSubsets("ABC")
我得到:
&#34;&#34;,&#34; A&#34;,&#34; B&#34;,&#34; AB&#34;,&#34; C&#34;,&# 34; AC&#34;,&#34; BC&#34;,&#34; ABC&#34;
而且,对于您的"MOM"
示例,我得到了:
&#34;&#34;,&#34; M&#34;,&#34; O&#34;,&#34; MO&#34;,&#34; M&#34;,&# 34; MM&#34;,&#34; OM&#34;,&#34; MOM&#34;
如果需要,过滤掉空字符串并重复值将是微不足道的,但是当它立即严格产生所有子集时。
答案 3 :(得分:0)
我认为通常最好避免产生和消除排列。像“aaaaaaaaaaaaaaab”这样的文字可以产生大量的重复。
public static IEnumerable<IEnumerable<T>>
GetPermutationsInner<T>(IEnumerable<IGrouping<T, T>> groupedList, int length)
{
if (length == 1) return groupedList.Select(t => new T[] { t.Key });
return GetPermutationsInner<T>(groupedList, length - 1)
.SelectMany(t => groupedList
.Where(e => t.Count(w => w.Equals(e.Key)) < e.Count())
.Select(s => s.Key),
(t1, t2) => t1.Concat(new T[] { t2 }));
}
public static IEnumerable<IEnumerable<T>>
GetPermutations<T>(IEnumerable<T> list)
{
var resultList = new List<IEnumerable<T>>();
for (int i = 1; i <= list.Count(); ++i)
{
resultList.AddRange(GetPermutationsInner<T>(list.GroupBy(g => g), i));
}
return resultList;
}