写了一个字符串表达式的计算方法(比如说"3+2*3/2-5*2d2"),按照最容易想到的办法使用多重循环嵌套
不过, 每一层嵌套的逻辑实际上是一样的, 是否可以有更简洁的表达方式呢?(比如说用一个函数
来执行每个for循环的逻辑)说明
//d是自定义的运算符,5d6表示投5次6面的骰子结果相加, 一枚硬币就可以看作一个d2的骰子
//d操作符哪里没有用循环, 其实考虑到一致性, 这里也应该可以用一个2层的循环来写
//这些代码可能有许多问题...欢迎大家指正, 比如说那个
if (下级运算符[0].equals(上级运算符[上级运算符循环]))
就从来没执行过, 因为前面的
Double.parseDoule()和Double.toString()把整数字符都转化成浮点字符了......(5=>5.0) public String countExpression(String countmessage) throws NumberFormatException
{
String returncm = countmessage;
String[] tadd = countmessage.split("\\+");
double[] taddnum = new double[tadd.length];
double naddtmp = 0;
for (int iadd=0;iadd<tadd.length;iadd++)
{
String[] tdec = tadd[iadd].split("-");
double[] tdecnum = new double[tdec.length];
double ndectmp = 0;
for (int idec=0;idec<tdec.length;idec++)
{
String[] tmul = tdec[idec].split("\\*");
double[] tmulnum = new double[tmul.length];
double nmultmp = 0;
for (int imul=0;imul<tmul.length;imul++)
{
//System.out.println(tmul[imul]);
String[] tdiv = tmul[imul].split("/");
double[] tdivnum = new double[tdiv.length];
double ndivtmp = 0;
for (int idiv=0;idiv<tdiv.length;idiv++)
{
if (tdiv[idiv].equalsIgnoreCase("d"))
tdiv[idiv] = "1d20";
String[] tdice = tdiv[idiv].split("d");
int intdiceaddtmp=0;
StringBuffer tmpDiceSeq=new StringBuffer(Colors.RED);
if (tdice[0].equals(tdiv[idiv]))
{
intdiceaddtmp=Integer.parseInt(tdiv[idiv]);
//System.out.println(intdiceaddtmp);
}
else
{
if (tdice.length > 2)
return "骰子表达式非法";
if (tdice[0].equals(""))
tdice[0]="1";
if (tdice.length == 1 )
{
for (int idice=0;idice<Integer.parseInt(tdice[0]);idice++)
{
int tmp = countDice(20);
intdiceaddtmp+=tmp;
if (idice == 0)
tmpDiceSeq.append(tmp);
else
tmpDiceSeq.append("+").append(tmp);
//intaddtmp.append("+").append(tmp);
}
returncm = returncm.replaceFirst(tdiv[idiv],tmpDiceSeq.append(Colors.BROWN).toString());
}
else
{
if (!checkDice(Integer.parseInt(tdice[1])))
{
return "这个骰子面数有点奇怪...";
}
for (int idice=0;idice<Integer.parseInt(tdice[0]);idice++)
{
int tmp = countDice(Integer.parseInt(tdice[1]));
intdiceaddtmp+=tmp;
if (idice == 0)
tmpDiceSeq.append(tmp);
else
tmpDiceSeq.append("+").append(tmp);
//intaddtmp.append("+").append(tmp);
}
returncm = returncm.replaceFirst(tdiv[idiv],tmpDiceSeq.append(Colors.BROWN).toString());
}
}
tdiv[idiv] = Integer.toString(intdiceaddtmp);
tdivnum[idiv] = Double.parseDouble(tdiv[idiv]);
if (tdivnum[idiv]==0)
return "不支持除法表达式中含有0";
}
if (tdiv[0].equals(tmul[imul]))
{
tmulnum[imul] = Double.parseDouble(tmul[imul]);//continue
}
else
{
ndivtmp = tdivnum[0];
for (int idivnum=1;idivnum<tdivnum.length;idivnum++)
{
ndivtmp = ndivtmp/tdivnum[idivnum];
} tmulnum[imul] = ndivtmp;
}
tmul[imul] = Double.toString(tmulnum[imul]);
}
if (tmul[0].equals(tdec[idec]))
{
tdecnum[idec] = Double.parseDouble(tdec[idec]);//continue
}
else
{
nmultmp = tmulnum[0];
for (int imulnum=1;imulnum<tmulnum.length;imulnum++)
{
nmultmp = nmultmp*tmulnum[imulnum];
}
tdecnum[idec] = nmultmp;
//System.out.println(nmultmp);
}
tdec[idec] = Double.toString(tdecnum[idec]);
//System.out.println(tdec[idec]);
}
if (tdec[0].equals(tadd[iadd]))
{
taddnum[iadd] = Double.parseDouble(tadd[iadd]);//continue
}
else
{
ndectmp = tdecnum[0];
for (int idecnum=1;idecnum<tdecnum.length;idecnum++)
{
ndectmp = ndectmp-tdecnum[idecnum];
}
taddnum[iadd] = ndectmp;
}
tadd[iadd] = Double.toString(taddnum[iadd]);
}
if (tadd[0].equals(countmessage))
{
returncm = countmessage + Colors.DARK_GREEN + "=" +Colors.BROWN + countmessage + Colors.DARK_GREEN + "=" + Colors.RED + countmessage;
}
else
{
naddtmp = taddnum[0];
for (int iaddnum=1;iaddnum<taddnum.length;iaddnum++)
{
//System.out.println(naddtmp+":"+iaddnum+":"+taddnum.length);
naddtmp = naddtmp+taddnum[iaddnum];
//System.out.println("+:"+naddtmp+":"+taddnum.length);
}
returncm = countmessage + Colors.DARK_GREEN + "=" +Colors.BROWN + returncm + Colors.DARK_GREEN + "=" + Colors.RED + Double.toString(naddtmp);
}
return returncm;
}
不过, 每一层嵌套的逻辑实际上是一样的, 是否可以有更简洁的表达方式呢?(比如说用一个函数
来执行每个for循环的逻辑)说明
//d是自定义的运算符,5d6表示投5次6面的骰子结果相加, 一枚硬币就可以看作一个d2的骰子
//d操作符哪里没有用循环, 其实考虑到一致性, 这里也应该可以用一个2层的循环来写
//这些代码可能有许多问题...欢迎大家指正, 比如说那个
if (下级运算符[0].equals(上级运算符[上级运算符循环]))
就从来没执行过, 因为前面的
Double.parseDoule()和Double.toString()把整数字符都转化成浮点字符了......(5=>5.0) public String countExpression(String countmessage) throws NumberFormatException
{
String returncm = countmessage;
String[] tadd = countmessage.split("\\+");
double[] taddnum = new double[tadd.length];
double naddtmp = 0;
for (int iadd=0;iadd<tadd.length;iadd++)
{
String[] tdec = tadd[iadd].split("-");
double[] tdecnum = new double[tdec.length];
double ndectmp = 0;
for (int idec=0;idec<tdec.length;idec++)
{
String[] tmul = tdec[idec].split("\\*");
double[] tmulnum = new double[tmul.length];
double nmultmp = 0;
for (int imul=0;imul<tmul.length;imul++)
{
//System.out.println(tmul[imul]);
String[] tdiv = tmul[imul].split("/");
double[] tdivnum = new double[tdiv.length];
double ndivtmp = 0;
for (int idiv=0;idiv<tdiv.length;idiv++)
{
if (tdiv[idiv].equalsIgnoreCase("d"))
tdiv[idiv] = "1d20";
String[] tdice = tdiv[idiv].split("d");
int intdiceaddtmp=0;
StringBuffer tmpDiceSeq=new StringBuffer(Colors.RED);
if (tdice[0].equals(tdiv[idiv]))
{
intdiceaddtmp=Integer.parseInt(tdiv[idiv]);
//System.out.println(intdiceaddtmp);
}
else
{
if (tdice.length > 2)
return "骰子表达式非法";
if (tdice[0].equals(""))
tdice[0]="1";
if (tdice.length == 1 )
{
for (int idice=0;idice<Integer.parseInt(tdice[0]);idice++)
{
int tmp = countDice(20);
intdiceaddtmp+=tmp;
if (idice == 0)
tmpDiceSeq.append(tmp);
else
tmpDiceSeq.append("+").append(tmp);
//intaddtmp.append("+").append(tmp);
}
returncm = returncm.replaceFirst(tdiv[idiv],tmpDiceSeq.append(Colors.BROWN).toString());
}
else
{
if (!checkDice(Integer.parseInt(tdice[1])))
{
return "这个骰子面数有点奇怪...";
}
for (int idice=0;idice<Integer.parseInt(tdice[0]);idice++)
{
int tmp = countDice(Integer.parseInt(tdice[1]));
intdiceaddtmp+=tmp;
if (idice == 0)
tmpDiceSeq.append(tmp);
else
tmpDiceSeq.append("+").append(tmp);
//intaddtmp.append("+").append(tmp);
}
returncm = returncm.replaceFirst(tdiv[idiv],tmpDiceSeq.append(Colors.BROWN).toString());
}
}
tdiv[idiv] = Integer.toString(intdiceaddtmp);
tdivnum[idiv] = Double.parseDouble(tdiv[idiv]);
if (tdivnum[idiv]==0)
return "不支持除法表达式中含有0";
}
if (tdiv[0].equals(tmul[imul]))
{
tmulnum[imul] = Double.parseDouble(tmul[imul]);//continue
}
else
{
ndivtmp = tdivnum[0];
for (int idivnum=1;idivnum<tdivnum.length;idivnum++)
{
ndivtmp = ndivtmp/tdivnum[idivnum];
} tmulnum[imul] = ndivtmp;
}
tmul[imul] = Double.toString(tmulnum[imul]);
}
if (tmul[0].equals(tdec[idec]))
{
tdecnum[idec] = Double.parseDouble(tdec[idec]);//continue
}
else
{
nmultmp = tmulnum[0];
for (int imulnum=1;imulnum<tmulnum.length;imulnum++)
{
nmultmp = nmultmp*tmulnum[imulnum];
}
tdecnum[idec] = nmultmp;
//System.out.println(nmultmp);
}
tdec[idec] = Double.toString(tdecnum[idec]);
//System.out.println(tdec[idec]);
}
if (tdec[0].equals(tadd[iadd]))
{
taddnum[iadd] = Double.parseDouble(tadd[iadd]);//continue
}
else
{
ndectmp = tdecnum[0];
for (int idecnum=1;idecnum<tdecnum.length;idecnum++)
{
ndectmp = ndectmp-tdecnum[idecnum];
}
taddnum[iadd] = ndectmp;
}
tadd[iadd] = Double.toString(taddnum[iadd]);
}
if (tadd[0].equals(countmessage))
{
returncm = countmessage + Colors.DARK_GREEN + "=" +Colors.BROWN + countmessage + Colors.DARK_GREEN + "=" + Colors.RED + countmessage;
}
else
{
naddtmp = taddnum[0];
for (int iaddnum=1;iaddnum<taddnum.length;iaddnum++)
{
//System.out.println(naddtmp+":"+iaddnum+":"+taddnum.length);
naddtmp = naddtmp+taddnum[iaddnum];
//System.out.println("+:"+naddtmp+":"+taddnum.length);
}
returncm = countmessage + Colors.DARK_GREEN + "=" +Colors.BROWN + returncm + Colors.DARK_GREEN + "=" + Colors.RED + Double.toString(naddtmp);
}
return returncm;
}
checkDice是检查骰子的合法性(d5的取随机数是可以的不过一般实际中没有d5)
countDice是计算随机数(里面写的是return Math.random()*n+1)
大体的思路是先用+分割表达式, 然后用-,以此类推, 最下层的循环计算完毕后把数值
赋给上层替换原来不能计算的表达式
举例而言3-2+4+3, 的一层分割为"3-2","4","3",
第二层分割为1(第二层可以计算减号),4(不能再计算的数值返回上层),3
的一层再用自己的方式计算(相加)
StrExpression se = new StrExpression();
System.out.println(se.getValue(expr));
http://www.hibernate.org.cn/viewtopic.php?t=4844&postdays=0&postorder=asc&start=0