正如标题所述,我有一个任务来查找字符串中最长的重复序列,并且只能使用linq完成-否ifs,不循环,不尝试,赋值仅允许在变量初始化时进行,递归是允许的。我已经在网上找到了解决方案,并且我了解发生了什么,但是我无法将其转换为linq-我对此并不熟悉。如果有人可以帮助我,我将不胜感激。这是我找到的-https://www.javatpoint.com/program-to-find-longest-repeating-sequence-in-a-string的链接。
List<int> a = new List<int> {1, 2, 1, 2, 1, 2, 3, 2, 1, 2};
List<List<int>> aa = new List<List<int>>();
outerLoop(a);
var max = aa.Max(x => x.Count);
var m = from v in aa
where v.Count == max
select v;
m.Dump();
void outerLoop(List<int> list)
{
List<int> f = new List<int>();
f.AddRange(list.Skip(list.Count-1).Take(list.Count).ToList());
innerLoop(list, list.Skip(1).Take(list.Count).ToList());
f.ForEach(k => outerLoop(list.Skip(1).Take(list.Count).ToList()));
}
void innerLoop(List<int> l, List<int> subList)
{
List<int> f = new List<int>();
f.AddRange(subList.Skip(subList.Count-1).Take(subList.Count).ToList());
var tt = l.TakeWhile((ch, i) => i < subList.Count && subList[i] == ch).ToList();
aa.Add(tt);
f.ForEach(k => innerLoop(l, subList.Skip(1).Take(subList.Count).ToList()));
}
所以我想出了这个“美”,我认为它不是很好的代码,但我认为它可以工作。如果有人有兴趣并想提出改善建议,欢迎他们::
如果输入为int[] x= {1, 2, 1, 2, 1, 2, 3, 2, 1, 2}
结果应该是1212
答案 0 :(得分:0)
尝试一下:
List<int> words = new List<int> { 1, 2, 1, 2, 1, 2, 3, 2, 1, 2 };
string result =
words
.Select((c, i) => i)
.SelectMany(i => Enumerable.Range(1, words.Count - i).Select(j => words.Skip(i).Take(j)), (i, w) => new { i, w })
.GroupBy(x => String.Join(",", x.w), x => x.i)
.Where(x => x.Skip(1).Any())
.Select(x => x.Key)
.OrderByDescending(x => x.Length)
.First();
那给了我1,2,1,2
。
如果您想要一个真正适用于字符串的字符串,请尝试以下操作:
var word = "supercalifragilisticexpialidocious";
string result =
word
.Select((c, i) => i)
.SelectMany(i => Enumerable.Range(1, word.Length - i).Select(j => word.Skip(i).Take(j)), (i, w) => new { i, w })
.GroupBy(x => new string(x.w.ToArray()), x => x.i)
.Where(x => x.Skip(1).Any())
.Select(x => x.Key)
.OrderByDescending(x => x.Length)
.First();
那给了我ali
。
这是一个稍微容易理解的版本:
var word = "supercalifragilisticexpialidocious";
string result =
(
from i in Enumerable.Range(0, word.Length)
from j in Enumerable.Range(1, word.Length - i)
group i by word.Substring(i, j) into gis
where gis.Skip(1).Any()
orderby gis.Key.Length descending
select gis.Key
).First();
答案 1 :(得分:0)
这是我的版本。它不是单个LINQ表达式,但仅使用LINQ。如果有多个答案,它将返回所有相同长度的子序列。它应该适用于任何类型的序列。它被编写为仅使用标准的LINQ方法。
它使用带有字符串键的GroupBy
来实现序列Distinct
。 (由于这个技巧,包含逗号的项目列表可能无法正常工作。)在生产代码中,对于基于Distinct
的序列,我将使用IEqualityComparer
和SequenceEqual
。在生产代码中,我将使用MaxBy
扩展名。它还有一个单独的步骤,用于找到最大重复序列长度,然后找到所有匹配的序列。
更新:由于我在GroupBy
中使用DistinctBy
,所以我意识到我可以使用它直接计算子序列重复数,而不必搜索它们。
var repeaters = Enumerable.Range(0, words.Count) // starting positions
.SelectMany(n => Enumerable.Range(1, (words.Count - n) / 2).Select(l => words.Skip(n).Take(l).ToList())) // subseqs from each starting position
.GroupBy(s => String.Join(",", s), (k, sg) => new { seq = sg.First(), Repeats = sg.Count() }) // count each sequence
.Where(sr => sr.Repeats > 1) // only keep repeated sequences
.Select(sr => sr.seq); // no longer need counts
var maxRepeaterLen = repeaters.Select(ss => ss.Count()).Max(); // find longest repeated sequence's length
var maxLenRepeaters = repeaters.Where(ss => ss.Count() == maxRepeaterLen); // return all sequences matching longest length