कैसे एक स्ट्रिंग में चरित्र की नौवीं घटना खोजने के लिए?


95

यहां पोस्ट किए गए एक प्रश्न के समान , मैं जावा में एक समाधान की तलाश कर रहा हूं।

अर्थात्, एक स्ट्रिंग से वर्ण / स्ट्रिंग की nth घटना का सूचकांक कैसे खोजा जाए?

उदाहरण: " / folder1 / folder2 / folder3 / "। इस स्थिति में, यदि मैं स्लैश (/) की तीसरी घटना के लिए पूछता हूं, तो यह फ़ोल्डर 3 से पहले दिखाई देता है, और मुझे इस सूचकांक स्थिति को वापस करने की उम्मीद है। मेरा वास्तविक इरादा इसे एक चरित्र की नौवीं घटना से प्रतिस्थापित करना है।

क्या जावा एपीआई में कोई सुविधाजनक / रेडी-टू-यूज़ विधि उपलब्ध है या क्या हमें इसे हल करने के लिए अपने आप पर एक छोटा सा तर्क लिखने की आवश्यकता है?

इसके अलावा,

  1. मैंने जल्दी से खोजा कि क्या Apache Commons Lang के StringUtils में इस उद्देश्य के लिए कोई विधि समर्थित है , लेकिन मुझे कोई नहीं मिला।
  2. क्या नियमित अभिव्यक्ति इस संबंध में मदद कर सकती है?

2
अपने विशेष उदाहरण के लिए, आप परिणाम के साथ क्या करना चाहते हैं इसके आधार पर, स्ट्रिंग को / पर विभाजित करना आसान हो सकता है, जो आपको अच्छी तरह से दे सकता है जो आपको सीधे चाहिए?
अर्चेतपाल पॉल

@Paul: यह भी एक अच्छा विचार है।
Gnanam

जवाबों:


128

यदि आपकी परियोजना पहले से ही अपाचे कॉमन्स पर निर्भर करती है StringUtils.ordinalIndexOf, तो आप इसका उपयोग कर सकते हैं , अन्यथा, यहाँ एक कार्यान्वयन है:

public static int ordinalIndexOf(String str, String substr, int n) {
    int pos = str.indexOf(substr);
    while (--n > 0 && pos != -1)
        pos = str.indexOf(substr, pos + 1);
    return pos;
}

इस पोस्ट को यहाँ एक लेख के रूप में फिर से लिखा गया है


"ऑफ-बाय-वन" त्रुटि के अलावा, @ जोंन स्कीट के समाधान में एक और महान सकारात्मक है - एक मामूली ट्वीक (लूप को उलट कर) के साथ, आप "आखिरी से भी" घटना हो सकती है।
करण चड्ढा

@ केरनधा, इस समाधान में लागू होती है। बस करने के लिए बदल जाते हैं lastIndexOf
ऐयोबे जू

60

मेरा मानना ​​है कि स्ट्रिंग के Nth घटना को खोजने के लिए सबसे आसान उपाय है, Apache Commons से StringUtils.ordinalIndexOf () का उपयोग करना ।

उदाहरण:

StringUtils.ordinalIndexOf("aabaabaa", "b", 2)  == 5

27

दो सरल विकल्प होते हैं:

  • charAt()बार-बार उपयोग करें
  • indexOf()बार-बार उपयोग करें

उदाहरण के लिए:

public static int nthIndexOf(String text, char needle, int n)
{
    for (int i = 0; i < text.length(); i++)
    {
        if (text.charAt(i) == needle)
        {
            n--;
            if (n == 0)
            {
                return i;
            }
        }
    }
    return -1;
}

जो कि indexOfबार-बार उपयोग करने के साथ-साथ अच्छा प्रदर्शन नहीं कर सकता है , लेकिन सही होने के लिए संभवतः सरल है।


15

आप कुछ इस तरह की कोशिश कर सकते हैं:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
      System.out.println(from3rd("/folder1/folder2/folder3/"));
    }

    private static Pattern p = Pattern.compile("(/[^/]*){2}/([^/]*)");

    public static String from3rd(String in) {
        Matcher m = p.matcher(in);

        if (m.matches())
            return m.group(2);
        else
            return null;
    }
}

ध्यान दें कि मैंने regex में कुछ धारणाएँ की हैं:

  • इनपुट पथ निरपेक्ष है (यानी "/" से शुरू होता है);
  • आपको परिणाम में 3rd "/" की आवश्यकता नहीं है।

एक टिप्पणी में अनुरोध के रूप में, मैं regex समझाने की कोशिश करेंगे: (/[^/]*){2}/([^/]*)

