StringTokenizer 在 JAVA 中拆分字符串是否更有效?

Is StringTokenizer more efficient in splitting strings in JAVA?

我一直在解决来自 SPOJ

的问题 Anti-Blot System

首先,我尝试使用 String 的 split 方法拆分输入字符串,提交后我得到了 TLE

我的代码使用拆分方法

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.regex.Pattern;
import java.util.regex.Matcher;


class ABSYS {
    public static void main(String[] args) throws IOException {
        int t;
        String[] numArray = new String[2];
        String[] numArray2 = new String[2];
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        t = Integer.parseInt(reader.readLine());
        while(t > 0) {
            String input = reader.readLine();
            if(input.isEmpty()) {
                continue;
            }
            numArray = input.split("\s{1}=\s{1}");
            numArray2 = numArray[0].split("\s{1}\+\s{1}");
            Pattern pattern = Pattern.compile("machula");
            Matcher matcher = pattern.matcher(numArray[1]);
            if(matcher.find()) {
                System.out.println(numArray[0] + " = " + (Integer.parseInt(numArray2[0]) + Integer.parseInt(numArray2[1])));
            }
            else {
                matcher = pattern.matcher(numArray2[0]);
                if(matcher.find()) {
                    System.out.println((Integer.parseInt(numArray[1]) - Integer.parseInt(numArray2[1])) + " + " + numArray2[1] + " = " + numArray[1]);
                }
                else {
                    System.out.println(numArray2[0] + " + " + (Integer.parseInt(numArray[1]) - Integer.parseInt(numArray2[0])) + " = " + numArray[1]);
                }
            }
            t--;
        }
    }
}

经过多次尝试,我失败了,无法让我的代码更有效率

然后,今天我读到了 StringTokenizer 并在我的代码中使用了它,我就在那里(在 spoj 上)

我的代码使用 StringTokenizer

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.regex.Pattern;
import java.util.StringTokenizer;


class ABSYS {
    public static void main(String[] args) throws IOException {
        int t, a = 0, b = 0, c = 0, matchula = 0;
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        Pattern pattern = Pattern.compile("^(\d)+$");
        t = Integer.parseInt(reader.readLine());
        while(t > 0) {
            String input = reader.readLine();
            if(input.isEmpty()) {
                continue;
            }
            StringTokenizer tokenizer = new StringTokenizer(input);
            String token = tokenizer.nextToken();
            if(pattern.matcher(token).matches()) {
                a = Integer.parseInt(token);
            }
            else
                matchula = 1;

            tokenizer.nextToken();
            token = tokenizer.nextToken();
            if(pattern.matcher(token).matches()) {
                System.out.println("b = " + token);
                b = Integer.parseInt(token);
            }
            else
                matchula = 2;

            tokenizer.nextToken();
            token = tokenizer.nextToken();
            if(pattern.matcher(token).matches()) {
                c = Integer.parseInt(token);
            }
            else
                matchula = 3;
            switch(matchula) {
                case 1: System.out.println((c-b) + " + " + b + " = " + c);
                        break;
                case 2: System.out.println(a + " + " + (c-a) + " = " + c);
                        break;
                case 3: System.out.println(a + " + " + b + " = " + (a+b));
                        break;
            }
            t--;
        }
    }
}

在 JAVA 文档中,他们不鼓励使用 StringTokenizer。

StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.

Jason S answer here

所述

if I wanted to tokenize a string with more complex logic than single characters (e.g. split on \r\n), I can't use StringTokenizer but I can use String.split().

我的疑惑

  1. 为什么会这样,尽管我发现它更省时。
  2. 不鼓励使用 StringTokenizer 的原因是什么?
  3. 如果像我的问题一样想使用简单的正则表达式怎么办,那么 StringTokenizerString.split() 好吗?

String.split() 比 StringTokenizer 更灵活,更易于使用。 StringTokenizer 早于 Java 支持正则表达式,而 String.split() 支持正则表达式,这使得它比 StringTokenizer 更强大。 String.split 的结果也是一个字符串数组,这通常是我们想要的结果。 StringTokenizer 确实比 String.split() 更快,但对于大多数实际用途来说,String.split() 已经足够快了。

查看此问题的答案了解更多详情Scanner vs. StringTokenizer vs. String.Split

虽然技术上确实如此,总体而言,StringTokenizerString.split() 快,但当您将范围缩小到单个字符定界符时,它们在性能方面几乎相同。

查看 String.split() 源代码显示它检查正则表达式模式是否是简单的分隔符,如果是,它会执行老式的 while 循环来搜索 String。在我发起的一个简单测试中,使用单个 char 来解析字符串时,我发现时间几乎没有差异。这是 StringTokenizer 的典型用例。因此,为了如此微小的性能提升而编写所有额外代码确实不值得。