2016-06-08 3 views
3

Назначение состоит в распаковке строки. В частности, код должен работать для 3 образцов, как показано на рисунке. Input - OutputДекомпрессировать строку с большим количеством вложенных строк

Мой код здесь работает в первых двух образцах. Однако я не могу придумать третий образец. Вероятно, я не понял, вероятно, понятие рекурсии. Вы можете мне помочь?

import java.util.Scanner; 

public class Compression4 { 

public static void main(String[] args) 
{ 
    Scanner in = new Scanner(System.in); 
    String input=in.next(); 
    System.out.println(uncompress(input)); 

} 
public static boolean flag = true; 

public static String uncompress(String compressedText) 
{ 
    return uncompress(compressedText, "", ""); 
} 
public static String getMultiple(String x, int N) { 
    if (N == 0) return ""; 

    return ""+x+getMultiple(x,N-1); 
} 
public static String uncompress(String text, String count, String output) 
{ 
    if (text.equals("")) 
    { 
     return output; 
    } 
    if(text.charAt(0) == '(') 
    {  
     int FirstIndex = text.indexOf("(")+1; 
     String inner = text.substring(FirstIndex, text.lastIndexOf(")")); 
     //System.out.println(inner); 
     flag = false; 
     return uncompress (inner, count, output); 

    } 
    else if (Character.isLetter(text.charAt(0))) 
    { 
     //letter case - need to take the count we have accrued, parse it into an integer and add to output 
     if (flag==true) 
     { 
       //System.out.println(count);// * text.charAt(0); 

       String s = String.valueOf(text.charAt(0)); 
       output += getMultiple(s,Integer.parseInt(count));       
       count ="1"; 
     }   
     else 
     { 
      //System.out.println(count);// * text.charAt(0); 
      output += getMultiple(text,Integer.parseInt(count)); 
      //System.out.println("output: "+output); 
      count="0"; 
     } 

    } 

    else if(Character.isDigit(text.charAt(0))) 
    { 
     //digit case - need to add to the count but keep as a string because must be parsed later 
     if(flag) 
      count += (""+text.charAt(0)); 
     else 
     { 
      count = "0"; 
      count += (""+text.charAt(0)); 

     } 

    } 

    //parse the *remainder* of the string, one character at a time, so pass in the substring(1) 

    return uncompress(text.substring(1), count, output); 

     } 
} 
+0

Это хорошее задание! Но только у вас есть три образца? – Aris2World

+0

Я добавлю еще несколько инструкций –

+0

Как можно понять из этих примеров, мы предполагаем, что число 11 в строке 11ab указывает, что следующий символ a повторяется 11 раз. Если мы хотим, чтобы более длинный шаблон повторялся, используйте круглые скобки: номер 4 в строке4 (ab) указывает, что подстрока ab повторяется 4 раза. Все несжатые строки состоят только из двух символов a и b. Хотя сжатые строки также могут содержать числа и круглые скобки, как в приведенных выше примерах. –

ответ

1

Извините за длинный код, но его легче объяснить с помощью кода, чем со словами.

Предпосылка:

  • Я думаю, что к этой проблеме в качестве переводчика языка, чтобы визуализировать строку
  • язык является простым и функциональным, так рекурсивная интерпретация возможна

Алгоритм фазы:

  • Во-первых: tokenize выражение (для работы на более высоком уровне abstr действие)
  • Во-вторых: разобрать выражение только лексемы

Рекурсия: логика основана на синтаксисе языка. Основные концепции рекурсии:

  • базовых случаи и рекурсивные случаи
  • состояния необходимо одной рекурсии (локальная переменные рекурсии, те, передается в качестве параметров к рекурсивному методу)
  • состояния для все рекурсии (глобальные переменные рекурсии, те, которые читаются/записываются в некоторой конкретной рекурсии)

Я сделал много комментариев, чтобы объяснить, что делает алгоритм. Если это не ясно, я могу объяснить это лучше.

import java.util.ArrayList; 
import java.util.List; 

public class TestStringDecompression { 

    // simpleExpr examples: a | b | 123a | 123b | 123(a) | 123(ab) | 123(ba) | (ab) | (ba) 
    // 11ab = aaaaaaaaaaab = = expression = simpleExpr simpleExpr = 11a b 
    // 4(ab) = abababab = expression = simpleExpr = 4(ab) 
    // 2(3b3(ab)) = bbbabababbbbababab = expression = compositeExpr = 2 (simpleExpr simpleExpr) = 2 (3b 3(ab)) 

