在每个第n个位置拆分一个字符串

Emi*_*kes 30 java regex string split

我使用这个正则表达式在每个第三个位置分割一个字符串:

String []thisCombo2 = thisCombo.split("(?<=\\G...)");
Run Code Online (Sandbox Code Playgroud)

其中G之后的3个点表示要分割的每个第n个位置.在这种情况下,3个点表示每3个位置.一个例子:

Input: String st = "123124125134135145234235245"
Output: 123 124 125 134 135 145 234 235 245.
Run Code Online (Sandbox Code Playgroud)

我的问题是,如何让用户控制必须拆分字符串的位置数?换句话说,如何制作用户控制的3个点,n个点?

Ask*_* B. 44

为了大幅提升性能,另一种方法是substring()在循环中使用:

public String[] splitStringEvery(String s, int interval) {
    int arrayLength = (int) Math.ceil(((s.length() / (double)interval)));
    String[] result = new String[arrayLength];

    int j = 0;
    int lastIndex = result.length - 1;
    for (int i = 0; i < lastIndex; i++) {
        result[i] = s.substring(j, j + interval);
        j += interval;
    } //Add the last bit
    result[lastIndex] = s.substring(j);

    return result;
}
Run Code Online (Sandbox Code Playgroud)

例:

Input:  String st = "1231241251341351452342352456"
Output: 123 124 125 134 135 145 234 235 245 6.
Run Code Online (Sandbox Code Playgroud)

它不像stevevls的解决方案那么短,但它的效率更高(见下文),我认为将来更容易调整,当然这取决于你的情况.


性能测试(Java 7u45)

2,000个字符长字符串 - 间隔为3.

split("(?<=\\G.{" + count + "})") 性能(以毫秒为单位):

7, 7, 5, 5, 4, 3, 3, 2, 2, 2
Run Code Online (Sandbox Code Playgroud)

splitStringEvery()(substring())性能(以毫秒为单位):

2, 0, 0, 0, 0, 1, 0, 1, 0, 0
Run Code Online (Sandbox Code Playgroud)

2,000,000个字符长字符串 - 间隔为3.

split() 性能(以毫秒为单位):

207, 95, 376, 87, 97, 83, 83, 82, 81, 83
Run Code Online (Sandbox Code Playgroud)

splitStringEvery() 性能(以毫秒为单位):

44, 20, 13, 24, 13, 26, 12, 38, 12, 13
Run Code Online (Sandbox Code Playgroud)

2,000,000个字符长字符串 - 间隔为30.

split() 性能(以毫秒为单位):

103, 61, 41, 55, 43, 44, 49, 47, 47, 45
Run Code Online (Sandbox Code Playgroud)

splitStringEvery() 性能(以毫秒为单位):

7, 7, 2, 5, 1, 3, 4, 4, 2, 1
Run Code Online (Sandbox Code Playgroud)

结论:

splitStringEvery()方法更快(即使在Java 7u6中发生更改之后),并且当间隔变得更高时它会升级.

即用型测试代码:

pastebin.com/QMPgLbG9

  • 这不仅仅是过早的优化吗? (5认同)
  • @thedayturns为什么要用问号发表该陈述?不要不确定你的指控.这是对那些[浪费时间进行不必要的性能改进]的人应该使用的指控之一(http://programmers.stackexchange.com/a/79954/62391).无论如何,这是快速编写的,随时可用的代码; 至少对我来说更容易理解; 并且在正面,它在最后一种情况下运行例如**快60倍**(它随着间隔增长*指数*).我的整个表演研究行为可能是不必要的,但现在它已经存在了几代人. (4认同)

ste*_*vls 29

您可以使用大括号运算符指定角色必须出现的次数:

String []thisCombo2 = thisCombo.split("(?<=\\G.{" + count + "})");
Run Code Online (Sandbox Code Playgroud)

大括号是一个方便的工具,因为您可以使用它来指定精确的计数或范围.


epo*_*och 20

使用Google Guava,您可以使用Splitter.fixedLength()

返回将字符串分成给定长度的片段的拆分器

Splitter.fixedLength(2).split("abcde");
// returns an iterable containing ["ab", "cd", "e"].
Run Code Online (Sandbox Code Playgroud)