नियमित अभिव्यक्ति दृश्य

  • /[^/]*एक है /, जिसके बाद [^/]*(अक्षर हैं जो एक नहीं हैं की किसी भी संख्या /),
  • (/[^/]*)किसी एक इकाई में पिछली अभिव्यक्ति को समूहित करता है। यह 1अभिव्यक्ति का समूह है,
  • (/[^/]*){2}इसका मतलब यह है कि समूह को {2}कई बार मेल खाना चाहिए ,
  • [^/]*फिर से किसी भी वर्ण की संख्या है जो एक नहीं है /,
  • ([^/]*)एकल इकाई में प्रीविओस अभिव्यक्ति को समूहित करता है। यह 2अभिव्यक्ति का nd समूह है।

इस तरह से आपको केवल उस विकल्प को प्राप्त करना है जो दूसरे समूह से मेल खाता है: return m.group(2);

डीबगेज द्वारा छवि शिष्टाचार


1
क्या आप सादे अंग्रेजी में रेगेक्स की व्याख्या कर सकते हैं? जैसे: एक बैकस्लैश जिसके बाद कुछ भी नहीं है जो बैकस्लैश नहीं है एक अनिश्चित समय की संख्या ... तो मुझे यकीन नहीं है।
गत

1
@Ced, मैंने एक स्पष्टीकरण और regex में एक छोटा फिक्स जोड़ा। मुझे उम्मीद है कि अब यह स्पष्ट है।
andcoz

Regex समझाने के लिए धन्यवाद।
विश्व रत्न

8

मैंने aioobe के उत्तर में कुछ बदलाव किए और एक nth lastIndexOf संस्करण प्राप्त किया, और कुछ NPE समस्याओं को ठीक किया। नीचे देखें कोड:

public int nthLastIndexOf(String str, char c, int n) {
        if (str == null || n < 1)
            return -1;
        int pos = str.length();
        while (n-- > 0 && pos != -1)
            pos = str.lastIndexOf(c, pos - 1);
        return pos;
}

3
मुझे लगता है कि यह उचित है कि विधि एक एनपीई फेंकता है यदि nullतर्क के रूप में दिया जाता है। यह मानक पुस्तकालय में सबसे आम व्यवहार है।
एरियोब डे

5
 ([.^/]*/){2}[^/]*(/)

कुछ भी / दो बार, फिर से मिलान करें। तीसरा वह है जो आप चाहते हैं

Matcher राज्य है जहां पिछले / है बताने के लिए इस्तेमाल किया जा सकता


मुझे यकीन है कि यह एक बहुत अच्छा जवाब है, लेकिन मैं अपने कोड में इसका उपयोग कैसे करूं?
ARK

@ -Coz के उत्तर को देखें (अलग-अलग regexp, लेकिन विचार समान है)
Archetypal पॉल

3
public static int nth(String source, String pattern, int n) {

   int i = 0, pos = 0, tpos = 0;

   while (i < n) {

      pos = source.indexOf(pattern);
      if (pos > -1) {
         source = source.substring(pos+1);
         tpos += pos+1;
         i++;
      } else {
         return -1;
      }
   }

   return tpos - 1;
}

3

आजकल वहाँ अपाचे कॉमन्स लैंग का समर्थन है स्ट्रिंगरिल्स ,

यह आदिम है:

int org.apache.commons.lang.StringUtils.ordinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal)

अपनी समस्या के लिए आप निम्नलिखित कोड कर सकते हैं: StringUtils.ordinalIndexOf(uri, "/", 3)

आप किसी स्ट्रिंग में किसी वर्ण की अंतिम nth घटना को lastOrdinalIndexOf विधि से भी ढूँढ सकते हैं ।


3

हो सकता है कि आप इसे String.split (..) विधि के माध्यम से भी प्राप्त कर सकें।

String str = "";
String[] tokens = str.split("/")
return tokens[nthIndex] == null 

2

एक और तरीका:

public static void main(String[] args) {
    String str = "/folder1/folder2/folder3/"; 
    int index = nthOccurrence(str, '/', 3);
    System.out.println(index);
}

public static int nthOccurrence(String s, char c, int occurrence) {
    return nthOccurrence(s, 0, c, 0, occurrence);
}

public static int nthOccurrence(String s, int from, char c, int curr, int expected) {
    final int index = s.indexOf(c, from);
    if(index == -1) return -1;
    return (curr + 1 == expected) ? index : 
        nthOccurrence(s, index + 1, c, curr + 1, expected);
}

2

यह उत्तर @aioobe के उत्तर में सुधार करता है। उस उत्तर में दो बग तय किए गए थे।
1. n = 0 को -1 लौटाना चाहिए।
2. nth घटना -1 लौट आई, लेकिन इसने n-1th घटनाओं पर काम किया।

इसे इस्तेमाल करे !

    public int nthOccurrence(String str, char c, int n) {
    if(n <= 0){
        return -1;
    }
    int pos = str.indexOf(c, 0);
    while (n-- > 1 && pos != -1)
        pos = str.indexOf(c, pos+1);
    return pos;
}

