why*_*sai 1 c c# algorithm search
我有这个数组,例如(大小是可变的):
x = ["10111", "10122", "10250", "10113"]
Run Code Online (Sandbox Code Playgroud)
我需要找到最长的字符串,它是每个数组元素的子字符串(在本例中为"10")(它不必是字符串的前缀).我必须从所有字符串中删除它.此示例的输出将是:
x=["111","222","250","113"] //common value = "10"
Run Code Online (Sandbox Code Playgroud)
此扩展名找到最长的最常见子字符串.请注意,"1"每个字符串中包含的内容甚至更多"10".(仅限C#):
public static class StringExtensions
{
public static IEnumerable<string> GetMostCommonSubstrings(this IList<string> strings)
{
if (strings == null)
throw new ArgumentNullException("strings");
if (!strings.Any() || strings.Any(s => string.IsNullOrEmpty(s)))
throw new ArgumentException("None string must be empty", "strings");
var allSubstrings = new List<List<string>>();
for (int i = 0; i < strings.Count; i++)
{
var substrings = new List<string>();
string str = strings[i];
for (int c = 0; c < str.Length - 1; c++)
{
for (int cc = 1; c + cc <= str.Length; cc++)
{
string substr = str.Substring(c, cc);
if (allSubstrings.Count < 1 || allSubstrings.Last().Contains(substr))
substrings.Add(substr);
}
}
allSubstrings.Add(substrings);
}
if (allSubstrings.Last().Any())
{
var mostCommon = allSubstrings.Last()
.GroupBy(str => str)
.OrderByDescending(g => g.Key.Length)
.ThenByDescending(g => g.Count())
.Select(g => g.Key);
return mostCommon;
}
return Enumerable.Empty<string>();
}
}
Run Code Online (Sandbox Code Playgroud)
现在很简单:
string[] x = new[] { "10111", "10122", "10250", "10113" };
string mostCommonSubstring = x.GetMostCommonSubstrings().FirstOrDefault();
if (mostCommonSubstring != null)
{
for (int i = 0; i < x.Length; i++)
x[i] = x[i].Replace(mostCommonSubstring, "");
}
Console.Write(string.Join(", ", x));
Run Code Online (Sandbox Code Playgroud)
输出:
111, 122, 250, 113
Run Code Online (Sandbox Code Playgroud)
编辑:如果您只是想在不考虑出现频率的情况下找到最长的公共子字符串,可以使用以下方法使用此优化方法(O(n)操作)HashSet<string>:
public static string GetLongestCommonSubstring(this IList<string> strings)
{
if (strings == null)
throw new ArgumentNullException("strings");
if (!strings.Any() || strings.Any(s => string.IsNullOrEmpty(s)))
throw new ArgumentException("None string must be empty", "strings");
var commonSubstrings = new HashSet<string>(strings[0].GetSubstrings());
foreach (string str in strings.Skip(1))
{
commonSubstrings.IntersectWith(str.GetSubstrings());
if (commonSubstrings.Count == 0)
return null;
}
return commonSubstrings.OrderByDescending(s => s.Length).First();
}
public static IEnumerable<string> GetSubstrings(this string str)
{
if (string.IsNullOrEmpty(str))
throw new ArgumentException("str must not be null or empty", "str");
for (int c = 0; c < str.Length - 1; c++)
{
for (int cc = 1; c + cc <= str.Length; cc++)
{
yield return str.Substring(c, cc);
}
}
}
Run Code Online (Sandbox Code Playgroud)
以这种方式使用它:
string[] x = new[] { "101133110", "101233210", "102533010", "101331310" };
string longestCommon = x.GetLongestCommonSubstring(); // "10"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4342 次 |
| 最近记录: |