问题说明:
给定一个字符串,例如:
String gsstring = "3565767 + 276756 * 76764 - 76 / 2 + 1";
如何将其当作数字运算,即相当于:
int gsint = 3565767 + 276756 * 76764 - 76 / 2 + 1;
我们如何来解析这样一个简单的公式(当前没有括号参与操作 )。
第一步:将此字符串变换为字节数组,将问题转换为针对字节数组的处理。
byte[] b = gsstring.getBytes();
第二步:编写工具方法。
1、判定一个字节是否为数字。
final public static boolean isdig(byte ch) {
return ch >= '0' && ch <= '9';
}
2、将所有的数字字节整理为一个真实的数字。
final public static int dig(byte[] b) {
int record = 0;
for (int i = 0; i < b.length; i++) {
record = record * 10 + (b[i] - '0');
}
return record;
}
3、将字节表示的符号转换为真正的运算操作。
final public static int calc(int record1, int record2, byte oper) {
int record = 0;
switch (oper) {
case '+':
record = record1 + record2;
break;
case '-':
record = record1 - record2;
break;
case '*':
record = record1 * record2;
break;
case '/':
record = record1 / record2;
break;
default:
break;
}
return record;
}
第三步:解析字节数组,将其记录为一个数字的集合以及一个符号的集合。
final public static Vector parse(byte[] b) {
Vector v = new Vector();
Vector dig = new Vector();
Vector sgn = new Vector();
byte[] bb = null;
int size, j, k;
for (int i = 0; i < b.length; i++) {
size = 0;
if (isdig(b[i])) {
j = i;
do {
size++;
j++;
} while (j < b.length && isdig(b[j]));
bb = new byte[size];
j = i;
k = 0;
do {
bb[k] = b[j];
k++;
j++;
} while (j < b.length && isdig(b[j]));
i = i + size - 1;
dig.add(new Integer(dig(bb)));
} else {
sgn.add(Byte.valueOf(b[i]));
}
}
v.add(sgn);
v.add(dig);
return v;
}
第四步:操作得到的结果。
提供思路:这种公式的特点是数字集合总是比符号集合多1,并且都是按照顺序存储的(现在采取的方案是这样)。所以,根据先乘除后加减原则,检索符号集合中的乘除后再检索加减,数字集合位置索引与符号索引之间存在对应关系,不难发现的。
增加处理:
public static int test(String gs) {
byte[] b = dealByte(gs.getBytes());
Vector v = parse(b);
Vector sgn = (Vector) v.elementAt(0);
Vector dig = (Vector) v.elementAt(1);
while (sgn.size() != 0) {
for (int i = 0; i < sgn.size(); i++) {
if ('*' == ((Byte) sgn.elementAt(i)).byteValue()
|| '/' == ((Byte) sgn.elementAt(i)).byteValue()) {
operate(sgn, dig, i);i--;
}
}
for (int i = 0; i < sgn.size(); i++) {
if ('+' == ((Byte) sgn.elementAt(i)).byteValue()
|| '-' == ((Byte) sgn.elementAt(i)).byteValue()) {
operate(sgn, dig, i);i--;
}
}
}
return ((Integer) dig.elementAt(0)).intValue();
}
static private void operate(Vector sgn, Vector dig, int index) {
int value = calc(((Integer) dig.elementAt(index)).intValue(),
((Integer) dig.elementAt(index + 1)).intValue(), ((Byte) sgn
.elementAt(index)).byteValue());
sgn.remove(index);
dig.setElementAt(new Integer(value), index);
dig.remove(index + 1);
}
此方式完全应用了算式的特点,加入括号处理相对复杂。
如何扩展加入(){}[],变得更强大一点??思考
OK。