स्ट्रिंग में स्थानापन्न की घटनाएँ


122

निम्नलिखित एल्गोरिथ्म मेरे लिए क्यों नहीं रुक रहा है? (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);

8
हमने उडासिटी में वास्तव में एक अच्छा किया: हमने newSTR = str.replace (findStr, "") का उपयोग किया; और लौटी गिनती = ((str.length () - newSTR.length ()) / findStr.length ());
SolarLunix

पात्रों के लिए इसी तरह का प्रश्न: stackoverflow.com/q/275944/873282
koppor

क्या आप उस मामले के लिए भी जिम्मेदार नहीं हैं जहां खोज स्ट्रिंग का उपसर्ग उसके प्रत्यय है? उस स्थिति में मुझे नहीं लगता कि सुझाए गए जवाबों में से कोई भी काम करेगा। यहाँ एक उदाहरण है। उस स्थिति में आपको अधिक विस्तृत एल्गोरिथ्म की आवश्यकता होगी, जैसे कि नथ मॉरिस प्रैट (KMP) जो CLRS पुस्तक में कोडित है
सिड

यह आपके लिए नहीं रुक रहा है, क्योंकि आपकी 'पड़ाव' स्थिति (lastIndex == -1) तक पहुंचने के बाद आप इसे lastIndex (lastIndex + = findStr.length ()) का मान बढ़ाकर रीसेट कर देते हैं;
लेगना

जवाबों:


83

आखिरी लाइन एक समस्या पैदा कर रही थी। 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);

121
यह उत्तर उस पोस्ट की सटीक प्रति है जो मैंने एक घंटे पहले बनाई थी;)
ओलिवियर

8
ध्यान दें कि यह अपेक्षित परिणाम वापस कर सकता है या नहीं। "आ" और स्ट्रिंग के साथ "आ" खोजने के लिए अपेक्षित घटनाओं की संख्या एक हो सकती है (इस कोड द्वारा लौटाया गया है), लेकिन दो भी हो सकते हैं (इस मामले में आपको "lastIndex ++" के बजाय "lastIndex ++" की आवश्यकता होगी) findStr.length () ") जो आप देख रहे हैं उसके आधार पर।
स्टैनिस्लाव नियाज़ेव

@olivier ने यह नहीं देखा कि :(( @ Thats बिल्कुल सही है ... मैं सिर्फ समस्या में कोड तय कर रहा था ... लगता है कि यह निर्भर करता है कि स्ट्रिंग में होने वाली संख्याओं के द्वारा bobcom का क्या अर्थ है ...
codebreach

1
जब लोग कॉपी और पेस्ट स्टैटिक विधि में इस तरह सामान लपेटना सीख रहे हैं? मेरा जवाब नीचे देखें, यह और भी अनुकूलित है।
एमएमएम

1
यहाँ नैतिक यह है कि यदि आप उत्तर लिखने का इरादा कर रहे हैं, तो पहले जांच लें कि किसी और ने पहले से ही सटीक उत्तर लिखा है या नहीं। एक ही उत्तर के दो बार होने का वास्तव में कोई लाभ नहीं है, चाहे आपका उत्तर कॉपी किया गया हो या स्वतंत्र रूप से लिखा गया हो।
दाऊद इब्न करीम

192

कैसे Apache कॉमन्स लैंग से StringUtils.countMatches का उपयोग करने के बारे में ?

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

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

यह आउटपुट:

3

9
कोई फर्क नहीं पड़ता कि यह सुझाव कितना सही है, इसे समाधान के रूप में स्वीकार नहीं किया जा सकता क्योंकि यह ओपी के सवाल का जवाब नहीं दे रहा है
kommradHomer

3
यह पदावनत है या कुछ और है .. मेरी आईडीई पहचान नहीं रही है
वामसी पावन महेश

@VamsiPavanMahesh StringUtils Apache Commons की लाइब्रेरी है। यहाँ देखें: commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/…
अनूप

यह उत्तर एक दिन पहले पीटर लॉरी के उत्तर की एक प्रति है (नीचे देखें)।
ज़ोन

StringUtilscountMatchesविधि नहीं है।
plaidshirt

117

आपका 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);

92

एक छोटा संस्करण। ;)

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

8
return haystack.split(Pattern.quote(needle), -1).length - 1;अगर उदाहरण के लिएneedle=":)"
Mr_and_Mrs_D

2
@lOranger इसके बिना ,-1यह ट्रेलिंग मैच छोड़ देगा।
पीटर लॉरी

3
आउच, धन्यवाद, जानकर अच्छा लगा! यह मुझे javadoc में छोटी लाइनों को पढ़ने के लिए सिखाएगा ...
लॉरेंट ग्रेजायर

