`
gao_20022002
  • 浏览: 160239 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

自己处理公式

    博客分类:
  • Java
阅读更多

问题说明:

给定一个字符串,例如:

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。

 

3
0
分享到:
评论
1 楼 timelyRain 2008-12-17  
你是为了研究语法分析 词法分析还是为了制作一个工具方法?

仅仅使用的话可以用脚本引擎来处理。beanshell

相关推荐

Global site tag (gtag.js) - Google Analytics