2013-10-08 3 views
1

다음 알고리즘을 적용하려고합니다. 내가 원하는 것은 주어진 문자열을 일련의 숫자 또는 연산자로 구성된 부분 문자열로 나눕니다.Java에서 문자열 알고리즘 나누기

이 문자열은 "22 + 2"이므로 [0] = "22"[1] = "+"및 [2] = "2"인 배열을 얻을 수 있습니다.

내가 지금까지 가지고있는,하지만 난 경계 예외에서 인덱스를 얻을 : 나는 오히려 대안을 제공 할 것보다 내 추론 뭐가 잘못 말한 것

public static void main(String[] args) { 
    String string = "114+034556-2"; 
    int k,a,j; 
    k=0;a=0;j=0; 
    String[] subStrings= new String[string.length()]; 

    while(k<string.length()){ 
     a=k; 
     while(((int)string.charAt(k))<=57&&((int)string.charAt(k))>=48){ 
      k++;} 
     subStrings[j]=String.valueOf(string.subSequence(a,k-1)); //exception here 

     j++; 
     subStrings[j]=String.valueOf(string.charAt(k)); 
     j++; 

    }} 

, 그러나 물론 나는 것 어떤 종류의 도움에 감사드립니다.

String[] operands = string.split("\\D");\\split around anything that is NOT a number 
char[] operators = string.replaceAll("\\d", "").toCharArray();\\replace all numbers with "" and turn into char array. 
+0

'+'뿐 아니라 모든 연산자에서 작동하기를 원하십니까? –

+0

예, 지금은 crtieria "숫자가 아닌 것은"괜찮을 것입니다. –

+0

이 특정 알고리즘이나 숫자와 연산자를 파싱하는 일반적인 문제에 관심이 있으십니까? 즉, 다른 알고리즘에 관심이 있습니까? – rcreswick

답변

0

은 "숫자가 아닌 것은"는, 당신은 몇 가지 간단한 정규식 물건을 사용할 수 있습니다 당신이 솔루션을 직접 파악하려는 것처럼 보이기 때문에 lookahead and lookbehind assertions

String equation = "22+2"; 
String[] tmp = equation.split("(?=[+\\-/])|(?<=[+\\-/])"); 
System.out.println(Arrays.toString(tmp)); 
+0

슬래시를 벗어나야합니다. 또한 Character # isDigit는 더 직관적 인 것처럼 보입니다. – Aurand

+0

@Aurand 고마워, 난 항상 탈출을 두 번 잊지. –

1

당신은 분할 정규 표현식을 사용할 수 있습니다 - 당신의 critera 단지의 경우 병렬 배열을 사용하기 마음을 해달라고하면

2

을 사용하여 사업자 수는 일부러 직접이 질문에 대답하고 있지 않다. 또한 의도적으로 split 또는 indexOf 함수를 사용하지 않는다고 가정합니다.이 함수는 매우 사소한 것입니다. 내가 눈치 챘을

몇 가지 :

  1. 하여 입력 문자열이 긴 경우, 당신은 아마 당신이 불변의 문자열에서 발생하는 메모리 문제를 방지 할 수 있도록, char 배열과 StringBuilder의 작업을 더 나을 것
  2. 예외를 잡으려고 시도했거나 인덱스의 범위를 벗어나는 원인이되는 k 값을 인쇄 해 보았습니까?
  3. 문자열이 종료되면 어떻게되는지 생각해 보셨습니까? 예를 들어, 입력 문자열이 "454"또는 이와 비슷하게 사소한 경우 디버거를 통해이 코드를 실행 했습니까?
+1

