簡體   English   中英

在Java中拆分字符串算法

[英]Splitting string algorithm in 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++;

   }}

我寧願被告知我的推理有什么問題而不是提供替代方案,但我當然會感激任何幫助。

我故意不直接回答這個問題,因為看起來你正在試圖找出一個解決方案。 我還假設你故意不使用split或indexOf函數,這將使這非常簡單。

我注意到的一些事情:

  1. 如果輸入字符串很長,那么使用char數組和stringbuilder可能會更好,這樣可以避免因不可變字符串引起的內存問題
  2. 您是否嘗試捕獲異常,或打印出k的值導致索引超出范圍的問題?
  3. 你有沒有想過當你的字符串終止時會發生什么? 例如,當輸入字符串為“454”或類似的微不足道時,您是否通過調試器運行此操作?

您可以使用正則表達式使用lookahead和lookbehind斷言從運算符中分割數字

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

如果你的critera只是“任何不是數字的東西”,那么你可以使用一些簡單的正則表達式,如果你不介意使用並行數組 -

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.
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,運算符= +,運算符= - ,運算符= *,運算符= /,運算符= +,

如果你對解析的一般問題感興趣,那么我建議在逐個字符級別上思考它,並在每個新角色的有限狀態機中移動。 (通常你需要一個不能在輸入中出現的終結符 - 比如C字符串中的\\ 0 - 但我們可以繞過它。)。

在這種情況下,您可能具有以下狀態:

  1. 初始狀態
  2. 只是解析了一個數字。
  3. 剛剛解析了一個運算符。

字符決定了從州到州的轉換:

  • 你從州1開始。
  • 數字轉換為狀態2。
  • 運營商過渡到州3。

可以使用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;
}

使用這樣的結構,您可以通過添加新狀態並根據當前狀態和傳入字符更新行為,更輕松地添加新功能/構造。 例如,如果字母出現在字符串中,您可以添加一個檢查來拋出錯誤(如果您想跟蹤它,則包括偏移位置)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM