繁体   English   中英

在string中搜索多个字符串

[英]Search multiple strings in string

在给定的字符串中,很容易搜索第一次出现的子字符串,如下所示:

int position = "01234".IndexOf ("23"); // returns 2

我想搜索多个可能的字符串中的任何一个的第一次出现:

var options = new [] {"77", "34", "12"};
int position = "01234".ImaginaryIndexOf (options); // should return 1

这样的函数似乎不存在于.NET框架中。 我错过了吗?

编辑:为了澄清,我正在寻找一种适用于大输入和不均匀分布选项的方法。 想象一下类似的东西

var options = new [] {"x", "y"};
new String ('x', 1000*1000).IndexOf (options)

没有我知道的内置方法..

但是为了这样做,您可以迭代所有options并为每个options计算IndexOf 然后检索不是-1的最小值(“未找到”):

int position = options.Select(o => "01234".IndexOf(o))
                      .OrderBy(i =>i).FirstOrDefault(i=> i != -1);

或者代替排序(即O(nlogn) )找到最小值( O(n) ):

int position = options.Select(o => "01234".IndexOf(o))
                      .Where(i => i != -1).DefaultIfEmpty(-1).Min();

至于编辑你可以考虑构建和后缀树数组 - 数组包含m个项目,其中m是options词的首字母的不同数量。 作为一般例子:

如果选项是: "some", "word", "something", "other"那么你构建:

    0        1        2...
 +-----------------------+
 |  s    |   w    |   o  |
 +- | ------ | ------ | -+
    o        o        t
    |        |        |
    m        r        h
    |        |        |
    e        d        e
   / \       |        |
  $   t      r        $
      |      |
      ...    $

然后迭代你的字符串,并为每个字母检查它是否在数组中。 如果没有继续下一个。 如果是,那么您可以在嵌套树中加深并检查字符串的下一个字母与树中的下一个级别相比较。 如果在主字符串的末尾没有到达任何$则文本中没有options 当然,您可以将数组作为HashSet<T>来改进对单词的第一个字母的搜索。

也许是这样的;

var options = new[] { "77", "34", "12" };
var position = options.Select(x => "01234".IndexOf(x))
    .Where(x => x > -1).OrderBy(x => x).DefaultIfEmpty(-1)
    .FirstOrDefault();

您可以定义字符串扩展名;

public static class StringExtensions
{
    public static int ImaginaryIndexOf(this string str,IEnumerable<string> options)
    {
        return options.Select(x => str.IndexOf(x))
            .Where(x => x > -1).OrderBy(x => x)
            .DefaultIfEmpty(-1).FirstOrDefault();
    }
}

然后;

var options = new[] { "77", "34", "12" };
"01234".ImaginaryIndexOf(options);

您好我们可以通过使用for循环或使用正则表达式解决这个问题。尝试以下代码我用于循环查找第一次出现的字符串的索引。

var options = new[] { "77", "34", "12" };
        for (int i = 0; i < options.Length; i++)
        {
            //MessageBox.Show(options[i].ToString); 
            int p

 var options = new[] { "77", "34", "12" }; for (int i = 0; i < options.Length; i++) { int position = "770123473673412".IndexOf(options[i].ToString()); MessageBox.Show(position.ToString()); } 

一些LINQ非常简单。 棘手的部分是处理-1 ...但是如果你理解了无符号和有符号整数,你可以通过强制转换使这个问题消失。

static class StringExtensions
{
    public static int ImaginaryIndexOf(this string input, IEnumerable<string> searchFor)
    {
        return (int)searchFor
            .Select
            (
                s => (uint)input.IndexOf(s) 
            )
            .Min();
    }
}

在DotNetFiddle上试一试

作为替代解决方案,您可以使用Regex

string input = "01234";
var rgex = new System.Text.RegularExpressions.Regex("(77|34|12)");
var match = rgex.Match(input);
int position = match.Success ? match.Index : -1;

您好我们可以通过使用for循环或使用正则表达式解决这个问题。尝试以下代码我用于循环查找第一次出现的字符串的索引。

 var options = new[] { "77", "34", "12" }; for (int i = 0; i < options.Length; i++) { int position = "770123473673412".IndexOf(options[i].ToString()); MessageBox.Show(position.ToString()); } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM