我正在尝试解压缩如下所示的字符串:

输入:4(ab)

输出:abababab

输入:11ab

输出:aaaaaaaaaaab

输入:2(3b3(ab))

输出:bbbabababbbbabababbab

上面的示例全部使用下面的递归方法正确显示,但是当我输入类似内容时会出现问题:

输入:4(ab)a

预期产量:ababababa

输入:2(3b3(ab))a

预期产量:bbbabababbbbababaaba

我意识到在return语句“return repeat”中出现问题。在其当前状态下,递归继续进行,直到到达括号后也到达输入字符串的末尾。基本上,我不知道如何在到达结尾括号时弄坏它,然后在剩下任何东西的情况下继续下去。在2(3b3(ab))a中,它应该返回2 *(3b3(ab))+ a,现在它返回2 *(3b3(ab))a。非常感谢您的帮助,因为我无法理解。

public static String decompress(String compressedText) throws Exception
{
   //BASE CASE
    if(compressedText.length() == 1)
    {
        if(compressedText.charAt(0) == ')')
        {
            System.out.println("1: " + compressedText);
            return "";
        }
        else
        {
            System.out.println("2: " + compressedText);
            return compressedText;
        }

    }
    //END BASECASE


    if(compressedText.charAt(0) == '(')
    {
        System.out.println("3: " + compressedText);
        return decompress(compressedText.substring(1));
    }


    //IF DOUBLE DIGIT
    if(Character.isDigit(compressedText.charAt(0)) == true && Character.isDigit(compressedText.charAt(1)) == true)
    {
        if(compressedText.charAt(3) != '(')
        {
            System.out.println("4: " + compressedText);
            int i = Integer.parseInt(compressedText.substring(0,2));
            String repeated = new String(new char[i]).replace("\0", compressedText.substring(2,3));
            return repeated + decompress(compressedText.substring(3));
        }
        else
        {
            System.out.println("5: " + compressedText);
            int i = Integer.parseInt(compressedText.substring(0,2));
            String repeated = new String(new char[i]).replace("\0", decompress(compressedText.substring(2)));
            return repeated;
        }

    }
    //END DOUBLE DIGIT



    //IF SINGLE DIGIT
    if (Character.isDigit(compressedText.charAt(0)) == true)
    {
        if(compressedText.charAt(1) !='(')
        {
            System.out.println("6: " + compressedText);
            int i = Integer.parseInt(compressedText.substring(0,1));
            String repeated = new String(new char[i]).replace("\0", compressedText.substring(1,2));
            return repeated + decompress(compressedText.substring(2));
        }
        else
        {
            System.out.println("7: " + compressedText);
            int i = Integer.parseInt(compressedText.substring(0,1));
            String repeated = new String(new char[i]).replace("\0", decompress(compressedText.substring(1)));
            return repeated;
        }

    }
    //END SINGLE DIGIT

    //IF RIGHT PARENTHESIS
    if (compressedText.charAt(0) == ')')
    {
        if (compressedText.charAt(1) != ')')
        {
            System.out.println("8: " + compressedText);
            return "";
        }
        else
        {
            System.out.println("9: " + compressedText);
            return  decompress(compressedText.substring(1));

        }

    }
    //END

        System.out.println("10: " + compressedText);
        return compressedText.charAt(0)+decompress(compressedText.substring(1));

}

最佳答案

使用元组作为递归的返回值,该值除了提供累积的字符串外,还提供右括号的索引:

index 0 1 2 3 4 5 6 7 8 9 10
str   2 ( 3 b 3 ( a b ) ) a

  f(0)

  => 2 * f(1)[0] add f(f(1)[1] + 1)  // f(1)[1] is the closing index

    f(1) => 3 * b + 3 * f(5)[0] add f(f(5)[1] + 1)

    => f(5) returns (ab,8)

    f(1) => bbb + ababab add f(9) // str[9] is closing parenthesis

    => f(1) returns (bbbababab,9)

  => 2 * bbbababab add f(10)

  => bbbabababbbbabababa

JavaScript代码:

var example = '2(3b3(ab)2(cd3(fg)))ab2(gh2(xz))';

console.log(example);
console.log(decompress(example));

function decompress(s){

  // returns tuple [accumulator, index of closing parenthesis]
  function f(i){

    var accum = '',
        mult = '',
        curr = '';

    // accumulate all parenthetical groups in this level
    while (i !== s.length){

      // closing parenthesis
      if (s[i] === ')'){

        // add the last decompression
        if (curr !== ''){
          accum += customReplicate(curr,mult);
        }

        // exit this call
        return [accum,i];
      }

      // character is a digit
      if (!isNaN(parseInt(s[i]))){

        // add previous decompression
        if (curr !== ''){
          accum += customReplicate(curr,mult);

          curr = '';
          mult = s[i];

        } else {
          mult += s[i];
        }

        i++;

      // character is a character
      } else if (s[i] !== '('){

        curr += s[i];
        i++;

      // parenthetical group
      } else if (s[i] === '('){

        // recursive call
        [tempAccum,index] = f(i + 1);

        accum += customReplicate(tempAccum,mult);
        mult = '';
        i = index + 1;
      }
    }

    return accum + customReplicate(curr,mult);
  }

  // initialize the recursion
  return f(0);
}

function customReplicate(str,times){
  return new Array(times === '' ? 1 : parseInt(times))
                 .fill(str).join('');
}

10-05 18:09