我环顾四周寻找一种解决方案来解析包含可能具有自己后缀的分子成分的化学式,以便能够解析其完整原子分数的公式。
在 Java 中如何做到这一点?
由于无法在短时间内找到一种方法(并且有一段时间没有完成有趣的算法),我选择了堆栈实现,因为它实际上没有数学运算堆栈复杂。
回顾堆栈,您只需要了解一些事情,因为这从根本上是解析数学语句的通用解决方案的修改实现。
1)您的整数后缀可以由多个字符组成
2)您的整数后缀可以是一个乘数(下一个字符是“)”)
3)您需要处理隐含的“1”
该实现将字符从一个堆栈中弹出并仅将字母和数字推入您的“返回堆栈”。
String expandFormula(String s){
Stack<Character> stack = new Stack();
Stack<Character> hanoi = new Stack();
char[] ca = s.toCharArray();
Character c;
List<Integer> multipliers = new ArrayList();
String multiBuff;
int val;
boolean flag;
for (int i = 0; i < ca.length; i++)
stack.push(ca[i]);
while(!stack.isEmpty()){
c = stack.pop();
if (Character.isLetter(c)){
try{
//previous parse was end of Symbol, implicit "1"
flag = Character.isUpperCase(hanoi.peek());
}
catch(EmptyStackException ese){ //change exception
flag = false;
}
//push implicit 1
if (flag){
stack.push(c);
stack.push('1');
}
//continue as usual
else
hanoi.push(c);
}
//begin number parsing
else if(Character.isDigit(c)){
flag = false;
multiBuff = c +"";
//parse the integer out
while(Character.isDigit(stack.peek())){
c = stack.pop();
multiBuff = c + multiBuff;
}
//if next char is ), then value is a suffix
if (stack.peek() == ')'){
flag = true;
stack.pop();
multipliers.add(Integer.parseInt(multiBuff));
//pop successive )s
while(stack.peek() == ')'){
stack.pop();
multipliers.add(1);
}
}
if(Character.isLetter(stack.peek())){
val = flag ? 0 : Integer.parseInt(multiBuff);
//get full value of
for(Integer i : multipliers){
if (val == 0)
val = i;
else
val *= i;
}
//trim and push first decibit
while(val > 0){
hanoi.push(Character.forDigit(val % 10, 10));
val /= 10;
}
}
}
//end of nest, remove most recent multiplier
else if(c == '(')
try{
multipliers.remove(multipliers.size()-1);
}
catch(ArrayIndexOutOfBoundsException aioobe){
}
}
multiBuff = "";
while(!hanoi.isEmpty())
multiBuff += hanoi.pop();
return multibuff;
}
此解决方案可以通过以下方式直接转换为您的输出字符串:
1) 将 "hanoi" 更改为字符串
2) 将 "hanoi.push(c)" 更改为 hanoi = c + hanoi
3) 将 "hanoi.peek()" 更改为 "hanoi.charAt(0)"
4) 根据需要更改例外(或无论如何使用一般例外)
5)只需返回 hanoi 而不是底部的 multibuff 东西。