나는 내가 "멍청하기 때문에 더 쉽게 사용하지 않는다"고 말하지는 않을 것이며, 이것을하기위한 더 쉬운 방법이 있다는 것을 몰랐다.하지만이 특별한 해결책이 왜 아닌지 알아 내고 싶다. 일. 색인 인쇄와 관련하여 귀하의 의견을 듣고 지금 무슨 일이 일어 났는지 생각합니다. 당신이 말했듯이, 그것이 끝나고 인덱스는 내가 설정 한 기준 때문에 계속 될 때해야합니다. 아직 해결 방법을 알려 드리고 있지만 입력 해 주셔서 감사드립니다. –

0
String input="22+2-3*212/21+23"; 
    String number=""; 
    String op=""; 
    List<String> numbers=new ArrayList<String>(); 
    List<String> operators=new ArrayList<String>(); 
    for(int i=0;i<input.length();i++){ 
     char c=input.charAt(i); 
     if(i==input.length()-1){ 
      number+=String.valueOf(c); 
      numbers.add(number); 
     }else if(Character.isDigit(c)){ 
      number+=String.valueOf(c); 
     }else{ 
       if(c=='+' || c=='-' || c=='*' ||c=='/'){ 
      op=String.valueOf(c); 
      operators.add(op); 
      numbers.add(number); 
      op=""; 
      number=""; 
      } 
     } 
    } 
    for(String x:numbers){ 
     System.out.println("number="+x+","); 
    } 
    for(String x:operators){ 
     System.out.println("operators="+x+","); 
    } 

이 출력 될 것이다 수 = 22, 번호 = 2, 번호 = 3, 개수 = 212, 번호 = 21, 번호 = 23 연산자 = + 운영자 = - 운영자 = * , operator = /, operator = +,

+0

아니요. 'c'가 문자 인 경우 '+', '-'등이 될 수 없습니다. – Aurand

+0

@Aurand 감사합니다. 편집 됨. – budaancamanyak

+0

이것은 제대로 작동하며, 내가 잘못하고있는 것에 대한 통찰력을 제공합니다. 고맙습니다. –

0

구문 분석의 일반적인 문제에 관심이 있다면 문자 단위로 생각하고 유한 상태 기계를 통해 이동하는 것이 좋습니다. 각각의 새로운 캐릭터. (종종 C 문자열의 \ 0과 같은 입력에서 발생할 수없는 터미네이터 문자가 필요하지만 그 주위를 감당할 수 있습니다.) 이 경우

, 당신은 다음과 같은 상태를 가질 수 있습니다
  1. 초기 상태
  2. 그냥 숫자를 구문 분석.
  3. 그냥 연산자를 구문 분석했습니다.

문자는 상태에서 상태로 전환을 결정 :

  • 당신은 상태 1에서 시작합니다.상태 3.

현재 상태로 상태 2

  • 운영자로 전이
  • 번호 변환은 각 캐릭터가 소비 된 후 상태를 변화 enum과 같은 추적 될 수있다.

    이 설정을 사용하면 입력 문자열을 반복하고 현재 상태를 켜기 만하면됩니다. 그런 구조로

    // this is pseudocode -- does not compile. 
    List<String> parse(String inputString) { 
        State state = INIT_STATE; 
        String curr = ""; 
        List<String> subStrs = new ArrayList<String>(); 
        for(Char c : inputString) { 
         State next; 
         if (isAnumber(c)) { 
         next = JUST_NUM; 
         } else { 
         next = JUST_OP; 
         } 
    
         if (state == next) { 
         // no state change, just add to accumulator: 
         acc = acc + c; 
         } else { 
         // state change, so save and reset the accumulator: 
         subStrs.add(acc); 
         acc = ""; 
         } 
         // update the state 
         state = next; 
        } 
        return subStrs; 
    } 
    

    , 당신은 더 쉽게 새로운 상태를 추가하고 현재 상태 및 수신 특성에 따라 동작을 업데이트하여 새로운 기능/구조를 추가 할 수 있습니다. 예를 들어 문자열에 문자가 표시되면 오류를 던지기위한 검사를 추가 할 수 있습니다 (추적하려는 경우 오프셋 위치 포함).