前言
自定义计算器算法实现,完成表达式计算背后的原理算法。
一、例题
三体星人计算器。
题目描述:三体星人的计算器与地球人的计算器规则类似,为十进制,仅支持正整数,不支持括号,计算处理为从右到左进行计算,仅支持加、减、乘、取余操作,并且操作优先级顺次递减。
输入:比如输入为:4+2%5-7*11,则计算从右向左进行,按操作优先级,先算5-7,变成4+2%2*11,再算2*11,变成4+2%22,再算4+2,变成6%22,最终为4。
输出:4
时间限制:无限制。
样例:输入:4+2%5-7*11,输出4。
二、题解
package com.xhu.other;
import java.util.*;
/**
* 火星计算器
*/
public class SepComputing {
public static void main(String[] args) {
String[] els = {"4", "+", "2", "%", "5", "-", "7", "*", "11"};
System.out.println(new SepComputing().computing(els));
Deque<Integer> d= new ArrayDeque<>();
d.add(1);
d.add(2);
System.out.println(d.peekLast());
}
public int computing(String[] els) {
//存数据的栈
Deque<Integer> data = new ArrayDeque<>();
//存符号优先级的优先级
Deque<Character> symbols = new ArrayDeque<>();
//规则为从右向左计算
for (int i = els.length - 1; i >= 0; i--) {
if (isDigit(els[i])) {
data.push(Integer.parseInt(els[i]));
continue;
}
//不是数字
if (symbols.isEmpty() || priority(els[i].charAt(0), symbols.peekFirst())) {
symbols.offerFirst(els[i].charAt(0));
continue;
}
//计算加减乘
char ch = els[i].charAt(0);
while (!symbols.isEmpty() && !priority(ch, symbols.peekFirst())) {
int leftData = data.pollFirst(), rightData = data.pollFirst();
int result = compute(rightData, leftData, symbols.pollFirst());
data.push(result);
}
symbols.push(ch);
}
//最后计算栈内元素
while (!symbols.isEmpty()) {
int leftData = data.pollFirst(), rightData = data.pollFirst();
data.push(compute(rightData, leftData, symbols.pollFirst()));
}
return data.poll();
}
//根据符号计算结果
private int compute(int data1, int data2, char ch) {
if (ch == '+')
return data1 + data2;
if (ch == '-')
return Math.abs(data1 - data2);
if (ch == '%')
return data1 % data2;
return data1 * data2;
}
//符号优先级(根据加减乘除和取余的优先级去设定规则,这里的规则为取余为低优先级,其它优先级相等)
private boolean priority(char ch1, char ch2) {
//大于等于为true
if (ch2 == '%')
return true;
if (ch1 == '%')
return false;
return true;
}
//是否为数字
private boolean isDigit(String s) {
//也可for循环去判断里面的字符是否在0-9中。要看是否有+-号。
try {
Integer.parseInt(s);
return true;
} catch (Exception e) {
return false;
}
}
}
总结
1)掌握双栈思想。