组合公式为 "((r1c1+r1c2)/r1c3)"
1. 组合的公式是一个字符串.
2. 字符串元素包括"rc0123456789+-*/()"
3. r1c1=7,r1c2=2,r1c3=4
4. 求组合成的公式的值是多少.
解决思路:
1.对公式进行字符合法性检查.
2.对公式中出现的变量进行取值替换.
3.检查语句的合法性.(组合规则)
4.检查运算的合法性.(除数为0的情况)
5.求值.
具体解决方法:
str1 = "(r1c1+r1c2)/r1c3)"
str1 = replace(str1," ","") '去除公式中间出现的空格
1. 对公式进行字符合法性检查.
bool1 = getDataOperationCharCheck(str1)
if bool1 = false then
Response.write "公式不合法.有异常字符出现.<br>"
else
Response.write "公式检查通过!<br>"
end if
2.对公式中出现的变量进行取值替换
RCstr = getdataoperation(str1)
3.检查语句的合法性.(组合规则)
bool2 = getDataOperationSyntaxCheck(RCstr)
if bool2 = false then
Response.write "运算公式语法不合法,有组合异常字符出现.<br>"
else
Response.Write "运算公式语法检查通过!<br>"
end if
4.检查运算的合法性.(除数为0的情况)
bool3 = getDataOperationRunCheck(RCstr)
if bool3 = false then
Response.write "运算公式运算不合法,有除数为0出现.<br>"
else
Response.write "运算公式运算合法性检查通过!<br>"
end if
5.求值.
intValue = getRunSearch(RCstr)
6.运算结果:
(((7*1.0)+(2*1.0))/(4*1.0)) = 2.25
'1.=============================================================
'对原始公式进行字符检查,是否有不合法的字符
function getDataOperationCharCheck(datastr)
datastr = replace(datastr," ","")
sumchar = "rc0123456789+-*/()"
strlen = len(datastr)
strreturn = true
for i = 1 to strlen
singlechar = mid(datastr,i,1)
if instr(sumchar,singlechar) = 0 then
strreturn = false
exit for
end if
next
getDataOperationCharCheck = strreturn
end function
'2.==============================================================
'对原始计划公式进行取值替换.
'实现方法:对原始字符串进行单个字符检查,
'在出现 "+-*/()" 中的任何一个字符时,对已经组合生成的变量进行取值.
'在取到值的同时对其进行 double 转换 ,实现方法是 (intvalue * 1.0)
function getdataoperation(datastr)
strlen = len(datastr)
sunstr = ""
strID = ""
intvalue = 0
singlechar = ""
operationstr="()+-*/"
for i=1 to strlen
'Response.write mid(datastr,i,1) & "<br>"
singlechar = mid(datastr,i,1)
if instr(operationstr,singlechar) > 0 then
if strID <> "" then
intvalue = getValue(strID)
sunstr = sunstr & "(" & intvalue & "*1.0)" '(1)
intvalue = 0
strID = ""
end if
sunstr = sunstr & singlechar
singlechar = ""
else
strID = strID & singlechar
end if
next
getdataoperation = sunstr
end function
'变量取值函数.
'下列数据是为测试使用.
'
function getValue(strRC)
select case strRC
case "r1c1"
getValue = 2
case "r1c2"
getValue = 7
case "r1c3"
getValue = 2
end select
end function
'3.==============================================================
'对公式进行语法合法性检查.
'eg.检查 (),--,++,**,//,(/,*) 等 是否成对出现.
'检查是否有
function getDataOperationSyntaxCheck(datastr)
strreturn = true
datastr = replace(datastr," ","") '去除所有的空格
strlen = len(datastr)
num1 = 0 '记录 括号的 个数 采用 有 ( 加1, 有 ) 减1
upsinglechar = "" '相对本次的字符的上一个字符
singlechar = ""
operationstr1="()+-*/"
operationstr2="(+-*/" '相对 在 ( 左边出现的运的符号是正确的.
for i = 1 to strlen
singlechar = mid(datastr,i,1)
select case singlechar
case "("
num1 = num1 + 1
if upsinglechar <> "" then
if instr(operationstr2,upsinglechar) = 0 then '在左括号的左边若不为空,必需出现 "(+-*/" 中的一个.
strreturn = false
exit for
end if
end if
case ")"
num1 = num1 - 1
if num1 < 0 then
strreturn = false
exit for
end if
if instr(operationstr2,upsinglechar) > 0 then '在右括号的左边若不为空,必需不能出现 "(+-*/" 中的一个
strreturn = false
exit for
end if
case "+"
if instr(operationstr2,upsinglechar) > 0 then '在加号的左边若不空,必需不能出现 "(+-*/" 中的一个
strreturn = false
exit for
end if
case "-"
if instr(operationstr2,upsinglechar) > 0 then '在减号的左边若不空,必需不能出现 "(+-*/" 中的一个
strreturn = false
exit for
end if
case "*"
if instr(operationstr2,upsinglechar) > 0 then '在乘号的左边若不空,必需不能出现 "(+-*/" 中的一个
strreturn = false
exit for
end if
case "/"
if instr(operationstr2,upsinglechar) > 0 then '在除号的左边若不空,必需不能出现 "(+-*/" 中的一个
strreturn = false
exit for
end if
end select
upsinglechar = singlechar
singlechar = ""
next
getDataOperationSyntaxCheck = strreturn
end function
'4.==============================================================
'对组合公式进行运算合法性的检查
'首选查找有没有 "/0"出现.
'其次查找类似 "/(****)" = /0 出现
function getDataOperationRunCheck(datastr)
strreturn = true
if instr(datastr,"/")>0 then
if instr(datastr,"/0") > 0 then
strreturn = false
else
'对/ 后面出现的()内的数据进行运算,取值是否会有0出现.
'首先计算 "/" 出现的次数
'再次判断 "/(" 出现的次数
'若 "/(" 出现的次为0 则安全.
intnum1 = getInstrNum(datastr,"/")
intnum2 = getInstrNum(datastr,"/(")
if intnum2 > 0 then
for j = intnum2 to 1 step -1
intpoint1 = getInstrPoint(datastr,"/(",j)
if intpoint1 > 0 then
sumpoint = getRunCheck(datastr,intpoint1)
if CDbl(sumpoint) = CDbl(0) then
strreturn = false
exit for
end if
end if
next
end if
end if
end if
getDataOperationRunCheck= strreturn
end function
'检查字符运行的合法性.
'主要是对/()出现的字公式进行计算是否会等于0
function getRunCheck(datastr,intpoint1)
strlen = len(datastr)
intpoint = intpoint1 + 1
intnum = 0
singlechar = ""
rcsearch = ""
intreturn = 0
for m = intpoint to strlen
singlechar = mid(datastr,m,1)
if singlechar = "(" then
intnum = intnum + 1
end if
if singlechar = ")" then
intnum = intnum - 1
end if
rcsearch = rcsearch & singlechar
if intnum = 0 then
intreturn = getRunSearch(rcsearch)
exit for
end if
next
getRunCheck = intreturn
end function
'5.==============================================================
'求值.
function getRunSearch(strrcsearch)
sql = "select " & strrcsearch & " as rcvalue "
Set rs = conn.execute(sql)
'Response.write "<br>" & strrcsearch & "=" & rs("rcvalue") & "<br>"
getRunSearch = rs("rcvalue")
end function
'公共函数==============================================================
'返回substr 在 str1 中出现的次数
function getInstrNum(str1,substr)
strlen = len(str1)
substrlen = len(substr)
singlechar = ""
intreturn = 0
for i = 1 to strlen
singlechar = mid(str1,i,substrlen)
if singlechar = substr then
intreturn = intreturn + 1
end if
next
getInstrNum = intreturn
end function
'返回substr 在 str1 中 第 intnum 次出现的位置
'intnum 必需是大于0的正整数
function getInstrPoint(str1,substr,intnum)
intreturn = 0
strlen = len(str1)
substrlen = len(substr)
singlechar = ""
intcount = 0
for i = 1 to strlen
singlechar = mid(str1,i,substrlen)
if singlechar = substr then
intcount = intcount + 1
end if
if intcount = intnum then
intreturn = i
exit for
end if
next
getInstrPoint = intreturn
end function