Java 面试测试:实现一个解码算法
我在亚马逊的采访中遇到了这个问题 给定一个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 <
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;
}
}
}