use*_*334 26 c# string pattern-matching
我有4个字符串:
"h:/a/b/c"
"h:/a/b/d"
"h:/a/b/e"
"h:/a/c"
Run Code Online (Sandbox Code Playgroud)
我想找到这些字符串的公共前缀,即"h:/a".怎么找到?
通常我会用分隔符拆分字符串'/'并将其放在另一个列表中,依此类推.
有没有更好的方法呢?
dtb*_*dtb 35
string[] xs = new[] { "h:/a/b/c", "h:/a/b/d", "h:/a/b/e", "h:/a/c" };
string x = string.Join("/", xs.Select(s => s.Split('/').AsEnumerable())
.Transpose()
.TakeWhile(s => s.All(d => d == s.First()))
.Select(s => s.First()));
Run Code Online (Sandbox Code Playgroud)
同
public static IEnumerable<IEnumerable<T>> Transpose<T>(
this IEnumerable<IEnumerable<T>> source)
{
var enumerators = source.Select(e => e.GetEnumerator()).ToArray();
try
{
while (enumerators.All(e => e.MoveNext()))
{
yield return enumerators.Select(e => e.Current).ToArray();
}
}
finally
{
Array.ForEach(enumerators, e => e.Dispose());
}
}
Run Code Online (Sandbox Code Playgroud)
Yeg*_*gor 18
我的一个简短的LINQy解决方案.
var samples = new[] { "h:/a/b/c", "h:/a/b/d", "h:/a/b/e", "h:/a/e" };
var commonPrefix = new string(
samples.First().Substring(0, samples.Min(s => s.Length))
.TakeWhile((c, i) => samples.All(s => s[i] == c)).ToArray());
Run Code Online (Sandbox Code Playgroud)
Sam*_*der 15
只需循环最短字符串的字符,并将每个字符与其他字符串中相同位置的字符进行比较.虽然他们都匹配继续前进.只要一个不匹配,那么直到当前位置-1的字符串就是答案.
像(伪代码)的东西
int count=0;
foreach(char c in shortestString)
{
foreach(string s in otherStrings)
{
if (s[count]!=c)
{
return shortestString.SubString(0,count-1); //need to check count is not 0
}
}
count+=1;
}
return shortestString;
Run Code Online (Sandbox Code Playgroud)
基于Sam Holder解决方案的工作代码(注意它给出h:/ a/not h:/ a作为问题中最长的公共初始子字符串):
using System;
namespace CommonPrefix
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(CommonPrefix(new[] { "h:/a/b/c", "h:/a/b/d", "h:/a/b/e", "h:/a/c" })); // "h:/a/"
Console.WriteLine(CommonPrefix(new[] { "abc", "abc" })); // "abc"
Console.WriteLine(CommonPrefix(new[] { "abc" })); // "abc"
Console.WriteLine(CommonPrefix(new string[] { })); // ""
Console.WriteLine(CommonPrefix(new[] { "a", "abc" })); // "a"
Console.WriteLine(CommonPrefix(new[] { "abc", "a" })); // "a"
Console.ReadKey();
}
private static string CommonPrefix(string[] ss)
{
if (ss.Length == 0)
{
return "";
}
if (ss.Length == 1)
{
return ss[0];
}
int prefixLength = 0;
foreach (char c in ss[0])
{
foreach (string s in ss)
{
if (s.Length <= prefixLength || s[prefixLength] != c)
{
return ss[0].Substring(0, prefixLength);
}
}
prefixLength++;
}
return ss[0]; // all strings identical up to length of ss[0]
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是最常见的子字符串问题(虽然它只是一个稍微专业的情况,因为您似乎只关心前缀)..NET平台中没有可以直接调用的算法库实现,但是这里链接的文章充满了你自己如何做的步骤.