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

时间:2009-02-12 11:41:18

标签: c# .net arrays string

我有一个包含很多路径的List。我有一个特定的路径,我想检查这个列表,看看是否有任何路径使用此路径,即:

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;
}

3 个答案:

答案 0 :(得分:7)

最快的方式可能是二进制搜索:

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);
}

但如果你只做了几次,那么排序阵列的成本将超过任何好处;在这种情况下,只需扫描数组 - 使用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;
    }
}

答案 1 :(得分:3)

var matches = list.Where(f => f.StartsWith(r.FILENAME) && f != r.FILENAME);

或者如果你只关心存在:

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

假设你正在使用.NET 3.5,否则List<T>中有类似的方法,你可以使用匿名方法。

答案 2 :(得分:2)

我觉得有趣的是这个相对简单的问题是“有效”答案的数量,取决于你如何定义“最快”。

  • 如果最快意味着“成本最低”,那么Marc的二元搜索方法就像你的回答一样。
  • 如果最快意味着“最快实施”,那么Jon的list.Any方法调用是合适的。
  • 如果最快意味着“蛮力”,那么您可能想要查看并行化搜索。在处理所需的方面成本会更高,但可能会根据您的服务器资源更快地执行。 PLINQ为您提供了一个很好的起点。