【问题标题】:How to replace large count of string values from list found in the string如何从字符串中找到的列表中替换大量字符串值
【发布时间】:2017-05-17 02:33:41
【问题描述】:

如果我得到大约 2000 个字符串值的列表,我想知道什么是快速且正确的方法:

 List<string> strList = new List<string>();  

例如:

for (int i = 1; i <= 2000; i++)
{
    strList.Add("a" + i);
}

如果找到相等的值,我想替换每个输入字符串:

string inputStr = "a1 a5 a80 a80 m124 a34 a300 e12 s00";

如果 strList 中有两千个值的任何单词,例如 if (strList.Any(inputStr.Contains)),那么我想要 inputStr.Replace"" 空白空间,那么所需的输出应该是::

"m124 e12 s00";

编辑:

由于我的首要任务是尽可能快地进行此替换,因此我尝试比较以下 Slai 和 sxmlln 给定解决方案的ElapsedMilliseconds 结果。两者都完全回答了我的问题,结果排在第二位:

2000 个值:

string inputStr = "a1 a5 a80 a80 m124 a34 a300 e12 s00";

结果:

ISet<String> : time: [ 0 ] fast
List<string> : time: [ 5 ] slow
HashSet<string> : time: [ 1 ] average

有时等于相同的字符串和内容:

ISet<String> : time: [ 0 ] fast
List<string> : time: [ 5 ] slow
HashSet<string> : time: [ 0 ] fast

8000 个值:

string inputStr = "a1 a5 a80 a80 m124 a34 a4987 a300 e12 s00";

结果:

ISet<String> : time: [ 2 ] fast
List<string> : time: [ 5 ] slow
HashSet<string> time: [ 3 ] average

20000 个值:

string inputStr = "a1 a5 a80 a80 m124 a34 a4987 a17890 a300 e12 s00";

结果:

ISet<String> : [ 7 ] fast
List<string> :  [ 12 ] average
HashSet<string> : [ 16 ] slow

200000 个值:

string inputStr1 = "a1 a5 a80 a80 m124 a34 a4987 a17890 a300 e12 s00 a123676";

结果:

ISet<String> : [ 105 ] fast
List<string> :  [ 111 ] average
HashSet<string> : [ 142 ] slow

ISet&lt;String&gt; 总是小于List&lt;string&gt; 并且小于或等于HashSet&lt;string&gt;。并且List&lt;string&gt; 在更大数量的值之后变得比HashSet&lt;string&gt; 更快,但在这个特定数量之前它比HashSet&lt;string&gt; 更慢,ElapsedMilliseconds 结果。

【问题讨论】:

  • 当然 2000 在处理 CPU 的处理能力时并没有那么多。但是对于具有真正庞大流程的此类事情,最好使用 StringBuilder ,因为它只会对字符串进行就地更改。在您的场景中,每次更改都会在 RAM 内存的新插槽中创建一个新字符串。
  • 有趣.. List 方法是@Thili77 答案的修改版吗?以最小化内存分配的方式解析输入字符串通常应该是最快的,但是它的工作量太大并且必须根据频率调整解析方法。
  • @Slai 在大多数情况下它等于或接近 HashSet ElapsedMilliseconds 结果至少它在快速/平均/慢速讲台上的相同位置。但我不能肯定地说,因为我在没有结果字符串的情况下使用这个过程,就像 Thili77 在 if 语句中添加条件 strList.Any(inputStr.Contains) 给出的那样,但是当我试图从 strListNew 中提取任何值,它是空的。所以说点什么,我对这个解决方案没有任何输出,只有实现,我不确定我做错了什么

标签: c# regex linq list replace


【解决方案1】:

我建议使用 Set。它们允许快速查找。

ISet<String> strSet = new HashSet<String>();  

for (int i = 1; i <= 2000; i++)
{
    strSet.Add("a" + i);
}

接下来,您可以将输入拆分为一个数组进行检查(因为您的输入可以按空格拆分)。

string inputStr = "a1 a5 a80 a80 m124 a34 a300 e12 s00";
string[] inputs = inputStr.Split(' ');

最后,现在您循环输入并检查它们是否存在于Set 中。如果没有,则将它们添加到您的结果中。

// this is from System.Text namespace
StringBuilder sbResult = new StringBuilder();
foreach (var input in inputs)
{ 
    if (!strSet.Contains(input))
        {
            sbResult.AppendFormat("{0} ", input);
        }
    }
}

string result = sbResult.ToString().Trim();

【讨论】:

    【解决方案2】:

    没有通用的快速正确的方法,因为它取决于太多的因素。

    List<string> strList = Enumerable.Range(1, 2000).Select(i => "a" + i).ToList();
    string inputStr = "a1 a5 a80 a80 m124 a34 a300 e12 s00";
    
    string result = string.Join(" ", inputStr.Split(' ').Except(strList)); // "m124 e12 s00"
    

    大部分时间都花在.Except LINQ 扩展中创建一个Set,所以前面只能创建一次Set来替换多个字符串:

    var strSet = new HashSet<string>(Enumerable.Range(1, 2000).Select(i => "a" + i));
    
    var result1 = string.Join(" ", inputStr1.Split(' ').Where(s => !strSet.Contains(s)));
    
    var result2 = string.Join(" ", inputStr2.Split(' ').Where(s => !strSet.Contains(s)));
    

    【讨论】:

    • 您好,我已经测试了解决方案的结果,请检查我的编辑
    【解决方案3】:

    您可以使用以下代码执行此操作...

    List<string> strListNew = new List<string>();
    foeach(var item in strList){
      if ( /*your condition in here*/ )
      {
        strListNew.Add(""); 
      }
      else{
        strListNew.Add(item);
      } 
    }
    

    这对你有用...

    【讨论】:

    • 你好,我不确定,可能我没理解对,你能解释一下,这段代码是如何完成我的要求的
    • 在这个 foreach 循环中,您将 strList 的每个字符串一个接一个地循环。因此,您必须检查每个 的条件,然后添加到新列表中。这里的新列表是 strListNew。
    • 我在这里得到了预期的方法名称 (item(inputStr.Contains))
    • 我没有多考虑条件。现在我已经编辑了。所以你现在就会明白了。
    • 所以让我得到,如果我放在那里 strList.Any(inputStr.Contains) 我如何获得最终字符串,我只是提取列表内容并且它是空的。所以我已经编辑了我的问题,可能还不够清楚,或者我的代码有问题
    猜你喜欢
    • 2022-06-14
    • 2017-03-16
    • 2021-05-22
    • 2022-01-02
    • 2013-05-01
    • 2017-06-22
    • 1970-01-01
    • 2021-03-26
    • 2011-03-09
    相关资源
    最近更新 更多