我正试图减少我正在研究的程序的运行时间,我想找出一种更简单的方法来查找具有整数值的字符的索引。
目前,我的函数跟踪字符串的每个字符,并返回它找到的第一个整数的索引。举个例子,如果我有字符串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
以及使用Pattern
和Matcher
类的例子。
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