字符串中子字符串的出现

为什么下面的算法对我来说没有停止? (str 是我要搜索的字符串,findStr 是我要找的字符串)

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;


while (lastIndex != -1) {
lastIndex = str.indexOf(findStr,lastIndex);


if( lastIndex != -1)
count++;


lastIndex += findStr.length();
}


System.out.println(count);
409345 次浏览

增加 lastIndex每当您寻找下一个发生。

否则它总是找到第一个子字符串(位置0)。

public int indexOf(int ch,
int fromIndex)

返回此字符串中指定字符第一个匹配项的索引,从指定索引处开始搜索。

因此 lastindex值总是0,并且它总是在字符串中找到 你好

尝试将 lastIndex+=findStr.length()添加到循环的末尾,否则您将陷入一个无止境的循环,因为一旦您找到了子字符串,您将尝试从相同的最后位置一次又一次地找到它。

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;


while((lastIndex = str.indexOf(findStr, lastIndex)) != -1) {
count++;
lastIndex += findStr.length() - 1;
}
System.out.println(count);

在循环结束时,计数是3; 希望能有所帮助

你真的要自己处理配对吗?特别是如果你需要的只是出现的次数,正则表达式更整洁:

String str = "helloslkhellodjladfjhello";
Pattern p = Pattern.compile("hello");
Matcher m = p.matcher(str);
int count = 0;
while (m.find()){
count +=1;
}
System.out.println(count);

您的 lastIndex += findStr.length();被放置在括号外,导致了一个无限循环(当没有发生时,lastIndex 总是指向 findStr.length())。

以下是固定版本:

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;


while (lastIndex != -1) {


lastIndex = str.indexOf(findStr, lastIndex);


if (lastIndex != -1) {
count++;
lastIndex += findStr.length();
}
}
System.out.println(count);

最后一行造成了一个问题。lastIndex永远不会是 -1,所以会有一个无限循环。这个问题可以通过将最后一行代码移动到 if 块中来解决。

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;


while(lastIndex != -1){


lastIndex = str.indexOf(findStr,lastIndex);


if(lastIndex != -1){
count ++;
lastIndex += findStr.length();
}
}
System.out.println(count);

更简短的版本。 ;)

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
System.out.println(str.split(findStr, -1).length-1);

使用 Apache Commons Lang 中的 StringUtils.CountMatches如何?

String str = "helloslkhellodjladfjhello";
String findStr = "hello";


System.out.println(StringUtils.countMatches(str, findStr));

产出:

3

试试这个,它用 -代替所有的匹配。

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int numberOfMatches = 0;
while (str.contains(findStr)){
str = str.replaceFirst(findStr, "-");
numberOfMatches++;
}

如果你不想破坏你的 str,你可以创建一个内容相同的新字符串:

String str = "helloslkhellodjladfjhello";
String strDestroy = str;
String findStr = "hello";
int numberOfMatches = 0;
while (strDestroy.contains(findStr)){
strDestroy = strDestroy.replaceFirst(findStr, "-");
numberOfMatches++;
}

执行这个代码块之后,下面是您的值:

str = "helloslkhellodjladfjhello"
strDestroy = "-slk-djladfj-"
findStr = "hello"
numberOfMatches = 3

下面是用于计算令牌在用户输入字符串中出现多少次的高级版本:

public class StringIndexOf {


public static void main(String[] args) {


Scanner scanner = new Scanner(System.in);


System.out.println("Enter a sentence please: \n");
String string = scanner.nextLine();


int atIndex = 0;
int count = 0;


while (atIndex != -1)
{
atIndex = string.indexOf("hello", atIndex);


if(atIndex != -1)
{
count++;
atIndex += 5;
}
}


System.out.println(count);
}


}

下面的方法显示子字符串在整个字符串上重复的次数

    String searchPattern="aaa"; // search string
String str="aaaaaababaaaaaa"; // whole string
int searchLength = searchPattern.length();
int totalLength = str.length();
int k = 0;
for (int i = 0; i < totalLength - searchLength + 1; i++) {
String subStr = str.substring(i, searchLength + i);
if (subStr.equals(searchPattern)) {
k++;
}


}

如果给出的答案是正确的,那么对于计算行返回值之类的东西是没有用的,而且太冗长了。以后的答案会更好,但所有的答案都可以通过简单的

str.split(findStr).length

它不会使用问题中的示例删除尾随匹配项。

下面是另一种不使用 regexp/pattern/matcher 甚至不使用 StringUtils 的解决方案。

String str = "helloslkhellodjladfjhelloarunkumarhelloasdhelloaruhelloasrhello";
String findStr = "hello";
int count =0;
int findStrLength = findStr.length();
for(int i=0;i<str.length();i++){
if(findStr.startsWith(Character.toString(str.charAt(i)))){
if(str.substring(i).length() >= findStrLength){
if(str.substring(i, i+findStrLength).equals(findStr)){
count++;
}
}
}
}
System.out.println(count);

