C#更好的方法吗?

时间:2010-10-02 04:26:50

标签: c#

您好我在下面有这个代码,我正在寻找更漂亮/更快的方法。

谢谢!

string value = "HelloGoodByeSeeYouLater";
string[] y = new string[]{"Hello", "You"};

foreach(string x in y)
{
    value = value.Replace(x, "");
}

5 个答案:

答案 0 :(得分:4)

你可以这样做:

y.ToList().ForEach(x => value = value.Replace(x, ""));

虽然我认为你的变体更具可读性。

答案 1 :(得分:3)

原谅我,但有人必须说出来,

value = Regex.Replace( value, string.Join("|", y.Select(Regex.Escape)), "" );

可能更快,因为它会创建更少的字符串。

编辑:感谢Gabe和lasseespeholt为Escape和Select。

答案 2 :(得分:2)

虽然不是更漂亮,但还有其他方法可以表达同样的事情。

在LINQ中:

value = y.Aggregate(value, (acc, x) => acc.Replace(x, ""));

使用String方法:

value = String.Join("", value.Split(y, StringSplitOptions.None));

我认为托管代码中的任何内容都不会比foreach中的简单替换更快。

答案 3 :(得分:2)

这取决于您要搜索的字符串的大小。 foreach示例对于小型操作非常好,但每次操作时都会创建一个新的字符串实例,因为该字符串是不可变的。它还需要以线性方式一遍又一遍地搜索整个字符串。

已提出基本解决方案。如果你对这种语法感到满意,那么提供的Linq示例是很好的;我也喜欢扩展方法的建议,尽管这可能是提议的解决方案中最慢的。除非你有极其特殊的需要,否则我会避免使用正则表达式。

因此,让我们探索更详细的解决方案,并假设您需要处理长度为数千个字符的字符串,并且有许多可能被替换的单词。如果这不适用于OP的需要,也许它会帮助其他人。

方法#1适用于大型字符串,几乎没有匹配。

方法#2适用于包含大量匹配的短字符串。

方法#1

我已经使用char数组和指针数学处理c#中的大规模解析,其中智能搜索操作针对搜索词的长度和潜在频率进行了优化。它遵循以下方法:

  • 非常便宜一次偷看一个角色
  • 仅调查潜在的匹配
  • 找到匹配后修改输出

例如,您可能会读取整个源数组,并且只有在找不到它们时才会向输出中添加单词。这将消除保持重新标注字符串的需要。

此技术的一个简单示例是在DOM解析器中查找结束HTML标记。例如,我可能会读取一个打开的STYLE标记,并希望跳过(或缓冲)数千个字符,直到找到一个结束的STYLE标记。

这种方法提供了令人难以置信的高性能,但如果你不需要它也会非常复杂(另外你需要精通内存操作/管理,否则你会产生各种错误和不稳定性)。

我应该注意.Net字符串库已经非常高效您可以根据自己的特定需求优化此方法并获得更好的性能(我已经验证了这一点)。

方法#2

另一种方法是将搜索词存储在包含字符串列表的词典中。基本上,您可以决定搜索前缀需要多长时间,并将源字符串中的字符读入缓冲区,直到达到该长度。然后,在字典中搜索与该字符串匹配的所有术语。如果找到匹配项,则通过迭代该列表进一步探索,如果没有,则表示您可以丢弃缓冲区并继续。

因为字典基于散列匹配字符串,所以搜索是非线性的,非常适合处理大量可能的匹配。

我正在使用这种方法,允许通过姓名,州,城市,美国联邦航空局代码等在美国的每个机场进行即时(<1ms)搜索。美国有13K机场,我创造了一个大约300K排列的地图(同样,一个前缀长度不一的字典,每个字符对应一个匹配列表)。

例如,亚利桑那州凤凰城的主要机场被称为Sky Harbor,其短ID为KPHX。我存储:

KP KPH KPHX

博士 河粉 Phoe

氩 阿里 亚利桑那州

Sk的 天空

哈 喀拉 Harb的

内存使用方面存在成本问题,但字符串实习可能会稍微减少这种情况,并且生成的速度可以证明此大小的数据集上的内存使用情况。搜索是在用户输入时发生的,并且速度非常快,以至于我实际上已经引入了一个人工延迟来平滑体验。

如果您需要深入研究这些方法,请给我发消息。

答案 4 :(得分:1)

优雅的扩展方法

(在电话级别可谓“更漂亮”)

我将实现一个扩展方法,允许您直接在原始字符串上调用您的实现,如此处所示。

value = value.Remove(y);
// or
value = value.Remove("Hello", "You");
// effectively
string value = "HelloGoodByeSeeYouLater".Remove("Hello", "You");

扩展方法实际上可以在任何字符串值上调用,因此可以轻松重用。

扩展方法的实施:
我将在extension method中将您自己的实现(在您的问题中显示)包装为漂亮或优雅的点,并使用params关键字提供一些灵活性来传递参数。您可以将其他人更快的实现主体替换为此方法。

static class EXTENSIONS {
    static public string Remove(this string thisString, params string[] arrItems) {
       // Whatever implementation you like:
       if (thisString == null)
           return null;
       var temp = thisString;
       foreach(string x in arrItems)
            temp = temp.Replace(x, "");
       return temp;
    }
}

这是我现在能提出的最明智的想法,没有其他人接触过。