4
अच्छा! लेकिन इसमें केवल गैर-अतिव्यापी मैच शामिल हैं, नहीं? उदाहरण के लिए "आ" का "आ" मिलना 1, 2 नहीं 1 होगा? ओवरलैपिंग या नॉन-ओवरलैपिंग मैच सहित बेशक दोनों वैध हैं और उपयोगकर्ता की आवश्यकताओं पर निर्भर करते हैं (शायद गिनती ओवरलैप्स को इंगित करने के लिए एक झंडा, हां या नहीं)?
कॉर्नेल मासन

2
-1 .. "आआआ" और "आ" पर इसे चलाने का प्रयास करें .. सही उत्तर 3 नहीं 2 है।
कल्याणाराम संथानम

79

क्या आपको वास्तव में अपने आप से मेल खाना है? खासकर यदि आप सभी की जरूरत घटनाओं की संख्या है, नियमित अभिव्यक्ति tidier हैं:

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);     

1
यह विशेष वर्ण नहीं ढूंढता है, यह नीचे तार के लिए 0 की गिनती पाएगा: String str = "hel+loslkhel+lodjladfjhel+lo"; Pattern p = Pattern.compile("hel+lo");
बेन

13
हाँ, यदि आप अपने रेगेक्स को सही ढंग से व्यक्त करेंगे। साथ कोशिश संकेत एक regex और जरूरतों में एक विशेष अर्थ से बच गया हो गया है। Pattern.compile("hel\\+lo");+
जीन

4
यदि आप जिस चीज की तलाश कर रहे हैं, वह एक मनमाना स्ट्रिंग लेना है और इसे एक सटीक मेल के रूप में उपयोग करना है जिसे सभी विशेष नियमित अभिव्यक्ति वर्णों के साथ अनदेखा किया जाता है, Pattern.quote(str)तो आपका मित्र है!
माइक फर्टक

2
यह "आ" के लिए काम नहीं करता है जब str = "aaaaaa"। 4 जवाब हैं, लेकिन तुम्हारा 2 दे रहे हैं
पूजन श्रीवास्तव

यह समाधान इस स्थिति के लिए काम नहीं करता है: str = "यह एक परीक्षण \\ n \\ r स्ट्रिंग है", subStr = "\\ r", यह 0 घटनाओं को दर्शाता है।
मकिस्म ओवसियनिकोव

19

मुझे बहुत आश्चर्य है कि किसी ने भी इस एक लाइनर का उल्लेख नहीं किया है। यह सरल, संक्षिप्त है और तुलना में थोड़ा बेहतर हैstr.split(target, -1).length-1

public static int count(String str, String target) {
    return (str.length() - str.replace(target, "").length()) / target.length();
}

शीर्ष उत्तर होना चाहिए। धन्यवाद!
lakam99

12

यह एक अच्छा और पुन: प्रयोज्य विधि में लिपटे है:

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;
}

8
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 है; आशा करता हूँ की ये काम करेगा


5
कोड में एक त्रुटि है। यदि हम किसी एकल वर्ण की खोज करते हैं, तो findStr.length() - 1रिटर्न 0 और हम एक अंतहीन चक्र में हैं।
जन बोधन

6

दिए गए उत्तरों में से एक या एक से अधिक पर विफल:

  • मनमानी लंबाई के पैटर्न
  • ओवरलैपिंग मैच (जैसे "23232 में" 232 "या" आ "में" आ "गिनना)
  • नियमित अभिव्यक्ति मेटा-वर्ण

यहाँ मैंने क्या लिखा है:

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

हाँ ... आश्चर्य है कि Apache StringUtils में ऐसा कुछ नहीं है।
माइक कृंतक

6
public int countOfOccurrences(String str, String subStr) {
  return (str.length() - str.replaceAll(Pattern.quote(subStr), "").length()) / subStr.length();
}

अच्छा उत्तर। क्या आप कुछ नोट्स को जोड़ने का मन बना सकते हैं कि यह कैसे काम करता है?
संतोष कुमार २

ज़रूर, str - हमारा स्रोत स्ट्रिंग है, सबस्ट्र्र - एक विकल्प है। लक्ष्य str में subStr की घटनाओं की मात्रा की गणना करना है। ऐसा करने के लिए, हम सूत्र का उपयोग करते हैं: (ab) / c, जहाँ a - str की लम्बाई, b - सबस्ट्र के सभी आवृत्तियों के बिना str की लंबाई (हम इसके लिए str से सबस्टार की सभी घटनाओं को हटाते हैं), c - उप-लंबाई की लंबाई । तो, मूल रूप से हम सब-स्ट्रस्ट्र के बिना स्ट्रों की लंबाई से स्ट्रै की लंबाई से निकालते हैं, और फिर हम सबस्ट्र्र की लंबाई पर परिणाम को विभाजित करते हैं। यदि आपके कोई अन्य प्रश्न हैं तो कृपया मुझे बताएं।
मैक्सिमम ओवसियानिकोव

संतोष, आपका स्वागत है! महत्वपूर्ण हिस्सा सबस्ट्र्र के लिए पैटर्न का उपयोग करना है। अन्यथा, कुछ मामलों में विफल हो सकता है, जैसे कि यह एक: str = "यह एक परीक्षण \\ n \\ r स्ट्रिंग है", subStr = "\\ r"। यहां दिए गए कुछ समान उत्तर पैटर्न का उपयोग नहीं करते हैं, इसलिए वे ऐसे मामलों में विफल होंगे।
मकिस्म ओवसियनिकोव

रेगेक्स का कोई कारण नहीं है, उपयोग replace, नहीं replaceAll
नैट्स


3
public int indexOf(int ch,
                   int fromIndex)

निर्दिष्ट वर्ण पर खोज शुरू करते हुए, निर्दिष्ट वर्ण की पहली घटना के इस स्ट्रिंग के भीतर सूचकांक लौटाता है।

तो आपका lastindexमान हमेशा 0 होता है और यह हमेशा स्ट्रिंग में हैलो पाता है ।


2

उत्तर के रूप में दिया गया उत्तर पंक्ति रिटर्न जैसी चीजों को गिनने के लिए अच्छा नहीं है और यह बहुत अधिक क्रिया है। बाद में उत्तर बेहतर हैं, लेकिन सभी के साथ बस हासिल किया जा सकता है

str.split(findStr).length

यह प्रश्न में उदाहरण का उपयोग करके अनुगामी मैचों को नहीं छोड़ता है।


1
यह पहले से ही एक और जवाब में कवर किया गया है ; और उस उत्तर ने भी बेहतर किया।
michaelb958 - GoFundMonica

1
यह प्रश्न में उत्तर पर टिप्पणी होनी चाहिए, अन्य उत्तर में नहीं।
james.garriss

2

आप इनबिल्ट लाइब्रेरी फ़ंक्शन का उपयोग करके घटनाओं की संख्या:

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

1
काम नहीं करता है, आपको आपके द्वारा उपयोग की जाने वाली निर्भरता को निर्दिष्ट करना चाहिए।
सैकत

1

lastIndex+=findStr.length()अपने लूप के अंत में जोड़ने का प्रयास करें, अन्यथा आप एक अंतहीन लूप में समाप्त हो जाएंगे क्योंकि एक बार जब आप सबस्ट्रिंग पाया, तो आप इसे एक ही अंतिम स्थिति से बार-बार खोजने की कोशिश कर रहे हैं।


1

इसको आजमाओ। यह सभी मैचों की जगह ए -

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

1

जैसा कि @Mr_and_Mrs_D ने सुझाव दिया है:

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

1

मौजूदा उत्तर के आधार पर, मैं बिना "छोटा" संस्करण जोड़ना चाहूंगा:

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

यदि स्ट्रिंग दोहराती है तो आप इसे ध्यान में रखते हैं, उदाहरण के लिए यदि आप स्ट्रिंग 'xx' को स्ट्रिंग 'xxx' में देख रहे हैं।
tCoe

1

यहाँ एक गिनती के लिए उन्नत संस्करण दिया गया है जो एक उपयोगकर्ता द्वारा दर्ज स्ट्रिंग में कितनी बार हुआ है:

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);
    }

}

1

यह नीचे दी गई विधि से पता चलता है कि उर पूरे स्ट्रिंग पर कितने समय में प्रतिस्थापन दोहराया गया है। आशा है कि आप का पूरा उपयोग करें: -

    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++;
        }

    }

0

यहां रेगेक्सपी / पैटर्न / माचिस का उपयोग किए बिना या यहां तक ​​कि स्ट्रिंगरिल्ट्स का उपयोग किए बिना अन्य समाधान है।

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);

0

यदि आपको मूल स्ट्रिंग के भीतर प्रत्येक प्रतिस्थापन के सूचकांक की आवश्यकता है, तो आप इस तरह 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;
}

0
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;

}


यह प्रश्न 8 साल पुराना है, और किसी भी संकेत के बिना कि यह 22 पोस्ट किए गए अन्य समाधानों की तुलना में बेहतर समाधान क्यों है, इसे संभवतः हटा दिया जाना चाहिए
जेसन व्हीलर

0

यह समाधान पूरे स्ट्रिंग में दिए गए सबस्ट्रिंग की घटना की कुल संख्या को प्रिंट करता है, इसमें उन मामलों को भी शामिल किया जाता है जहां ओवरलैपिंग मैच मौजूद हैं।

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);
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.