内存中最好的可能字符串替换

时间:2017-08-02 11:14:03

标签: c# string memory optimization

我需要更换一个大小为3MB的巨大字符串。替换必须在内存中完成。我知道开始和结束标记,但不知道他们的索引(显然)替换字符串几乎是相同或更小的大小! 例如:
< hello > jaskhdjksehrf87897g8df7g8d7g8dfy9g6d89sg78dfgy9df69g87s97090dgs8d7f6srsd564f5sd45f46sd5f76d5g68df6g785sd67g58576sd5g875sdfg578df6g6sd87g6f89g69s6d8g6 AND MUCH MORE < /hello >

替换字符串将有另一个开始和结束标记,必须用现有标记替换。 有人可以用尽可能最简单的方法帮我解决这个问题。我需要在C#中完成。

P.S。记住字符串不在文件中!

1 个答案:

答案 0 :(得分:1)

在我看来,这是你能做的最好的事情。

首先,在输入字符串中找到开始/结束标记位置。我认为没有比使用string.IndexOf方法的线性搜索更好的方法了。唯一的优化是从开始标记的结束位置开始搜索结束标记。

然后你可以计算得到的字符串长度,分配char[]缓冲区,使用string.CopyTo方法将输入字符串的未改变部分和替换字符串复制到适当的位置,最后创建并返回一个缓冲区中的字符串使用相应的string constructor

像这样(没有验证):

static string Replace(string input, string startTag, string endTag, string newStartTag, string newEndTag, string newContent)
{
    // Determine tags start/end positions
    int startTagStart = input.IndexOf(startTag);
    if (startTagStart < 0) return input; // or throw exception
    int startTagEnd = startTagStart + startTag.Length;
    int endTagStart = input.IndexOf(endTag, startTagEnd);
    if (endTagStart < 0) return input; // or throw exception
    int endTagEnd = endTagStart + endTag.Length;

    // Determine the resulting string length and allocate a buffer
    int resultLength = startTagStart + newStartTag.Length + newContent.Length + newEndTag.Length + (input.Length - endTagEnd);
    var buffer = new char[resultLength];
    int pos = 0;

    // Copy the substring before the start tag
    input.CopyTo(0, buffer, pos, startTagStart);
    pos += startTagStart;
    // Copy the new start tag
    newStartTag.CopyTo(0, buffer, pos, newStartTag.Length);
    pos += newStartTag.Length;
    // Copy the new content
    newContent.CopyTo(0, buffer, pos, newContent.Length);
    pos += newContent.Length;
    // Copy the new end tag
    newEndTag.CopyTo(0, buffer, pos, newEndTag.Length);
    pos += newEndTag.Length;
    // Copy the substring after the end tag
    input.CopyTo(endTagEnd, buffer, pos, input.Length - endTagEnd);

    // Create and return a string from the buffer
    return new string(buffer);
}

使用评论中的示例进行测试:

var input = "<Tag1>string 1</Tag1>";
var output = Replace(input, "<Tag1>", "</Tag1", "<Tag2>", "</Tag2>", "string 2");
// output == "<Tag2>string 2</Tag2>"