Java 面试测试:实现一个解码算法

Java 面试测试:实现一个解码算法,java,algorithm,data-structures,decoding,string-parsing,Java,Algorithm,Data Structures,Decoding,String Parsing,我在亚马逊的采访中遇到了这个问题 给定一个Java字符串作为输入3[a]2[bc]编写一个函数对其进行解码,因此输出应为“**aaabcbc**” 我尝试过以下方法,但不正确,因为它不处理嵌套元素 String test = "3[a]2[b]5[b]"; Map<Character, Integer> map = new HashMap<>(); char[] characters = test.toCharArray(); for (int i = 0; i <

我在亚马逊的采访中遇到了这个问题

给定一个Java字符串作为输入
3[a]2[bc]
编写一个函数对其进行解码,因此输出应为“
**aaabcbc**

我尝试过以下方法,但不正确,因为它不处理嵌套元素

String test = "3[a]2[b]5[b]";
Map<Character, Integer> map = new HashMap<>();

char[] characters = test.toCharArray();
for (int i = 0; i < characters.length-1; i++) {
    if(characters[i]=='['){
        if(map.containsKey(characters[i+1])){
            int count = map.get(characters[i+1]);
            map.put(characters[i+1], Character.getNumericValue(characters[i-1])+count);
        }else{
            map.put(characters[i+1], Character.getNumericValue(characters[i-1]));
        }

    }
 }
 for (Map.Entry<Character, Integer> c : map.entrySet()) {
    for (int i = 0; i < c.getValue(); i++) {
        System.out.printf("%s",c.getKey());
    }
}   
String test=“3[a]2[b]5[b]”;
Map Map=newhashmap();
char[]characters=test.toCharArray();
for(int i=0;i
正确的解决方案是什么

是否可以使用封装类来解码这个问题,如果您仔细观察问题的格式,我们可以将其转换为解码器类的对象。 2[…]3[…]4[…]

类解码器{
private int count;//数字示例2[a]3[bc]4[d]计数值为2,3,4
私有字符串数据;//示例a、bc、d
私有解码器;//对于嵌套值,示例3[2[a]]在这种情况下,解码器将为2[a]

}

当问题存在歧义时所做的假设:

对于第二种情况,3[2[a]-->3[aa]-->aaaaaa

对于第三种情况,如果整数在方括号内,则用户将 通常提供输入和解码

对于第四种情况,若整数在方括号外,则从输出中删除该字符串

你能试试这个代码吗?我在评论中问了一些问题,请澄清一下

import java.util.Random;
import java.util.Scanner;


public class MyClass {
    private static String code = "3[a]2[bc]";

    private static class Pair {
        int s = 0;
        int e = 0;
    }


    private static Pair getPair() {
        char[] chars = code.toCharArray();
        Pair pair = new MyClass.Pair();
        int pointer = 0;
        for (char c : chars) {
            if (c == '[') {
                pair.s = pointer;
            }
            if (c == ']') {
                pair.e = pointer;
                break;
            }
            pointer = pointer + 1;
        }
        if (pair.e > (pair.s + 1) ||  pair.s !=0) {
            return pair;
        }else{
            return null;
        }

    }

    private static boolean parseInteger(String s)
    {
        try {
            Integer.parseInt(s);
            return true;
        } catch(NumberFormatException e) {
            return false;
        }
    }

    private static void decode(Pair pair){
        String pattern = code.substring(pair.s+1, pair.e);
        String patternCount = code.substring(pair.s-1, pair.s);
        if(!parseInteger(patternCount)) {
            code = code.replace(code.substring(pair.s-1, pair.e+1) , "");
        }else if(parseInteger(pattern)){
            Scanner scanner = new Scanner(System.in);
            System.out.println("Enter Code for : "+code.substring(pair.s-1, pair.e+1)  );
            String replacement  = "";
            pattern = scanner.nextLine();
            for(int i  =  0 ; i < Integer.parseInt(patternCount);i++){
                replacement =  replacement + pattern;
            }
            code = code.replace(code.substring(pair.s-1, pair.e+1) , replacement);
        }else{
            String replacement = "";
            for(int i  =  0 ; i < Integer.parseInt(patternCount);i++){
                replacement =  replacement + pattern;
            }
            code = code.replace(code.substring(pair.s-1, pair.e+1) , replacement);
        }
    }

    public static void main(String[] args) {
        boolean  decoding  =  false;
        do{
            Pair  pair = getPair();
            decoding = pair != null ? true : false;
            if(decoding){
                decode(pair);
            }

        }while(decoding);

        System.out.println(code);
    }
}
import java.util.Random;
导入java.util.Scanner;
公共类MyClass{
私有静态字符串code=“3[a]2[bc]”;
私有静态类对{
int s=0;
int e=0;
}
私有静态对getPair(){
char[]chars=code.toCharArray();
Pair Pair=新的MyClass.Pair();
int指针=0;
for(char c:chars){
如果(c=='['){
pair.s=指针;
}
如果(c==']'){
e=指针;
打破
}
指针=指针+1;
}
if(pair.e>(pair.s+1)| | pair.s!=0){
返回对;
}否则{
返回null;
}
}
私有静态布尔整数(字符串s)
{
试一试{
整数.parseInt(s);
返回true;
}捕获(数字格式){
返回false;
}
}
专用静态无效解码(成对){
字符串模式=代码子字符串(对.s+1,对.e);
String patternCount=code.substring(pair.s-1,pair.s);
如果(!parseInteger(patternCount)){
代码=代码.替换(代码.子字符串(对.s-1,对.e+1),“”);
}else if(解析整数(模式)){
扫描仪=新的扫描仪(System.in);
System.out.println(“输入代码:”+Code.substring(pair.s-1,pair.e+1));
字符串替换=”;
pattern=scanner.nextLine();
for(int i=0;i
将嵌套表达式如
2[2[a]3[b]
缩减为
aabbbaabbbb
可以通过最内层的redux(=可缩减表达式)来完成

因此,继续替换不需要的形式
数字[字母]
,直到不能再减少

因为这似乎只是一个草图:

String expression = "...";
for (;;) {
    boolean reduced = false;
    for (int i = 0; i < expression.length(); ++i) {
        if (found reducable expression) {
            reduced = true;
            expression = reduced expression;
            break; // Otherwise we would need to correct i.
        }
    }
    if (!reduced) {
        break;
    }
}

正如在评论中所讨论的,基于堆栈的解决方案更优越,尽管我发现它需要更多的工作。

可以更干净一些,但似乎可以解决所提到的问题
更新我更新了代码,以解决@JimMichel指出的问题 这将考虑数字的多个数字,并且不接受格式错误的输入

public static String decode(String in) {      
    Deque<Character> stack = new ArrayDeque<Character>();
    Deque<Integer> occurencesStack = new ArrayDeque<Integer>();
    StringBuilder result = new StringBuilder();
    int brackets = 0;
    for(int i = 0; i < in.length(); ++i) {
        Character ch = in.charAt(i);
        if(ch == '[') {
            ++brackets;
            continue;
        }
        else if(ch == ']') {
            --brackets;
            StringBuilder temp = new StringBuilder();               
            while(!stack.isEmpty()) {
                Character top = stack.pop();
                temp.append(top);               
            }
            int times = occurencesStack.pop();
            if(temp.length() == 0) {
                temp = new StringBuilder(result);
                result.setLength(0);
                for(int j = 0; j < times; ++j) {
                    result.append(temp);
                }                   
            }
            else {
                temp.reverse();
                for(int j = 0; j < times; ++j) {
                    result.append(temp);
                }
                temp.setLength(0);              
            }
        }
        else if(Character.isDigit(ch)) {                
            StringBuilder nb = new StringBuilder();
            nb.append(ch);
            while(i < in.length() - 1 && Character.isDigit(in.charAt(i + 1))) {
                nb.append(in.charAt(i + 1));
                ++i;                    
            }
            if(i < in.length() - 1 && in.charAt(i + 1) == ']') {
                throw new IllegalArgumentException("Invalid sequence");
            }
            occurencesStack.push(Integer.parseInt(nb.toString()));
        }
        else if(ch >= 'a' && ch <= 'z') {   
            if(i < in.length() - 1 && in.charAt(i + 1) == '[') {
                throw new IllegalArgumentException("Invalid sequence");
            }
            stack.push(ch);

        }
        else {
            throw new IllegalArgumentException("Invalid character in sequence "+ch);
        }           
    }

    if(brackets != 0) {
        throw new IllegalArgumentException("Unmatched brackets!");
    }

  return result.toString();  

}    
公共静态字符串解码(字符串输入){
Deque stack=new ArrayDeque();
Deque occurrencesstack=new ArrayDeque();
StringBuilder结果=新建StringBuilder();
int括号=0;
对于(int i=0;iString expression = "...";
Pattern reduxPattern = Pattern.compile("(\\d+)\\[(\\pL*)\\]");
boolean reducing;
do {
    Matcher m = reduxPattern.matcher(expression);
    reducing = false;
    StringBuffer sb = new StringBuffer();
    while (m.find()) {
        reducing = true;
        int n = Integer.parseInt(m.group(1));
        String letters = m.group(2);
        String repetition = String.join("", Collections.nCopies(n, letters));
        sb.appendReplacement(repetition);
    }
    m.appendTail(sb);
    expression = sb.toString();
} while (reducing);
public static String decode(String in) {      
    Deque<Character> stack = new ArrayDeque<Character>();
    Deque<Integer> occurencesStack = new ArrayDeque<Integer>();
    StringBuilder result = new StringBuilder();
    int brackets = 0;
    for(int i = 0; i < in.length(); ++i) {
        Character ch = in.charAt(i);
        if(ch == '[') {
            ++brackets;
            continue;
        }
        else if(ch == ']') {
            --brackets;
            StringBuilder temp = new StringBuilder();               
            while(!stack.isEmpty()) {
                Character top = stack.pop();
                temp.append(top);               
            }
            int times = occurencesStack.pop();
            if(temp.length() == 0) {
                temp = new StringBuilder(result);
                result.setLength(0);
                for(int j = 0; j < times; ++j) {
                    result.append(temp);
                }                   
            }
            else {
                temp.reverse();
                for(int j = 0; j < times; ++j) {
                    result.append(temp);
                }
                temp.setLength(0);              
            }
        }
        else if(Character.isDigit(ch)) {                
            StringBuilder nb = new StringBuilder();
            nb.append(ch);
            while(i < in.length() - 1 && Character.isDigit(in.charAt(i + 1))) {
                nb.append(in.charAt(i + 1));
                ++i;                    
            }
            if(i < in.length() - 1 && in.charAt(i + 1) == ']') {
                throw new IllegalArgumentException("Invalid sequence");
            }
            occurencesStack.push(Integer.parseInt(nb.toString()));
        }
        else if(ch >= 'a' && ch <= 'z') {   
            if(i < in.length() - 1 && in.charAt(i + 1) == '[') {
                throw new IllegalArgumentException("Invalid sequence");
            }
            stack.push(ch);

        }
        else {
            throw new IllegalArgumentException("Invalid character in sequence "+ch);
        }           
    }

    if(brackets != 0) {
        throw new IllegalArgumentException("Unmatched brackets!");
    }

  return result.toString();  

}    
if (token is an operand)
    push token onto stack
else
    pop operand2
    pop operand1
    result = operand1 <operator> operand2
    push result onto stack
private static void decode(String value) {
    int startBracket=0;
    int endBracket=0;
    int encodedCount=0;
    int startIndex=0;
    String result="";
    StringBuilder temp=new StringBuilder();
    char[] data = value.toCharArray();
    for (int i = 0; i < data.length; i++) {
        if(data[i]=='['){
            if(encodedCount==0){
                encodedCount=Character.getNumericValue(data[i-1]);
                startIndex=i;
            }

            startBracket++;
            continue;
        }
        if(data[i]==']'){
            endBracket++;
        }
        if(startBracket==endBracket && startBracket!=0 && endBracket !=0){
            System.out.println(encodedCount);
            result=value.substring(0,startIndex-1);             
            String expandedTarget=value.substring(startIndex+1,i);
            String remainingEncodedValue = value.substring(i+1,value.length());
            System.out.println(expandedTarget);
            System.out.println(remainingEncodedValue);

            for (int j = 1; j <= encodedCount; j++) {
                temp.append(expandedTarget);
            }
            if(remainingEncodedValue.length()>1)
                temp.append(remainingEncodedValue);

            System.out.println("Decoded Result : "+result + temp.toString());
            decode(result + temp.toString());
            break;
        }
    }

}