to Drate(鸟窝里的虫) : 如果可以换成别的格式,不就不用问了吗:D 我手里有一个程序它已经实现了啊,可是就是不知道是怎么实现的!
(市场A表(29,3)+市场B表(30,3)+市场C表(31,3))*[2000]+市场C表(31,5)/[1000]首先我要从这个表达式中读出“市场A表(29,3)”,“市场B表(30,3)”然后到表格中找到对应的数值,-----------------------------------------字符串查找、替换都可以,但 得到的结果字符串(真正要计算的表达式的字符串格式) 怎么转换为 求值表达式 ? Study
都是加号吗??那有办法,我贴上的是我原来写的找出空格的算法 function Readparameter(source :String;j: Integer):String; var position: Integer; I: Integer; begin {参数source为须读入大字符串,J为第几个字符串} position:=pos(' ',source);{空格的位置} if j=1 then Result:=(copy(source,0,position-1)) else if j>1 then begin //找到第J-1个空格 For I:=1 To j-1 do begin position:=pos(' ',source);{空格的位置} source:=copy(source,position+1,Length(source)); end; //读取第J个字符串 position:=pos(' ',source);{空格的位置} Result:=Copy(source,0,position-1); end else Result:=''; end;
1、调用这个函数就实现了把其分成“市场A表(29,3)”,“市场B表(30,3)”....的功能, 2、然后再把这个函数再改一下(干脆改成多一个参数输入找的是什么字符算了),调用找出小括号里的两个数字 3、然后调用找出逗号,就接着分解出数字了。 over 给分
procedure TForm1.Button1Click(Sender: TObject); var temp,TempString,MidString:string; FormalString:TStringList; OpString:TStringList; //操作符是顺序的列表列表; beginIndex,i:integer; begin beginIndex := 0; FormalString := TStringList.Create; OpString := TStringList.create; TempString := '市场A表(29,3)+市场B表(30,3)+市场C表(31,3))*[2000]+市场C表(31,5)/[1000]'; temp := tempstring; for i:=0 to Length(temp) - 1 do begin if MidChr(temp[i]) then //比较涵数 begin OpString.add(temp[i]); MidString := MidStrings(Temp,beginIndex,i); //组合字符串; FormalString.Add(MidString);//需要的公式项目在此; BeginIndex := i; end; end; MidString := Copy(temp,BeginIndex+1,Length(temp)-BeginIndex);
end;//组合字符串; function TForm1.MidStrings(CurrString:string;BeginIndex,Index:integer):String; var resultString:String; begin if BeginIndex = 0 then resultstring := Copy(CurrString,1,index-1) else resultstring := Copy(CurrString,BeginIndex+1,(Index-1)-BeginIndex); result := resultstring; end;//判断是否为分隔符 function TForm1.MidChr(CurrString:String):Boolean; begin result := false; if (CurrString = '+') or (currString = '-') or (currString = '*') or (currString = '/') then result := true end;
关于字符串计算的问题很好解决。 function TForm1.Calculate(Expression: string): string; var vScript: Variant; begin vScript := CreateOleObject('ScriptControl'); vScript.Language := 'JavaScript'; // vScript.Language := 'VBScript'; Result := vScript.Eval(Expression); end; procedure TForm1.Button1Click(Sender: TObject); begin showmessage(Calculate(edit1.Text)); end;
建义把 (市场A表(29,3)+市场B表(30,3)+市场C表(31,3))*[2000]+市场C表(31,5)/[1000] 改成 (市场A表[29,3]+市场B表[30,3]+市场C表[31,3])*2000+市场C表[31,5]/1000 然后用: /** *@decription: 获取表达式的值. *@param value : 待计算的字符串表达式 *@return : 字符串表达式的值. */ function getValue(String value):float var strLeft,strTemp,strMid,strRight:String; dblTemp:float; begin int intIndexLeft;//最后一个“(”在字符串value 中的位置 int intIndexRight;//第一个")"在字符串value中的位置. intIndexLeft = lastIndexOf(value,'(');//取得左括号的索引 if ( intIndexLeft = 0 ) then//value中不存在括号. begin if pos('市场', value) then result := getCellValue(value); else result := parseValue(value); end else begin intIndexRigh = STRPOS(COPY(value,intIndexLeft,length(value)),')');//获取与左括号相匹配的右括号。 //将表达式分成 左 中 右三串 strLeft = STRPOS(value,0,intIndexLeft);//取左串 strTemp = STRPOS(value,intIndexLeft+1,intIndexRight);//取中串 try dblTemp = parseValue(strTemp);//计算中串的值. except //计算出错 end; strMid = floattostr(dblTemp);//得到新的中串 strRight= STRPOS(value,intIndexRight+1,length(value));//获取右串 value = strLeft + strMid + strRight;//重新组合字符串表达式 . getValue(value);//递归计算. } //end else return result; end;
//取得最后一个分隔字符所在位置 function lastIndexOf(String sourceStr; String strSplit):Integer var sourceStr :String; begin str := 'afsdfaasdfsdfadfsfasfdsf'; result := pos(strSplit, sourceStr); while pos(strSplit, sourceStr)<>0 do begin result := pos(strSplit, sourceStr); sourceStr1 := copy(sourceStr,result,length(sourceStr));//得到部分sourceStr sourceStr := copy(sourceStr1);//删掉第一个分隔符前的sourceStr end; end;
function getCellValue(String StrCell):float begin //查询数据表 end;
function parseValue(String:strValue):float begin //对字符串进行计算 end;
var TempString:String; FList,LastList:Tstrings; i:integer; begin FList:=TstringList.Create; LastList:=TstringList.Create; TempString := '市场A表(29,3)+(市场B表(30,3)+市场C表(31,3))*[2000]+市场C表(31,5)/[1000]'; ExtractStrings(['+','-','*','/'], [], pchar(TempString), FList);//使用运算符号来拆分串 LastList.Clear; for i:=0 to FList.Count-1 do begin {中括号为常量表达式,不参与分解} if pos('[',Flist[i])=0 then LastList.Add(FList[i]); end; end; 剩下的就容易了:D给分!
SubStr1 := 市场B表(30,3);
SubStr2 := 市场A;
SubStr3 := 市场C表(30,3);
...Val := 市场B表(30,3) -> Value;
...AnsiReplaceStr(S, SubStr1, FloatToStr(Val));
...找一個表達式解析器傳入參數 S;
你的办法太死了,不是所有的公式都是一个样子的啊
如果可以换成别的格式,不就不用问了吗:D
我手里有一个程序它已经实现了啊,可是就是不知道是怎么实现的!
function Readparameter(source :String;j: Integer):String;
var
position: Integer;
I: Integer;
begin
{参数source为须读入大字符串,J为第几个字符串}
position:=pos(' ',source);{空格的位置}
if j=1 then
Result:=(copy(source,0,position-1))
else if j>1 then
begin
//找到第J-1个空格
For I:=1 To j-1 do
begin
position:=pos(' ',source);{空格的位置}
source:=copy(source,position+1,Length(source));
end;
//读取第J个字符串
position:=pos(' ',source);{空格的位置}
Result:=Copy(source,0,position-1);
end
else
Result:='';
end;
2、然后再把这个函数再改一下(干脆改成多一个参数输入找的是什么字符算了),调用找出小括号里的两个数字
3、然后调用找出逗号,就接着分解出数字了。
over
给分
var
temp,TempString,MidString:string;
FormalString:TStringList;
OpString:TStringList; //操作符是顺序的列表列表;
beginIndex,i:integer;
begin
beginIndex := 0;
FormalString := TStringList.Create;
OpString := TStringList.create;
TempString := '市场A表(29,3)+市场B表(30,3)+市场C表(31,3))*[2000]+市场C表(31,5)/[1000]';
temp := tempstring;
for i:=0 to Length(temp) - 1 do
begin
if MidChr(temp[i]) then //比较涵数
begin
OpString.add(temp[i]);
MidString := MidStrings(Temp,beginIndex,i); //组合字符串;
FormalString.Add(MidString);//需要的公式项目在此;
BeginIndex := i;
end;
end;
MidString := Copy(temp,BeginIndex+1,Length(temp)-BeginIndex);
end;//组合字符串;
function TForm1.MidStrings(CurrString:string;BeginIndex,Index:integer):String;
var
resultString:String;
begin
if BeginIndex = 0 then
resultstring := Copy(CurrString,1,index-1)
else
resultstring := Copy(CurrString,BeginIndex+1,(Index-1)-BeginIndex);
result := resultstring;
end;//判断是否为分隔符
function TForm1.MidChr(CurrString:String):Boolean;
begin
result := false;
if (CurrString = '+') or (currString = '-') or (currString = '*') or (currString = '/') then
result := true
end;
function TForm1.Calculate(Expression: string): string;
var
vScript: Variant;
begin
vScript := CreateOleObject('ScriptControl');
vScript.Language := 'JavaScript';
// vScript.Language := 'VBScript';
Result := vScript.Eval(Expression);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(Calculate(edit1.Text));
end;
(市场A表(29,3)
市场B表(30,3)
市场C表(31,3))
[2000]
市场C表(31,5)
[1000]
2、去除多于扩号得到StringList2
市场A表(29,3)
市场B表(30,3)
市场C表(31,3)
[2000]
市场C表(31,5)
[1000]
3、如果不是以'['开头,查找数据,以'['开头则去除'[]',得到StringList3
data1
data2
data3
2000
data4
1000
4、根据StringList1和String3替换原始字符串,得到字符串
(data1+data2+data3)*2000+data4/10005、计算
这里面有'+','-','*','/',括号也是有的有用,有的无用,你的办法是不行的。to 沙隆拔斯: 你没有考虑括号的问题。
你的思路非常正确,解决后给分!
(市场A表(29,3)+市场B表(30,3)+市场C表(31,3))*[2000]+市场C表(31,5)/[1000]
改成
(市场A表[29,3]+市场B表[30,3]+市场C表[31,3])*2000+市场C表[31,5]/1000
然后用:
/**
*@decription: 获取表达式的值.
*@param value : 待计算的字符串表达式
*@return : 字符串表达式的值.
*/
function getValue(String value):float
var
strLeft,strTemp,strMid,strRight:String;
dblTemp:float;
begin
int intIndexLeft;//最后一个“(”在字符串value 中的位置
int intIndexRight;//第一个")"在字符串value中的位置. intIndexLeft = lastIndexOf(value,'(');//取得左括号的索引
if ( intIndexLeft = 0 ) then//value中不存在括号.
begin
if pos('市场', value) then
result := getCellValue(value);
else
result := parseValue(value);
end
else
begin
intIndexRigh = STRPOS(COPY(value,intIndexLeft,length(value)),')');//获取与左括号相匹配的右括号。
//将表达式分成 左 中 右三串
strLeft = STRPOS(value,0,intIndexLeft);//取左串
strTemp = STRPOS(value,intIndexLeft+1,intIndexRight);//取中串
try
dblTemp = parseValue(strTemp);//计算中串的值.
except
//计算出错
end;
strMid = floattostr(dblTemp);//得到新的中串
strRight= STRPOS(value,intIndexRight+1,length(value));//获取右串
value = strLeft + strMid + strRight;//重新组合字符串表达式 .
getValue(value);//递归计算.
} //end else
return result;
end;
//取得最后一个分隔字符所在位置
function lastIndexOf(String sourceStr; String strSplit):Integer
var
sourceStr :String;
begin
str := 'afsdfaasdfsdfadfsfasfdsf';
result := pos(strSplit, sourceStr);
while pos(strSplit, sourceStr)<>0 do
begin
result := pos(strSplit, sourceStr);
sourceStr1 := copy(sourceStr,result,length(sourceStr));//得到部分sourceStr
sourceStr := copy(sourceStr1);//删掉第一个分隔符前的sourceStr
end;
end;
function getCellValue(String StrCell):float
begin
//查询数据表
end;
function parseValue(String:strValue):float
begin
//对字符串进行计算
end;
TempString:String;
FList,LastList:Tstrings;
i:integer;
begin
FList:=TstringList.Create;
LastList:=TstringList.Create;
TempString := '市场A表(29,3)+(市场B表(30,3)+市场C表(31,3))*[2000]+市场C表(31,5)/[1000]';
ExtractStrings(['+','-','*','/'], [], pchar(TempString), FList);//使用运算符号来拆分串
LastList.Clear;
for i:=0 to FList.Count-1 do
begin
{中括号为常量表达式,不参与分解}
if pos('[',Flist[i])=0 then
LastList.Add(FList[i]);
end;
end;
剩下的就容易了:D给分!