1
public class Sam_Stringnth {

    public static void main(String[] args) {
        String str="abcabcabc";
        int n = nthsearch(str, 'c', 3);
        if(n<=0)
            System.out.println("Character not found");
        else
            System.out.println("Position is:"+n);
    }
    public static int nthsearch(String str, char ch, int n){
        int pos=0;
        if(n!=0){
            for(int i=1; i<=n;i++){
                pos = str.indexOf(ch, pos)+1;
            }
            return pos;
        }
        else{
            return 0;
        }
    }
}

0
/* program to find nth occurence of a character */

import java.util.Scanner;

public class CharOccur1
{

    public static void main(String arg[])
    {
        Scanner scr=new Scanner(System.in);
        int position=-1,count=0;
        System.out.println("enter the string");
        String str=scr.nextLine();
        System.out.println("enter the nth occurence of the character");
        int n=Integer.parseInt(scr.next());
        int leng=str.length();
        char c[]=new char[leng];
        System.out.println("Enter the character to find");
        char key=scr.next().charAt(0);
        c=str.toCharArray();
        for(int i=0;i<c.length;i++)
        {
            if(c[i]==key)
            {
                count++;
                position=i;
                if(count==n)
                {
                    System.out.println("Character found");
                    System.out.println("the position at which the " + count + " ocurrence occurs is " + position);
                    return;
                }
            }
        }
        if(n>count)
        { 
            System.out.println("Character occurs  "+ count + " times");
            return;
        }
    }
}

0

मेरा समाधान:

/**
 * Like String.indexOf, but find the n:th occurance of c
 * @param s string to search
 * @param c character to search for
 * @param n n:th character to seach for, starting with 1
 * @return the position (0-based) of the found char, or -1 if failed
 */

public static int nthIndexOf(String s, char c, int n) {
    int i = -1;
    while (n-- > 0) {
        i = s.indexOf(c, i + 1);
        if (i == -1)
            break;
    }
    return i;
}

0

कोड उर्फ ​​फील्ड चौड़ाई के स्थान पर nth घटना स्थान लौटाता है। उदाहरण। यदि स्ट्रिंग "कम पिघलने में ढेर " है, तो टोकन "लो" के 2 वें धीरज की खोज करने के लिए स्ट्रिंग है , तो आप मेरे साथ सहमत होंगे कि यह 2 कुलदेवता "18 और 21" को घटाने पर है । indexOfOccurance ("स्टैक ओवरफ्लो इन लो मेलो", लो, 2) एक स्ट्रिंग में 18 और 21 रिटर्न देता है।

class Example{
    public Example(){
    }
            public String indexOfOccurance(String string, String token, int nthOccurance) {
                    int lengthOfToken = token.length();
                    int nthCount = 0;
                    for (int shift = 0,count = 0; count < string.length() - token.length() + 2; count++, shift++, lengthOfToken++)
                        if (string.substring(shift, lengthOfToken).equalsIgnoreCase(token)) { 
                    // keeps count of nthOccurance
                            nthCount++; 
                        if (nthCount == nthOccurance){
                    //checks if nthCount  == nthOccurance. If true, then breaks 
                             return String.valueOf(shift)+ " " +String.valueOf(lengthOfToken);   
                        }  
                    }
                    return "-1";
                }
    public static void main(String args[]){
    Example example = new Example();
    String string = "the man, the woman and the child";
    int nthPositionOfThe = 3;
   System.out.println("3rd Occurance of the is at " + example.indexOfOccurance(string, "the", nthPositionOfThe));
    }
    }

0
public static int findNthOccurrence(String phrase, String str, int n)
{
    int val = 0, loc = -1;
    for(int i = 0; i <= phrase.length()-str.length() && val < n; i++)
    {
        if(str.equals(phrase.substring(i,i+str.length())))
        {
            val++;
            loc = i;
        }
    }

    if(val == n)
        return loc;
    else
        return -1;
}

2
हालांकि यह कोड प्रश्न को हल कर सकता है, जिसमें यह भी बताया गया है कि यह समस्या कैसे और क्यों हल करती है, इससे वास्तव में आपके पोस्ट की गुणवत्ता को बेहतर बनाने में मदद मिलेगी, और संभवत: अधिक वोटों का परिणाम होगा। याद रखें कि आप भविष्य में पाठकों के लिए सवाल का जवाब दे रहे हैं, न कि केवल उस व्यक्ति से जो अब पूछ रहा है। कृपया स्पष्टीकरण जोड़ने के लिए अपने उत्तर को संपादित करें और संकेत दें कि क्या सीमाएँ और मान्यताएँ लागू होती हैं।
पिक्स द विजार्ड ऑफ द व्हेल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.