Java字符串函数indexOf()可以查找多个字符吗?



我正试图减少我正在研究的程序的运行时间,我想找出一种更简单的方法来查找具有整数值的字符的索引。

目前,我的函数跟踪字符串的每个字符,并返回它找到的第一个整数的索引。举个例子,如果我有字符串JohnCena1237728394712(是的,这是我想到的第一个字符串),函数应该返回8,因为字符串中出现的第一个整数1的索引是8。然而,它必须先循环遍历每个字符才能找到索引,这有时会变得很昂贵。

如果在尝试想出更简单的方法来做到这一点时有所帮助,我可以确定进入函数,字符串的格式将始终是"[letters]"+"[numbers]",所以我只需要找到(可能是随机的)字母段的结尾来获得我想要的。

我想做的是使用indexOf(),这样我就不必使用循环,但我不知道如何使用函数而不使用十个if语句(当然,这将破坏目的)。

是否有一种方法来检查多个整数,同时使用indexOf(),或其他一些函数?

您可以使用正则表达式匹配器来完成此操作。

类似:

 Pattern pattern = Pattern.compile("\d");
 Matcher matcher = pattern.matcher(inputString);
 if(matcher.find()) {
     return matcher.first();
 }
 return -1;

这是相当可读和可扩展的。有些人可能会认为,与通过字符串的简单for循环相比,它太过了。编译regex需要时间,并且需要创建几个对象,如果您对性能非常关注,那么所有这些都是有代价的。

 for(int i = 0; i < str.length(); i++) {
     char c = str.charAt(i);
     if(c >= '0' && c <= '9') {
         return i;
     }
 }
 return -1;

必须依次查看每个字符,因此无论您编写它还是在您调用的库方法中,都会在某处出现循环。

你可以通过将字符串分解成块并做一些map-reduce-ish的事情来从多个内核中挤出一些速度。但这只适用于非常大的字符串,其中的数字很少。

方法是使用正则表达式,这是一种非常强大的方式来表示字符串内容。

String str = "Hello world";
str.matches("\w+ \w+");                   // returns true

以及使用PatternMatcher类的例子。

String line = "Hello amazing world";
String pattern = "(\w+) \w+ (\w+)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(line);
if (m.find( )) {
     System.out.println(m.group(1));        // Prints "Hello"
     System.out.println(m.group(2));        // Prints "world"
}

您可以检查字符的ascii码,看看它是整数还是非整数

注意:假设整数只有1位

String str = "hello123";
for(int i=0; i < str.length(); i++) {
    char c = str.charAt(i);
    if(c >= '0' && c <= '9') {
         // Code goes here
    }
}

替代解决方案:

  • 为每个目标字符使用indexOf(),但这将具有O(n^2)的时间复杂度
  • 将目标整数的集合存储在一个集合中,然后循环字符串并检查字符是否在集合中(如果整数大于一个数字,这很好)

您也可以避免.charAt(i),尽管它没有多大意义…简单地从字符串中获取一个char数组,然后用一个有索引的FOR循环循环,在到达第一个数字时返回索引:

char[] chars = string.toCharArray();
for (int i=0; i<chars.lenght; i++) {
    if(chars[i] >= '0' && chars[i] <= '9')
        return i; //Or whatever code you need.
}

如果我正确理解了你的问题,你有一堆字符后面跟着一堆整数。

您可以使用修改的二进制搜索来查找字符串中发生转换的点。如果您需要分析非常大的字符串,这应该证明是有用的。最坏情况下性能为O(log n)。

我在下面编写了一个示例:

public class binSearch {
    static int indexFinder(String s) {
        // this doesn't check for invalid inputs btw
        int beg = 0;
        int end = s.length() - 1;
        int mid;
        int iter = 0;
        while (beg < end) {
            System.out.println("Iteration: " + iter + "   String: " + s.substring(beg, end+1));
            mid = (end + beg) / 2;
            System.out.println("Mid: " + mid + "   char: " + s.charAt(mid));
            if (Character.isDigit(s.charAt(mid))) {
                if (Character.isDigit(s.charAt(beg))) {
                    return beg;
                }
                end = mid;
            } else {
                beg = mid + 1;
            }
            iter++;
        }
        return beg;
    }
    public static void main(String[] args) {
        System.out.println("Running");
        String[] strings = {"joohhhnnnnnCEEENNAAAAAA123829898", "efi1029082198"};
        for (String s : strings) {
            StringBuilder check = new StringBuilder();
            for(int i = 0; i < s.length(); i++) {
                check.append(i % 10);
            }
            System.out.println(s);
            System.out.println(check.toString() + "n");
            System.out.println("First int index: " + indexFinder(s) + "nn");
        }
    }
}
输出:

Running
joohhhnnnnnCEEENNAAAAAA123829898
01234567890123456789012345678901
Iteration: 0   String: joohhhnnnnnCEEENNAAAAAA123829898
Mid: 15   char: N
Iteration: 1   String: NAAAAAA123829898
Mid: 23   char: 1
Iteration: 2   String: NAAAAAA1
Mid: 19   char: A
Iteration: 3   String: AAA1
Mid: 21   char: A
Iteration: 4   String: A1
Mid: 22   char: A
First int index: 23

efi1029082198
0123456789012
Iteration: 0   String: efi1029082198
Mid: 6   char: 9
Iteration: 1   String: efi1029
Mid: 3   char: 1
Iteration: 2   String: efi1
Mid: 1   char: f
Iteration: 3   String: i1
Mid: 2   char: i
First int index: 3

最新更新