developer tip

문자열에서 n 번째 문자를 찾는 방법은 무엇입니까?

optionbox 2020. 9. 13. 10:22
반응형

문자열에서 n 번째 문자를 찾는 방법은 무엇입니까?


여기게시 된 질문과 유사하게 Java로 솔루션을 찾고 있습니다.

즉, 문자열에서 문자 / 문자열의 n 번째 발생 인덱스를 찾는 방법은 무엇입니까?

예 : " / folder1 / folder2 / folder3 / ". 이 경우 세 번째 슬래시 (/)를 요청하면 folder3 앞에 나타나며이 인덱스 위치를 반환 할 것으로 예상합니다. 내 실제 의도는 문자의 n 번째 발생에서 부분 문자열을 만드는 것입니다.

Java API에서 사용할 수있는 편리하고 즉시 사용할 수있는 방법이 있습니까? 아니면이 문제를 해결하기 위해 자체적으로 작은 논리를 작성해야합니까?

또한,

  1. Apache Commons Lang의 StringUtils 에서 이러한 목적으로 지원되는 방법이 있는지 빠르게 검색 했지만 찾을 수 없습니다.
  2. 이와 관련하여 정규 표현식이 도움이 될 수 있습니까?

프로젝트가 이미 Apache Commons에 의존하는 경우를 사용할 수 있습니다 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;
}

이 게시물은 여기 에 기사로 다시 작성되었습니다 .


문자열의 N 번째 발생을 찾는 가장 쉬운 해결책 은 Apache Commons에서 StringUtils.ordinalIndexOf () 를 사용하는 것 입니다.

예:

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

두 가지 간단한 옵션이 발생합니다.

  • 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반복적 으로 사용하는 것만 큼 성능이 좋지 않을 수 있지만 올바르게 사용 하는 것이 더 간단 할 수 있습니다.


다음과 같이 시도 할 수 있습니다.

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

정규식에서 몇 가지 가정을 수행했습니다.

  • 입력 경로는 절대적입니다 (예 : "/"로 시작).
  • 결과에 세 번째 "/"가 필요하지 않습니다.

의견에서 요청한대로 정규식을 설명하려고합니다. (/[^/]*){2}/([^/]*)

정규식 시각화

  • /[^/]*A는 /다음 [^/]*의 (a하지 않은 문자의 수 /)
  • (/[^/]*)이전 표현식을 단일 항목으로 그룹화합니다. 이것은 1표현식 st 그룹입니다.
  • (/[^/]*){2}그룹이 정확히 {2}시간 과 일치해야 함을 의미합니다.
  • [^/]*다시 말하지만 /,
  • ([^/]*)previos 표현식을 단일 엔티티로 그룹화합니다. 이것은 2표현식 의 두 번째 그룹입니다.

이렇게하면 두 번째 그룹과 일치하는 부분 문자열 만 가져 오면됩니다. return m.group(2);

이미지 제공 : Debuggex


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

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

/ 두 번 뒤에 오는 모든 항목을 일치시킨 다음 다시 일치시킵니다. 세 번째는 당신이 원하는 것입니다

매처 / 마지막이고 상태는 말할 수 있습니다


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

요즘에는 Apache Commons Lang의 StringUtils 지원이 있습니다 .

이것은 기본입니다.

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

문제에 대해 다음을 코딩 할 수 있습니다. StringUtils.ordinalIndexOf(uri, "/", 3)

lastOrdinalIndexOf 메서드를 사용하여 문자열에서 마지막 n 번째 문자를 찾을 수도 있습니다 .


또 다른 접근 방식 :

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

이 답변은 @aioobe의 답변을 향상시킵니다. 그 대답의 두 가지 버그가 수정되었습니다.
1. n = 0은 -1을 반환해야합니다.
2. n 번째 발생은 -1을 반환했지만 n-1 번째 발생에서 작동했습니다.

이 시도 !

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

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

String.split (..) 메서드를 통해서도이 작업을 수행 할 수 있습니다.

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

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

내 솔루션 :

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

코드는 필드 너비라고도하는 n 번째 발생 위치 하위 문자열을 반환합니다. 예. 문자열 "Stack overflow in low melow""low"토큰의 두 번째 발생 을 검색하는 문자열 인 경우 두 번째 발생이 "18 and 21" 서브 트링에 있음에 동의합니다 . indexOfOccurance ( "Stack overflow in low melow", low, 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));
    }
    }

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

참고 URL : https://stackoverflow.com/questions/3976616/how-to-find-nth-occurrence-of-character-in-a-string

반응형