3

これは可能ですか?C# が不変の文字列を使用することを考えると、次の行に沿ったメソッドがあると予想できます。

var expensive = ReadHugeStringFromAFile();
var cheap = expensive.SharedSubstring(1);

そのような関数がない場合、わざわざ文字列を不変にする必要があるでしょうか? または、別の理由で文字列がすでに不変である場合、このメソッドを提供しないのはなぜでしょうか?

私がこれを調べている具体的な理由は、ファイルの解析を行っていることです。単純な再帰降下パーサー (TinyPG によって生成されたパーサーや、手で簡単に記述できるパーサーなど) は、あらゆる場所で Substring を使用します。これは、解析する大きなファイルを提供すると、信じられないほどのメモリ チャーンが発生することを意味します。確かに回避策はあります。基本的には独自の SubString クラスをロールしてから、もちろん、StartsWith などの String メソッドや Regex などの String ライブラリを使用できることを忘れるので、これらの独自のバージョンもロールする必要があります。ANTLR などのパーサー ジェネレーターは基本的にそれを行っていると思いますが、私のフォーマットは、そのようなモンスター ツールの使用を正当化できないほど単純です。TinyPG でさえ、おそらくやり過ぎです。

誰か、明らかな、またはそれほど明白ではない標準の C# メソッド呼び出しがどこかに欠けていると教えてください...

4

6 に答える 6

5

いいえ、そんなことはありません。

.NET 文字列には、char 配列への参照、オフセット、および長さを持つ Java 文字列とは異なり、テキスト データが直接含まれています。

どちらのソリューションも、状況によっては「勝ち」があり、他の状況では負けます。

これがキラーになると確信している場合は、独自の内部 API で使用する Java スタイルの文字列を実装できます。

于 2009-06-16T21:10:37.100 に答える
2

私の知る限り、より大きなパーサーはすべてストリームを使用して解析します。それはあなたの状況に適していませんか?

于 2009-06-16T21:13:00.230 に答える
1

.NET Framework は文字列インターンをサポートしています。これは部分的な解決策ですが、文字列の一部を再利用する可能性はありません。部分文字列を再利用すると、一見しただけでは明らかではない問題が発生すると思います。StringBuilderを使用して多くの文字列操作を行う必要がある場合は、行く方法です。

于 2009-06-16T21:11:02.793 に答える
0

「安い」を表す単純なクラスを簡単に作成できます。部分文字列の開始インデックスと部分文字列の長さを保持するだけです。いくつかのメソッドを使用すると、必要に応じて部分文字列を読み取ることができます-使用できる文字列キャスト演算子が理想的です

string text = myCheapObject;

実際の文字列であるかのようにシームレスに機能します。StartsWith のようないくつかの便利なメソッドのサポートを追加することは、迅速かつ簡単になります (それらはすべて 1 つのライナーになります)。

もう 1 つのオプションは、通常のパーサーを作成し、複数のコピーを保持するのではなく、トークンへの参照を共有する Dictionary にトークンを格納することです。

于 2009-06-16T21:16:38.927 に答える
0

C# には、探しているすぐに使える機能を提供するものはありません。

必要なのは、O(1) 連結と O(log n) 部分文字列をサポートする不変のデータ構造であるRope データ構造です。ロープの C# 実装は見つかりませんが、ここでは Javaの実装です。

それを除けば、TinyPG や ANTLR を使用するのが最も簡単な方法であれば、問題はありません。

于 2009-06-16T21:15:49.087 に答える
0

「unsafe」を使用して自分でメモリ管理を行うことができます。これにより、探していることを実行できる可能性があります。また、StringBuilder クラスは、操作ごとに新しい文字列を作成しないため、文字列を何度も操作する必要がある場合に最適です。

于 2009-06-16T21:15:51.863 に答える