2016-05-05 3 views
-1

入力文字列が長すぎる(長さ> 200,000)場合、次のメソッドは例外をスローします。問題はsubstring()の使用に関連しているようですが、他の投稿を見て、使用方法をString str = new String(s.substring(i,i+k));に変更しましたが、問題はまだ発生します...メモ帳例外がまだスローされている理由は何ですか? (私は、ヒープサイズを大きくしたくない)非常に大きな文字列で部分文字列を実行するとJavaメモリ不足エラーが発生する

方法:

private static Map<String,Integer> findSubString(String s, int k) { 
    Map<String,Integer> map = new HashMap<>(); 
    for (int i = 0; i < s.length() - (k - 1); i++) { 
     String str = new String(s.substring(i,i+k)); 
     if (map.containsKey(str)) { 
      map.put(str, map.get(str) + 1); 
     } 
     else { 
      map.put(str, 1); 

     } 
    } 

    return map; 
} 

エラー:私の意見では

java.lang.OutOfMemoryError: Java heap space 
at java.util.Arrays.copyOfRange(Arrays.java:3664) 
at java.lang.String.<init>(String.java:207) 
at java.lang.String.substring(String.java:1969) 
at Solution.findSubString(Solution.java:112) 
+0

XmXの値は? – AdamSkywalker

+0

あなたはそれが例えば64GB以上の十分に大きいと仮定することができます。問題はコードにあります。 – xcoder

+0

Javaバージョン? – AdamSkywalker

答えて

1

以下がより良い方法になります。

str = s.substring(i,i+k).intern() ; 最初にnew String部分を削除し、をループから外します。我々はどうにかしてsubStringから返された文字列が一意であることを確認する必要があります。 internを使用すると、Javaは同じ文字列を再利用します。しかし注意のための注意。 internを使用するとコードが遅くなります。

メモリを節約できます。

+0

私のためには機能しません – AdamSkywalker

+0

このコードは重複した文字列を生成しません(短命以外)結果のインターン操作は無効です – sibnick

+0

これは私が考えることができる最適な最適化です。 –

0

このライン

String str = new String(s.substring(i,i+k)); 

は、メモリリークを引き起こします。ループ内でインスタンス化を避ける必要があります。あなたが言うとき

0

たぶん、あなたは無効な仮定を使用している:

You can assume it to be sufficiently large, more than 64gb for eg. The problem is with the code.

マップに存在し、それが吹くとき、彼らがどのような大きさでどのように多くのエントリ。次のようなデバッグコードを追加してみてください:

if (map.size() % 50000 == 0) { 
      System.out.println(map.size()); 
} 

さらに情報を投稿してください。入力文字列サイズ、部分文字列のサイズ、最後に報告された結果、使用されているXmx値。

関連する問題