1

これは基本的に私の前の質問のフォローアップです。このコードを使用して、配列に含まれる文字列を置き換えています。

string[] replacements = {"these",
                         "words",
                         "will",
                         "get",
                         "replaced"};

string newString = "Hello.replacedthesewordswillgetreplacedreplaced";

for (int j = 0; j < replacements.Length; j++)
{
    newString = Regex.Replace(newBase,
    @"((?<firstMatch>(" + replacements[j] + @"))(\k<firstMatch>)*)",
    m => "[" + j + "," + (m.Groups[3].Captures.Count + 1) + "]");
}

このコードnewStringを実行すると、次のようになります。

こんにちは。[4,1][0,1][1,1][2,1][3,1][4,2]

これは、上記のような小さな交換には問題なく機能します。基本的には文字列を即座に置き換えますが、大量の置換の場合は遅くなる傾向があります。

より速く交換できるように最適化する方法を誰かが見ることができますか?

forループがそれを遅くしていると思います。配列には、置換する必要のない文字列が常に含まれているため (メインのnewString文字列に含まれていないため)、for ループの前にそれを確認する方法があるかどうか疑問に思います。それは遅くなるかもしれませんが...

他に良い方法が思い浮かばなかったので質問させていただきました。助けてくれてありがとう!:)

4

1 に答える 1

1

試してみる方法がいくつかあります(NBは両方ともテストされていませんが、動作し、現在のコードよりも高速であるはずです)。

静的にコンパイルされた正規表現を使用するもの:

private static readonly Dictionary<string, int> Indexes = new Dictionary<string, int> 
{
  { "these", 0 },
  { "words", 1 },
  { "will", 2 },
  { "be", 3 },
  { "replaced", 4 },
};

private static readonly Regex ReplacementRegex = new Regex(string.Join("|", Indexes.Keys), RegexOptions.Compiled)

...
var occurrences = Indexes.Keys.ToDictionary(k => k, k => 0);
return ReplacementRegex.Replace(newString, m => {
  var count = occurences[m.Value];
  occurences[m.Value] = count + 1;
  return "[" + Indexes[m.Value] + "," + count + "]";
});    

そして正規表現なしで:

for (int j = 0; j < replacements.Length; j++)
{
  var index = 0;
  var count = 0;
  var replacement = replacements[j];
  while((index = newString.IndexOf(replacement, index)) > -1) 
  {
    count++;
    newString = newString.Substring(0, index) + "[" + j + "," + count + "]" + newString.Substring(index + replacement.Length);
  }
}
于 2012-12-15T15:32:03.090 に答える