Возникновение подстроки в строке
Почему для меня не останавливается следующий алгоритм? (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);
Ответы
Ответ 1
Последняя строка создавала проблему. 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);
Ответ 2
Как насчет использования StringUtils.countMatches от Apache Commons Lang?
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
System.out.println(StringUtils.countMatches(str, findStr));
Это выводит:
3
Ответ 3
Ваш 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);
Ответ 4
Более короткая версия.;)
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
System.out.println(str.split(findStr, -1).length-1);
Ответ 5
Вам действительно нужно справляться с совпадением? Особенно, если вам нужно только количество вхождений, регулярные выражения являются более аккуратными:
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);
Ответ 6
Вот он, завернутый в хороший и многоразовый метод:
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;
}
Ответ 7
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; надеюсь, что это поможет
Ответ 8
public int countOfOccurrences(String str, String subStr) {
return (str.length() - str.replaceAll(Pattern.quote(subStr), "").length()) / subStr.length();
}
Ответ 9
Многие из приведенных ответов терпят неудачу на одном или нескольких из:
- Шаблоны произвольной длины
- Перекрывающиеся совпадения (например, подсчет "232" в "23232" или "aa" в "aaa" )
- Мета-символы регулярного выражения
Вот что я написал:
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
Ответ 10
Я очень удивлен, что никто не упомянул этот лайнер. Он простой, лаконичный и работает немного лучше, чем str.split(target, -1).length-1
public static int count(String str, String target) {
return (str.length() - str.replace(target, "").length()) / target.length();
}
Ответ 11
Приращение lastIndex
всякий раз, когда вы ищете следующее вхождение.
В противном случае всегда найдется первая подстрока (в позиции 0).
Ответ 12
public int indexOf(int ch,
int fromIndex)
Возвращает индекс в этой строке первого вхождения указанного символа, начиная поиск по указанному индексу.
Итак, ваше значение lastindex
всегда равно 0, и оно всегда находит привет в строке.
Ответ 13
Ответ, приведенный как правильный, не годится для подсчета таких вещей, как возврат строк и слишком многословный. Более поздние ответы лучше, но все может быть достигнуто просто с помощью
str.split(findStr).length
Он не отбрасывает завершающие совпадения, используя пример в вопросе.
Ответ 14
Вы можете указать количество вхождений, используя встроенную библиотечную функцию:
import org.springframework.util.StringUtils;
StringUtils.countOccurrencesOf(result, "R-")
Ответ 15
попробуйте добавить lastIndex+=findStr.length()
в конец вашего цикла, иначе вы окажетесь в бесконечном цикле, потому что как только вы найдете подстроку, вы пытаетесь найти ее снова и снова из той же последней позиции.
Ответ 16
Попробуйте это. Он заменяет все совпадения на -
.
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
Ответ 17
Этот метод ниже показывает, сколько временных подстрок повторяется на всей строке. Надеюсь использовать полное вам: -
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++;
}
}
Ответ 18
Как предложил @Mr_and_Mrs_D:
String haystack = "hellolovelyworld";
String needle = "lo";
return haystack.split(Pattern.quote(needle), -1).length - 1;
Ответ 19
Основываясь на существующих ответах, я хотел бы добавить "более короткую" версию без 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
Ответ 20
Вот расширенная версия для подсчета, сколько раз токен произошел в введенной пользователем строке:
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);
}
}
Ответ 21
вот другое решение без использования regexp/patterns/matchers или даже без использования 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);
Ответ 22
Если вам нужен индекс каждой подстроки в исходной строке, вы можете сделать что-то с 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;
}
Ответ 23
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;
}
Ответ 24
Это решение печатает общее количество появления данной подстроки во всей строке, также включает случаи, когда совпадающие совпадения существуют.
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);
}
}