C# 替换字符串中字符列表的有效方法

C# 替换字符串中字符列表的有效方法,c#,optimization,C#,Optimization,我想用空字符串替换一些字符{'z','x','q'},下面是我的代码 string input = "xeatq" char[] words = new char[] { 'y', 'x', 'q' }; foreach (char c in words) input = input.Replace(c.ToString(), ""); return input; 但我认为这不是替换许多数据字符串(在我的例子中是一百万个数据)的有效方法,它太慢了。有什么有效的方法来做我的工作,你

我想用空字符串替换一些字符
{'z','x','q'}
,下面是我的代码

string input = "xeatq"

char[] words = new char[] { 'y', 'x', 'q' };

foreach (char c in words)
    input = input.Replace(c.ToString(), "");

return input;

但我认为这不是替换许多数据字符串(在我的例子中是一百万个数据)的有效方法,它太慢了。有什么有效的方法来做我的工作,你能给我提供最好的方法吗?

另一种方法是

input = new string(input.Select(c => words.Contains(c) ? "" : c).ToArray())
一个简单的Linq应该做到:

using System.Linq;

...

// All characters which are not in words
input = string.Concat(input.Where(c => !words.Contains(c)));
如果您有一个很长的
输入
字符串和巨大的
单词
,因此您需要进行优化

// We explictly build the string; input.Length - to allocate memory just once
StringBuilder sb = new StringBuilder(input.Length); 

// HashSet is more efficient for Contains than array: O(1) vs. O(N)
HashSet<char> hs = new HashSet<char>(words);

foreach (char c in input)
  if (!hs.Contains(c))
    sb.Append(c);

input = sb.ToString();

如果反复执行
RegularExpression
,则其速度可能会明显快于此。此外,为什么不使用
string
数组而不是
char
(而不是每次都使用
ToString()
)?你能给我一个示例
Regex.Replace(输入,“z | x | q”,string.Empty)
效率如何?@DzarrahDeveloper既然你关心效率,为什么不使用BenchmarkDotNet在这里比较不同的答案,然后发布您的发现呢?效率如何?您的解决方案在每次提交时都分配一个字符串,因此我的应该更有效。也许您可以测量它并将结果发布在此处效率如何请记住,
string.Concat
在内部使用
StringBuilder
,但它是从缓存中获取的。因此,如果您反复调用此函数,那么使用
string.Concat
可能比创建自己的
StringBuilder
更便宜,即使是对于大型字符串也是如此。像往常一样,描述您的实际用例@Dzarrah Developer:将字符替换为
(空字符串)等于跳过字符:
AxB
->
AB
。如果我想将其更改为x到g而不是空,如何space@Dzarrah开发者:如果要将符号映射到
字符串
s(例如,
'x'
'XX'
),请尝试使用字典,请参阅我的编辑。
 Dictionary<char, string> map = new Dictionary<char, string>() {
   {'x', "XX"}, // change x into "XX"
   {'y', ""},   // remove y
   {'z', ""},   // remove z
 };

 // Now input.Length is estimation; you may want to put, say input.Length + 1000  
 StringBuilder sb = new StringBuilder(input.Length); 

 foreach (var c in input) {
   if (map.TryGetValue(c, out var v))
     sb.Append(v);
   else 
     sb.Append(c);
 }

 input = sb.ToString();