C#

文字列を文字列で分割する

C#

手っ取り早い方法としてVB.NETの固有の関数を用いる方法がある。
しかし、一定の条件が揃っていればそれよりも高速に分割が可能である。

これについて考察した内容を述べてみる。

C#のstringにSplit機能があるが、これは「文字」による分割をサポートしてはいるが「文字列」による分割のオーバーロードメソッドは存在しない。
よって他の方法を用いる必要があるのだが、一般的にVB.NET固有の関数を利用する方法が挙げられる。

VB.NET関数による文字列の分割はStrings.Split関数で行える。
これをC#上で使用するには、VisualStudioではプロジェクトの参照の追加で『Microsoft Visual Basic .NET Runtime』を追加する、
あるいは以下のコンパイルオプションを指定する必要がある。

/r:Microsoft.VisualBasic.dll (「/r:」は「/reference:」の省略形)

そしてusing節に『using Microsoft.VisualBasic;』の一行を付け加える。
たとえば『ABC[SPRIT]DEF[SPRIT]GHI[SPRIT]JKL』なんて文字列を『[SPRIT]』という文字列で分割したいときは以下のようなコードを書く。

string[] parts;
string target    = "ABC[SPRIT]DEF[SPRIT]GHI[SPRIT]JKL";
string delimiter = "[SPRIT]";
parts = Strings.Split(target, delimiter, -1, CompareMethod.Binary);

引数の詳細に関しては各自ググって欲しい。
4番目の引数を変えることでいろいろな場面に対応できるのがこの関数の魅力だ。
しかしながらある条件を満たせばVB.NET関数を使わずに高速で分割処理ができる方法がある。
まず、その必要条件を挙げると…

  • 区切り文字列は完全一致であり、大文字小文字等の区別はしない
  • 対象文字列には絶対出現しない文字を挙げることができる

さて、この条件の下でなにをするかというと、

Replaceで区切り文字列を任意の一文字に置き換えて、置き換えた文字を区切りにSplitで分割する!

ということ。
実際にやってみるとこんな感じ。

string[] parts;
string target    = "ABC[SPRIT]DEF[SPRIT]GHI[SPRIT]JKL";
string delimiter = "[SPRIT]";
parts = target.Replace(delimiter, "分").Split('分');

これは「分」という文字がtarget文字列の中に絶対含まれないことを想定しているものだ。
何気にこいつが一番早い。
ためしに速度比較してみる。例に出した操作をそれぞれ50万回行って処理時間を計測した

VB Split(binary) took = 578ms
Replace + Split took = 422ms

という具合。
これは目からウロコじゃね?

スポンサーリンク
記事を書いた人

システムえんじにゃー🐈
趣味はエレキギター、自転車など。作曲したい。
World of Warshipsやってます。
記事に関する質問はお気軽にどうぞ。

surface0 (さーふぇす)をフォローする

コメント

タイトルとURLをコピーしました