    public static void main(String[] args) { 
     System.out.println(new StringInflater().inflate("11ab")); 
     System.out.println(new StringInflater().inflate("4(ab)")); 
     System.out.println(new StringInflater().inflate("2(3b3(ab))")); 
    } 

    public static class StringInflater { 

     // This store the position of the last parsed token 
     private int posLastParsedToken = 0; 

     public String inflate(String expression) { 
      return parse(tokenize(expression), 0, false); 
     } 

     /** 
     * Language tokens: 
     * <ul> 
     * <li>literals: 
     * <ul> 
     * <li>intLiteral = [0-9]*</li> 
     * <li>charLiteral = [ab]</li> 
     * </ul> 
     * </li> 
     * <li>separators: 
     * <ul> 
     * <li>leftParen = '('</li> 
     * <li>rightParen = ')'</li> 
     * </ul> 
     * </li> 
     * </ul> 
     */ 
     private Object[] tokenize(String expression) { 
      List<Object> tokens = new ArrayList<Object>(); 
      int i = 0; 
      while (i < expression.length()) { 
       if ('0' <= expression.charAt(i) && expression.charAt(i) <= '9') { 
        String number = ""; 
        while ('0' <= expression.charAt(i) && expression.charAt(i) <= '9' && i < expression.length()) { 
         number += expression.charAt(i++); 
        } 
        tokens.add(Integer.valueOf(number)); 
       } else { 
        tokens.add(expression.charAt(i++)); 
       } 
      } 
      return tokens.toArray(new Object[tokens.size()]); 
     } 

     /** 
     * Language syntax: 
     * <ul> 
     * <li>simpleExpr = [intLiteral] charLiteral | [intLiteral] leftParen charLiteral+ rightParen</li> 
     * <li>compositeExpr = [intLiteral] leftParen (simpleExpr | compositeExpr)+ rightParen</li> 
     * <li>expression = (simpleExpr | compositeExpr)+</li> 
     * </ul> 
     */ 
     private String parse(Object[] tokens, int pos, boolean nested) { 
      posLastParsedToken = pos; 
      String result = ""; 
      if (tokens[pos] instanceof Integer) { 
       /** it's a intLiteral */ 
       // get quantifier value 
       int repetition = (int) tokens[pos]; 
       // lookahead for (
       if (tokens[pos + 1].equals("(")) { 
        // composite repetition, it could be: 
        // simpleExpr: "[intLiteral] leftParen charLiteral+ rightParen" 
        // compositeExpr: "[intLiteral] leftParen (simpleExpr | compositeExpr)+ rightParen" 
        result = parse(tokens, pos + 1, true); 
       } else { 
        // simple repetition, it could be: 
        // simpleExpr: [intLiteral] charLiteral 
        result = parse(tokens, pos + 1, false); 
       } 
       result = repeat(result, repetition); 
       // evaluate the rest of the expression because syntax allows it 
       if (posLastParsedToken + 1 == tokens.length) { 
        // end of the expression 
        return result; 
       } else { 
        // there are other simpleExpr or compositeExpr to parse 
        return result + parse(tokens, posLastParsedToken + 1, false); 
       } 
      } else if (tokens[pos].equals('(')) { 
       /** it's a leftParen */ 
       // an open paren means what follow this token is considered nested (useful for string to treat as char sequence) 
       return parse(tokens, pos + 1, true); 
      } else if (tokens[pos].equals(')')) { 
       /** it's a rightParen */ 
       // a closed paren, nothing to render 
       return ""; 
      } else { 
       /** it's a charLiteral */ 
       if (nested) { 
        // it's nested between paren, so more parsing is requested to consume next charLiteral or next simpleExpr or compositeExpr 
        return tokens[pos] + parse(tokens, pos + 1, nested); 
       } else { 
        // it's not nested between paren, return charLiteral as is 
        return "" + tokens[pos]; 
       } 
      } 
     } 

     private String repeat(String s, int repetition) { 
      StringBuilder result = new StringBuilder(); 
      for (int i = 0; i < repetition; i++) { 
       result.append(s); 
      } 
      return result.toString(); 
     } 

    } 

} 
Смежные вопросы