1

私は文字列を与えられました:

00122334455667788990875645346787659870984780...

上記の文字列サイズは常に偶数になります。各要素に 2 文字が含まれる文字列の Arraylist を返すメソッドを実装する必要があります。たとえば、上記の文字列の場合:

1st position of arraylist will contain: 00
2nd: 12
3rd: 23
...

私はそれを自分で実装しようとしましたが、これは私の関数がどのように見えるかです:

private static ArrayList<String> getArrayListFrom(String data) {
    if(data.length()%2==0){
        ArrayList<String> aList = new ArrayList<String>();
        char[] dArray = data.toCharArray();
        //logic here.
        for(int i = 0; i < dArray.length + 2; i = i+2){
            if(i != 0){
                aList.add(dArray[i-2]+""+dArray[i-1]);
            }
        }
        return aList;
    }else{
        System.out.println("Invalid data.");
        return null;
    }
}

このURL は、この場合、単純な反復がより効率的であることを示唆しています。同意しますか?

4

2 に答える 2

10

単一の分割でこれを行うことができます (まあ、これは実行時に最も効率的ではないかもしれませんが、これは簡潔で、書くコードが少ないです):

String[] arr = str.split("(?<=\\G..)");

そして、List<String>使用Arrays#asList()方法を取得します。

正規表現パターンは、2 文字 - が前にある空のスペースで分割されますが..、前の一致で既に考慮された文字は無視されます - \\G。アンカー\\Gは、前の一致が終了した位置に一致します。

String str = "00122334455667788990875645346787659870984780";
String[] arr = str.split("(?<=\\G..)");

System.out.println(Arrays.asList(arr));

プリント:

[00, 12, 23, 34, 45, 56, 67, 78, 89, 90, 87, 56, 45, 34, 67, 87, 65, 98, 70, 98, 47, 80]

文字列で分割を行う方法は次のとおりです。

   " 00     1    2       2334455667788990875645346787659870984780"  (whitespaces represent empty string) 
//     |       |       |
//   split,  no-split, split -> gives 12
//   |    |  |      |  
//   \    /  \      /
//  gives 00  as the preceding two characters are `1` and `0`.
//            but 0 is already considered for the previous empty string

参照:


実行時のパフォーマンスが問題になる場合は、単純なループを使用できます。

String str = "00122334455667788990875645346787659870984780";
List<String> list = new ArrayList<String>();
for (int i = 0; i < str.length(); i += 2) {
    list.add(str.substring(i, i + 2));
} 
System.out.println(list);

ただし、正規表現の分割が実際に大きな文字列のパフォーマンスのボトルネックであるかどうかを自分で確認し、両方を適切にベンチマークすることができます。


分割とループの両方の方法をベンチマークしました。そして予想通り、長さの文字列の場合、ループは分割よりもほぼ 4 ~ 5 倍効率的です1000

public static void usingSplit(String str) {
    String[] arr = str.split("(?<=\\G..)");
    List<String> list = Arrays.asList(arr);
}

public static void usingLoop(String str) {
    List<String> list = new ArrayList<String>();
    for (int i = 0; i < str.length(); i += 2) {
        list.add(str.substring(i, i + 2));
    }
}

// Warm up JVM
    for (int i = 0; i < 1000000; ++i) {
        usingSplit(str);
    }
    for (int j = 0; j < 1000000; j++) {
        usingLoop(str);
    }

    long nano = System.nanoTime();
    for (int i = 0; i < 1000000; ++i) {
        usingSplit(str);
    }
    System.out.println("Time with usingSplit(): " + (System.nanoTime() - nano) * 1.0 / Math.pow(10, 9) + " Seconds");

    nano = System.nanoTime();
    for (int j = 0; j < 1000000; j++) {
        usingLoop(str);
    }
    System.out.println("Time with usingLoop(): " + (System.nanoTime() - nano) * 1.0 / Math.pow(10, 9) + " Seconds");

いくつかの連続実行での出力:

Run 1:
Time with usingSplit(): 34.391315143 Seconds
Time with usingLoop(): 7.515221612 Seconds

Run 2:
Time with usingSplit(): 33.41518869 Seconds
Time with usingLoop(): 7.868896218 Seconds

誰かがベンチマークの結果に欠陥があると思われる場合は、コメントに書き留めてください。

于 2013-09-21T08:27:23.847 に答える