2016-05-15 44 views
0

嵌套的ArrayList我有一個字符串爲:字符串轉換成Java中

String input = {{a,b,c}, 4,6, 7 , {c, d, {g,h, {} }}}; 

我需要「輸入」轉換成嵌套的ArrayList其中內內容的每個「{}」在單獨的列表中。請注意,在添加List中的每個元素之前,需要修剪輸入中的隨機空白。 因此,對於需要所需的輸出爲(在所描繪的toString輸出()用於表示法):

List<Object> output = [[a,b,c],4,6,7,[c,d,[g,h,[]]]] 

在這裏,每一個元素是一個列表項。所以

List<Object> emptyList = [] 
    List<Object> subList1 = [g,h,emptyList] 
    List<Object> subList2 = [c,d,subList1] 
    List<Object> subList3 = [a,b,c] 
    List<Object> parentList = [sublist3,4,6,7,sublist2] 

我只需要最後/父列表作爲'parentList'上面,中間結果可以被忽略。
有人可以幫助我一個整潔的算法來解決這個問題。我已經嘗試了幾個小時,但未能派生出適當的遞歸調用方法解決方案。然而,非遞歸方法解決方案也是最受歡迎的:)

我已經嘗試使用下面的代碼。雖然,這有點粗俗。

package com.psl.demo; 

    import java.util.ArrayList; 
    import java.util.Arrays; 
    import java.util.Collections; 
    import java.util.List; 

    public class ListClass { 

     public List<Object> converToList(String string){ 
      List<Object> list = new ArrayList<Object>(); 

      string = string.trim(); 
      StringBuilder sb = new StringBuilder(string); 

      List<Integer> startIndices= new ArrayList<Integer>(); 
      List<Integer> endIndices = new ArrayList<Integer>(); 

      int counter = 0; 
      while(counter < sb.length()){ 
       if(sb.charAt(counter) == '{'){ 
        startIndices.add(counter); 
        sb.setCharAt(counter, ' '); 
       } 
       counter++; 
      } 

      int reverseCounter = sb.length()-1; 
      while(reverseCounter > 0){ 
       if(sb.charAt(reverseCounter) == '}'){ 
        endIndices.add(reverseCounter); 
        sb.setCharAt(reverseCounter, ' '); 
       } 
       reverseCounter--; 
      } 

      if(startIndices.size() != endIndices.size()){ 
       System.out.println("Brackets do not match. exiting"); 
       System.exit(1); 
      } 


      int size = startIndices.size(); 
      counter = 0; 
      reverseCounter = size-1; 
      for(int i=0; i<size; i++){ 
       String contents =     sb.substring(startIndices.get(reverseCounter), endIndices.get(counter)); 
       //sb.replace(startIndices.get(reverseCounter),   endIndices.get(counter),""); 
       contents = contents.trim(); 
       List<Object> subList = new ArrayList<Object>(); 
       Object[] tokens = contents.split(","); 
       for(int j=0; j< tokens.length;j++){ 
        tokens[j] = tokens[j].toString().trim(); 
       } 
       subList = Arrays.asList(tokens); 
       list.add(subList); 
       counter++; 

       reverseCounter--; 
      } 

      Collections.reverse(list); 
      return list; 
     } 

     public static void main(String[] args) { 
      String string = "{{a ,b, {hello, world}}, 4 ,6, 7, { c , d }   }"; 
      ListClass obj = new ListClass(); 
      List<Object> list= obj.converToList(string); 
      System.out.println(list); 
     } 

    } 

請忽略System.exit()代碼部分。這將被替換爲正確的代碼。 由於我提到的特定需求,使用了對象類型列表。

+1

那麼你有什麼嘗試,什麼問題阻止你?您迭代字符串的字符,提取值並使用堆棧跟蹤當前正在構建的列表。不需要遞歸。 – Andreas

+0

有一個'List ' –

+0

不應該輸入給你一個編譯錯誤是一個壞主意。輸入不是'String' – Priyamal

回答

0

這可能是類似於DS表達式求值。所以我認爲你需要去與堆棧這種類型的問題的數據結構。嘗試使用以下代碼,它可能會解決您的問題。

package src.com; 
import java.util.ArrayDeque; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Deque; 
import java.util.List; 
public class Abc {  
    public static class Bean { 
     int token; 
     Object obj; 
     public Bean(){} 
     public Bean(int tocken, Object o) { 
      super(); 
      this.token = tocken; 
      this.obj = o; 
     } 
    } 
    public static void main(String[] args) { 
     String input = "{{a,b,c},4, 6,7,{d,e,{},{ }}}"; 
     input = input.replaceAll(" ", ""); 
     List<Object> list = getList(input); 
     System.out.println(list); 
    } 
    @SuppressWarnings("unchecked") 
    public static List<Object> getList(String input1) { 
     Deque<Object> stack = new ArrayDeque<Object>(); 
     char[] chararray = input1.toCharArray(); 
     String temp = ""; 
     for (int i = 0; i < chararray.length; i++) { 
      if (chararray[i] == '}') { 
       if (!temp.equals("")) { 
        stack.push(new Bean(0, temp)); 
        temp = ""; 
       } 
       List<Object> tmplist = new ArrayList<>(); 
       while (true) { 
        Object object = stack.pop(); 
        if (object instanceof Bean) { 
         Bean b = (Bean) object; 
         if (b.token == 1) 
          break; 
         tmplist.add(b.obj); 
        } else { 
         tmplist.add(object); 
         if (stack.isEmpty()) 
          break; 
        } 
       } 
       Collections.reverse(tmplist); 
       stack.push(tmplist); 
      } else { 
       if (chararray[i] == '{') { 
        stack.push(new Bean(1, Character.toString(chararray[i]))); 
       } else if (chararray[i] == ',') { 
        if (!temp.equals("")) { 
         stack.push(new Bean(0, temp)); 
         temp = ""; 
        } 
       } else { 
        temp = temp + Character.toString(chararray[i]); 
       } 
      } 
     } 
     return (List<Object>) stack.pop(); 
    } 
} 
0

你試圖做的事情看起來很像JSON反序列化。如果ab等進行了引號括起來,你可以使用Jackson

import com.fasterxml.jackson.databind.ObjectMapper; 
    // ... 
    ObjectMapper jsonMapper = new ObjectMapper(); 
    String content = "{{\"a\",\"b\",\"c\"}, 4,6, 7 , {\"c\", \"d\", {\"g\", \"h\", {} }}}"; 
    String contentWithBrackets = content.replace('{', '[').replace('}',']'); 
    List list = jsonMapper.readValue(contentWithBrackets, List.class); 
    System.out.println(list); // [[a, b, c], 4, 6, 7, [c, d, [g, h, []]]] 
+0

你提出了一個非常好的解決方案!非常感謝!但是,項目中不允許使用任何外部罐。如果是這樣,你的是最好的,簡潔明快的解決方案:) –