C# 在C中搜索数组中字符串的开头#

C# 在C中搜索数组中字符串的开头#,c#,.net,arrays,string,C#,.net,Arrays,String,我有一个包含很多路径的列表。我有一个特定的路径,我想对照此列表检查是否有使用此路径的路径,即: f.StartsWith(r.FILENAME) && f != r.FILENAME 最快的方法是什么 编辑:根据以下答案完成功能: static bool ContainsFragment(string[] paths, string fragment) { // paths **must** be pre-sorted via Array.Sort(paths);

我有一个包含很多路径的列表。我有一个特定的路径,我想对照此列表检查是否有使用此路径的路径,即:

f.StartsWith(r.FILENAME) && f != r.FILENAME
最快的方法是什么

编辑:根据以下答案完成功能:

static bool ContainsFragment(string[] paths, string fragment)
{
    // paths **must** be pre-sorted via Array.Sort(paths);
    if (paths.Length == 0) return false;
    int index = Array.BinarySearch(paths, fragment);
    if (index >= 0 && index+1 < paths.Length)
    { //we found it 
        if (paths[index + 1].StartsWith(fragment) &&
            paths[index + 1].EndsWith(".manifest"))
        {
            return true;
        }
    }
    return false;
}
静态bool包含片段(字符串[]路径,字符串片段)
{
//路径**必须**通过数组预排序。排序(路径);
if(path.Length==0)返回false;
int index=Array.BinarySearch(路径、片段);
如果(索引>=0&&index+1
最快的方法可能是二进制搜索:

static bool ContainsFragment(string[] paths, string fragment)
{
    // paths **must** be pre-sorted via Array.Sort(paths);
    if (paths.Length == 0) return false;
    int index = Array.BinarySearch(paths, fragment);
    // we want the index of the *next highest* path
    if (index < 0) { // no match
        index = ~index; 
    } else { // exact match
        index++; // for strict substring (non-equal)
    }
    return index < paths.Length && paths[index].StartsWith(fragment);
}
静态bool包含片段(字符串[]路径,字符串片段)
{
//路径**必须**通过数组预排序。排序(路径);
if(path.Length==0)返回false;
int index=Array.BinarySearch(路径、片段);
//我们需要*次高*路径的索引
如果(索引<0){//不匹配
索引=~index;
}else{//精确匹配
index++;//用于严格子字符串(非相等)
}
返回索引
但是,如果只进行几次排序,排序数组的成本将超过任何好处;在这种情况下,只需扫描阵列-使用LINQ等,或者只需:

bool found = false;
for(int i = 0 ; i < paths.Length ; i++) {
    if(paths[i].StartsWith(fragment) &&
          paths[i].Length != fragment.Length)
    {
        found = true;
        break;
    }
}
boolfound=false;
for(int i=0;i
或者如果你只关心存在:

bool any = list.Any(f => f.StartsWith(r.FILENAME) && f != r.FILENAME);

诚然,这是假设您使用的是.NET 3.5,否则在
列表中有类似的方法,您可以使用匿名方法。

我发现这个相对简单的问题的有趣之处在于“有效”答案的数量,这取决于您如何定义“最快”

  • 如果faster意味着“成本最低”,那么Marc的二进制搜索方法听起来就像你的答案
  • 如果faster表示“最快实现”,那么Jon的
    列表。任何
    方法调用都是合适的
  • 如果faster的意思是“蛮力”,那么您可能需要考虑并行化搜索。就所需的处理而言,它的成本更高,但根据您的服务器资源,执行速度可能更快。为您提供了一个很好的起点

支票的金额将从50000到几十万次不等,因此这类支票是值得的。我想要的是,如果有任何点击不是完全匹配的(总是会有完全匹配),而是一个开始相同但不完全相同的匹配。我仍然觉得这不是最快的方法,因为我相信我们仍然在数组中循环,直到找到我们想要的匹配。不,二进制搜索不会循环-它是一半。因此,它将在15个步骤中搜索50000个。我怀疑(因为总是会有一个精确的匹配)你还需要在匹配后检查下一个项目…如果你在我的问题中看到,我已经更新了一个功能,我相信它会工作。我不太明白你怎么处理index=~index;最后一个返回语句实际上与代码非常相似;如果找不到,~index返回下一项的索引-与代码中的“index+1”相同。在我的“Find a match”版本中,我只使用了index++,但结果是一样的。这并不比执行简单的for循环快,甚至可能更慢。(注意,我更新了你的评论)你是完全正确的。我的问题可能是“成本最低”和“暴力”的结合。在这里的一个示例中,我需要比较250000条记录(即集合中的每条记录,如果记录集中有另一条开始相同但较长的记录,则为se)。(在下一条注释中继续)我需要按顺序输出记录,但检查顺序不相关。因此,也许将Marc的二进制搜索和多线程方法结合起来是最好的。PLINQ可能会自动为我做这件事,但我有我的疑问:)谢谢你的提示。PLINQ只会并行化迭代,这可以加快某些搜索算法。如果列表已经排序,二进制搜索是最好的选择,并且不能并行化。但是,排序可以。您可能想提出另一个问题,询问250k记录列表的最佳排序算法。多处理器/内核的可用性将比搜索对这一点产生更大的影响。
bool any = list.Any(f => f.StartsWith(r.FILENAME) && f != r.FILENAME);