如果您需要原始字符串中每个子字符串的索引,您可以使用 indexOf 进行如下操作:

 private static List<Integer> getAllIndexesOfSubstringInString(String fullString, String substring) {
int pointIndex = 0;
List<Integer> allOccurences = new ArrayList<Integer>();
while(fullPdfText.indexOf(substring,pointIndex) >= 0){
allOccurences.add(fullPdfText.indexOf(substring, pointIndex));
pointIndex = fullPdfText.indexOf(substring, pointIndex) + substring.length();
}
return allOccurences;
}

正如@Mr _ and _ Mrs _ D 所建议的:

String haystack = "hellolovelyworld";
String needle = "lo";
return haystack.split(Pattern.quote(needle), -1).length - 1;

下面是一个很好的、可重用的方法:

public static int count(String text, String find) {
int index = 0, count = 0, length = find.length();
while( (index = text.indexOf(find, index)) != -1 ) {
index += length; count++;
}
return count;
}

许多给出的答案都在以下一个或多个问题上失败了:

  • 任意长度的图案
  • 重叠匹配(例如在“23232”中计算“232”或在“ aaa”中计算“ aa”)
  • 正则表达式元字符

我是这么写的:

static int countMatches(Pattern pattern, String string)
{
Matcher matcher = pattern.matcher(string);


int count = 0;
int pos = 0;
while (matcher.find(pos))
{
count++;
pos = matcher.start() + 1;
}


return count;
}

示例呼叫:

Pattern pattern = Pattern.compile("232");
int count = countMatches(pattern, "23232"); // Returns 2

如果需要非正则表达式搜索,只需使用 LITERAL标志适当地编译模式:

Pattern pattern = Pattern.compile("1+1", Pattern.LITERAL);
int count = countMatches(pattern, "1+1+1"); // Returns 2

基于现有的答案,我想添加一个“较短”的版本,没有 if:

String str = "helloslkhellodjladfjhello";
String findStr = "hello";


int count = 0, lastIndex = 0;
while((lastIndex = str.indexOf(findStr, lastIndex)) != -1) {
lastIndex += findStr.length() - 1;
count++;
}


System.out.println(count); // output: 3

使用内置库函数可以查看出现的次数:

import org.springframework.util.StringUtils;
StringUtils.countOccurrencesOf(result, "R-")

我非常惊讶没有人提到这一行。它简单,简洁,性能略好于 str.split(target, -1).length-1

public static int count(String str, String target) {
return (str.length() - str.replace(target, "").length()) / target.length();
}
public int countOfOccurrences(String str, String subStr) {
return (str.length() - str.replaceAll(Pattern.quote(subStr), "").length()) / subStr.length();
}
public static int getCountSubString(String str , String sub){
int n = 0, m = 0, counter = 0, counterSub = 0;
while(n < str.length()){
counter = 0;
m = 0;
while(m < sub.length() && str.charAt(n) == sub.charAt(m)){
counter++;
m++; n++;
}
if (counter == sub.length()){
counterSub++;
continue;
}
else if(counter > 0){
continue;
}
n++;
}


return  counterSub;

}

该解决方案打印整个字符串中给定子字符串出现的总次数,还包括存在重叠匹配的情况。

class SubstringMatch{
public static void main(String []args){
//String str = "aaaaabaabdcaa";
//String sub = "aa";
//String str = "caaab";
//String sub = "aa";
String str="abababababaabb";
String sub = "bab";


int n = str.length();
int m = sub.length();


// index=-1 in case of no match, otherwise >=0(first match position)
int index=str.indexOf(sub), i=index+1, count=(index>=0)?1:0;
System.out.println(i+" "+index+" "+count);


// i will traverse up to only (m-n) position
while(index!=-1 && i<=(n-m)){
index=str.substring(i, n).indexOf(sub);
count=(index>=0)?count+1:count;
i=i+index+1;
System.out.println(i+" "+index);
}
System.out.println("count: "+count);
}
}

再来点甜言蜜语

    public int countOccurrences(String str, String sub) {
if (str == null || str.length() == 0 || sub == null || sub.length() == 0) return 0;
int count = 0;
int i = 0;
while ((i = str.indexOf(sub, i)) != -1) {
count++;
i += sub.length();
}
return count;
}

我刚才在一次采访中被问到这个问题,我完全不知所措。(像往常一样,我告诉自己,面试一结束就会有答案)我做到了,电话结束5分钟后:

    int subCounter=0;
int count =0;
for(int i=0; i<str.length(); i++) {
if((subCounter==0 && "a".equals(str.substring(i,i+1)))
|| (subCounter==1 && "b".equals(str.substring(i,i+1)))
|| (subCounter==2 && "c".equals(str.substring(i,i+1)))) {
++subCounter;
}
if(subCounter==3) {
count = count+1;
subCounter=0;
}
}
System.out.println(count);