0

1 つの文字列に含まれるさまざまな文字の数を確認する必要があります。文字列の長さは 20,000 にもなり、テスト ケースの合計は 10,000 以下です。以下のコードが示すように、文字列の他の文字を置き換えてから、その長さを確認することでそれを行っていました。

 int no7=myString.replaceAll("[^7]","").length();
 int no0_3=myString.replaceAll("[^0-3]","").length();
 int no5_6=myString.replaceAll("[^56]","").length();

replaceAll メソッドがどのように機能するのか、文字列の各文字をチェックする単一のループでカウントを行うと速くなるかどうか疑問に思っていました。前もって感謝します。

4

3 に答える 3

2

まず+、文字クラスの後に a を追加することで、置換をより高速に行うことができます (例: [^7]+)。これにより、一度に 1 つずつではなく、不要な文字の連続実行が置き換えられます。入力文字列によっては、これによりパフォーマンスが大幅に向上する場合があります。

しかし、あなたの場合、私は実際には何も置き換えず、長さをチェックしません。必要なのは、7 の数、0 から 3 までの桁数、および 5 と 6 の数です。したがって、それらをチェックする単一のループを作成するだけです。

int no7 = 0, no0_3 = 0, no5_6 = 0;
for (int i = 0; i < myString.length(); i++) {
  char c = myString.charAt(i);
  if (c == '7') no7++;
  if (c >= '0' && c <= '3') no0_3++;
  if (c == '5' || c == '6') no5_6++;
}

これは、3 つの個別の文字列を作成して長さを確認し、それらを再度破棄する必要がなく、正規表現の作成、解析、実行時間を節約できるため、高速になります。したがって、すべての文字に対する単純な反復 (これはとにかく正規表現が行う必要があることです)により、元の実行時間の最大で 3 分の 1 に短縮されます。

于 2012-10-07T14:29:32.870 に答える
0

replaceAll は内部で Pattern を構築し、提供された文字列で Matcher メソッドを呼び出します。パターンのコンパイルには時間がかかるため、これを頻繁に行う場合は、コンパイル済みのパターンをコード内で static final フィールドとして使用するのが最善の方法です。

于 2012-10-07T14:29:19.687 に答える
0

replaceAll メソッドがどのように機能するのか疑問に思っていました

APIドキュメントにはすでに明確に言及されていると思います:

「このメソッドを str.replaceAll(regex, repl) の形式で呼び出すと、式とまったく同じ結果が得られます。

Pattern.compile(regex).matcher(str).replaceAll(repl)"

文字列の各文字をチェックする単一のループでカウントを行うと速くなるかどうか

コンパイルされた正規表現は、ほとんどの場合、手動の文字チェックよりも高速であるとは思えません。文字数が少ない場合は高速になる可能性がありますが、結果の文字列をどのように作成するかにも依存します (Java 文字列は不変であることを思い出してください)。

于 2012-10-07T14:31:15.220 に答える