java - 最有效的方法来实现这个?

标签 java string parsing

我得到了一个字符串:

00122334455667788990875645346787659870984780...

上面给定的字符串大小总是偶数。 我必须实现一个方法,该方法将返回一个字符串数组列表,其中每个元素将包含 2 个字符。例如上面的字符串:

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;
    }
}

This URL 建议在这种情况下简单迭代更有效。你们同意吗?

最佳答案

您可以通过单个拆分来完成此操作(好吧,这在运行时可能不是最有效的,但这是简洁的,可以编写更少的代码):

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);

但您可以自己检查一下,正则表达式拆分是否真的是大字符串的性能瓶颈,并适本地对它们进行基准测试。


我对这两种方法进行了基准测试 - 拆分和循环。正如预期的那样,对于长度为 1000 的字符串,循环的效率几乎是拆分的 4-5 倍。 .

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

如果有人认为基准测试结果有缺陷,请在评论中注明。

关于java - 最有效的方法来实现这个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18930532/

相关文章:

java - 在java中将图像转换为8位灰度RAW图像

javascript - 如何正确地将 C# 对象列表解析为 Javascript。仅显示类似 "System.Collections.Generic.List` 1"的类型

java - 批注作为另一个批注的快捷方式

java - 为什么递归调用打印 '123456' 而不是 '1' ?

java - 如何根据 JUNIT 的结果生成 XML 并配置 ant 来使用它?

c - 使用 free() 使 strtok 返回的字符串为空

c# - 有没有更好的方法来计算 C# 中字符串中的字符串格式占位符?

java - 为什么空正则表达式和空捕获组正则表达式返回字符串长度加一结果

java - Android中从Json数组解析Json

c++ - 使用 flex 和 bison 进行乘法解析