我有一个字符串例如
string text = "xfoofoobarbar fooxxfoo barxxxfoo";
此字符串包含5x foo
,这是最长,其中最多出现重复的子字符串 ,其中包含至少2个字符 字符串所以这是我想要的结果。
bar
只出现3次,因此不是最常出现的子字符串oo
在字符串中也是5倍,但foo
更长 - 所以foo
更喜欢XababaY
会导致ab
存在2x(不重叠,2x ba
被忽略,因为ab
首先出现)XaaaaaaaY
会导致aa
,因为aa
出现3次且重复次数最多。我很想展示一些迄今为止我尝试过的方法,但我老实说不知道从哪里开始。 LINQ?正则表达式?
正确方向的提示/方法对我也有帮助。
答案 0 :(得分:2)
我想说从这里开始的第一个地方是从长度为2的输入到输入长度的所有可能的子串生成列表:
string text = "xfoofoobarbar fooxxfoo barxxxfoo";
var allSubstrings = Enumerable.Range(2,text.Length)
.ToDictionary(k => k,v => FindSubStrings(text,v));
...
IEnumerable<string> FindSubStrings(string input, int length)
{
for(var i=0;i<input.Length-length;i++)
{
yield return input.Substring(i,length);
}
}
实例:http://rextester.com/ZUR68480
从那里应该就像通过子串分组来获取计数一样简单,并且适当地排序结果。但是你的要求似乎在最长的长度和#34;之间进行选择。和&#34;大多数事件&#34;,你不能同时拥有它们!
以下是我的全面实施,我应该指出,目前选择xfoo
作为获胜者。
public static void Main(string[] args)
{
string text = "xfoofoobarbar fooxxfoo barxxxfoo";
var allSubstrings = Enumerable.Range(2,text.Length-2)
.Select(x => {
var longestSub = FindSubStrings(text,x).GroupBy(y => y).OrderByDescending(y => y.Count()).FirstOrDefault();
return new Substrings {
Length = x,
Count = longestSub.Count(),
Value = longestSub.Key
};
});
foreach(var item in allSubstrings)
{
Console.WriteLine(item.Length + ":" + item.Count + ":" + item.Value);
}
var best = allSubstrings.Where(x => x.Count>1).OrderByDescending(x => x.Length).ThenByDescending(x => x.Count).First();
Console.WriteLine("Longest, most frequest substring is " + best.Value);
}
public class Substrings
{
public int Length{get;set;}
public int Count{get;set;}
public string Value{get;set;}
}
private static IEnumerable<string> FindSubStrings(string input, int length)
{
for(var i=0;i<input.Length-length;i++)
{
yield return input.Substring(i,length);
}
}