JavaのString#substring()
メソッドの時間複雑度はどのくらいですか? Javaの7の寿命内の更新6のようJavaの部分文字列()の時間複雑度
答えて
新しい答え
、substring
の挙動はコピーを作成するように変更 - ので、すべてString
は、前述したように、他のオブジェクトと共有ないあるchar[]
を指し、私が知っている限り。その時点で、substring()
はO(n)操作になりました。ここでnは部分文字列内の数字です。
旧答え:前のJava 7
文書化されていない - しかし、あなたが想定した場合の練習O(1)は、ガベージコレクションが必要とされない、など
これは単にを参照する新しいString
オブジェクトを構築します同じ基底のchar[]
ですが、オフセットとカウント値が異なります。したがって、コストは、検証を実行して単一の新しい(適度に小さい)オブジェクトを構築するのにかかる時間です。ガベージコレクション、CPUキャッシュなどに基づいて時間が変化する操作の複雑さについて話すのは理にかなっている限り、O(1)です。特に、元の文字列または部分文字列の長さに直接依存しません。
O(1)元の文字列のコピーが行われないため、オフセット情報の異なる新しいラッパーオブジェクトが作成されます。
次のように判断しますが、Javaのパフォーマンスの欠点は、文字列の部分文字列ではなく、どこかにあります。 コード:
public static void main(String[] args) throws IOException {
String longStr = "asjf97zcv.1jm2497z20`1829182oqiwure92874nvcxz,nvz.,xo" +
"aihf[oiefjkas';./.,z][p\\°°°°°°°°?!(*#&(@*&#!)^(*&(*&)(*&" +
"fasdznmcxzvvcxz,vc,mvczvcz,mvcz,mcvcxvc,mvcxcvcxvcxvcxvcx";
int[] indices = new int[32 * 1024];
int[] lengths = new int[indices.length];
Random r = new Random();
final int minLength = 6;
for (int i = 0; i < indices.length; ++i)
{
indices[i] = r.nextInt(longStr.length() - minLength);
lengths[i] = minLength + r.nextInt(longStr.length() - indices[i] - minLength);
}
long start = System.nanoTime();
int avoidOptimization = 0;
for (int i = 0; i < indices.length; ++i)
//avoidOptimization += lengths[i]; //tested - this was cheap
avoidOptimization += longStr.substring(indices[i],
indices[i] + lengths[i]).length();
long end = System.nanoTime();
System.out.println("substring " + indices.length + " times");
System.out.println("Sum of lengths of splits = " + avoidOptimization);
System.out.println("Elapsed " + (end - start)/1.0e6 + " ms");
}
出力:それはOである(1)またはそうでない場合
substring 32768 times Sum of lengths of splits = 1494414 Elapsed 2.446679 ms
、依存しています。メモリ内の同じ文字列を参照している場合は、が非常にの長い文字列であると想像してください。長い文字列を参照して長い文字列を参照しないでください。長い間メモリを解放していいのではないでしょうか?
古いバージョンのJavaではO(1)でしたが、Jonが述べたように、同じ基本char []と異なるオフセットと長さの新しいStringが作成されました。
しかし、これは実際のchar []が除去された共有、オフセットおよび長さフィールドを除去したJava 7アップデート6
を開始変化しています。 substring()はすべての文字を新しいStringにコピーするだけです。
エルゴ、サブストリングは今線形複雑度のJava 7アップデート6
+1これは最近のSun JavaとOpenJDKのバージョンのケースです。 GNU Classpath(と他の人は、私が推測する)はまだ古いパラダイムを使用しています。残念ながら、少しの知的慣性があるようです。この。私は2013年に、部分文字列が共有 'char [] 'を使用するという前提に基づいて、様々なアプローチを推奨しています。 – thkala
新しいバージョンはもはやO(1)の複雑さを持たないようになっています。 O(1)に部分文字列を実装するための代替手段があることを知りたいのですか? String.substringは非常に便利なメソッドです。 –
にO(N)です。これは、部分文字列に対するメモリリークの問題を修正した後です。
Java 1.7.0_06から、String.substringは定数の代わりに線形の複雑さを持つことを覚えておいてください。
それでは(長い文字列の場合)もっと悪いですか? –
- 1. Java 7文字列 - 部分文字列の複雑さ
- 2. 分割アルゴリズム - 時間の複雑度
- 3. random.sampleの時間複雑度
- 4. プログラムの時間複雑度
- 5. フィボナッチアルゴリズムの時間複雑度
- 6. このwhileループの時間複雑度
- 7. 以下のコードの時間複雑度
- 8. アルゴリズムのBigO時間の複雑度
- 9. 分裂征服アルゴリズムの時間複雑度
- 10. キャニーエッジ検出器の時間複雑度
- 11. モジュラー算術の時間複雑度
- 12. erlang dictの時間複雑度
- 13. 遺伝的アルゴリズムの時間複雑度
- 14. python str.index時間の複雑度
- 15. アルファベータ検索時間の複雑度
- 16. Swift Setの時間複雑度.indexOf
- 17. 複数の部分文字列を一度に置換する
- 18. 文字列中の部分文字列の総数java
- 19. 未分類配列のバイナリ検索の時間の複雑さ
- 20. 時間複雑度/グラフ理論
- 21. 時間複雑度を計算する
- 22. 文字列のスカラフィルタ部分文字列
- 23. 文字列内の部分文字列
- 24. 部分文字列のpowershell部分文字列
- 25. 時間文字列の合計時間の文字列
- 26. Javaの文字を部分文字列にする
- 27. 時間複雑またはJava
- 28. Javaアルゴリズム:奇数偶数を分離する(時間空間の複雑さ)
- 29. ハスケルの部分文字列
- 30. Vimで部分文字列の複数のコピーの文字列を生成
@iはかなり頻繁に使用されるライブラリ関数なので、太陽はそれに合わせて最適化しなければならないと思います。だから、O(1) – TimeToCodeTheRoad