!!!!!!!看谁基础牢!!!!!!!!!!!

soyol 2004-08-10 12:19:00
如何实现:
(a+b)*c*(d+e)
用程序分解为
a*c*d+a*c*e+b*c*d+b*c*e
其中a,..,e是字符串
...全文
1821 51 打赏 收藏 转发到动态 举报
写回复
用AI写文章
51 条回复
切换为时间正序
请发表友善的回复…
发表回复
S.F. 2004-11-12
  • 打赏
  • 举报
回复
up
lushiyu0 2004-09-28
  • 打赏
  • 举报
回复
看俺的!
if str =‘(a+b)*c*(d+e)’then
str:='a*c*d+a*c*e+b*c*d+b*c*e'
;

哈哈,搞笑一下
getter 2004-08-15
  • 打赏
  • 举报
回复
若是表達式求值用後綴式(逆波闌)...若解析表達式的話...我還想不到...
打簡單的先乘進...
wjwboy 2004-08-14
  • 打赏
  • 举报
回复
学过数学的都知道呀!
lw549 2004-08-14
  • 打赏
  • 举报
回复
1.用栈
原理上面已经有人说了,估计也没什么别的方法
2.用树
上面也有人说了.
3.用字符替换
这个用的资源比较少,用循环检查表达式的')'找到后就找他左边的最近的'(',然后计算里面的结果,将得到的结果替换掉括号之间的内容,如此循环.

无论哪种方法,递归都是必须的.原理大同小异.

第三种方法实现代码
http://borland.mblogger.cn/lw549/posts/808.aspx
soyol 2004-08-14
  • 打赏
  • 举报
回复
我的方法是用一个递归直接解析成
{
{A,B,C}
{D,E}
{F,G,H }
}

------
type
TRuleList=class(TStringList)
private
//确定需要添加项的列数,例:(a+b)*c 中添加 c 时为2 。
addcount:integer;
public
Constructor Create();
procedure addColumn(); //加列
procedure addItem(const item:string); //为account列加新行
procedure addList(const childlist:TRuleList); //加新表
function getRule():string;
Destructor Destroy();override;
end;

-----------
//主函数
function getResult(const source:string):string;
var
ipos:integer; //原始字符串遍历下标
bracketcount:integer; //括号记数
wordflag:0..2; //0-未开始读词;1-已开始读词;2-括号结束
aword:string; //词
//err:string; //出错信息
rulelist:TRuleList; //规则

function getRule(const source:string):TRuleList; //解析函数
var
rlist,childlist:TRuleList;
begin
result:=nil;
rlist:=TRuleList.Create();
try
while ipos<=length(source) do
begin
case source[ipos] of
AnsiChar('*'):
begin
if wordflag=0 then
begin
raise Exception.Create('语法错误: 第'+inttostr(ipos)+'字节 * 号附近');
end;
if wordflag=1 then
begin
rlist.addItem(aword);
end;
wordflag:=0;
aword:='';
ipos:=ipos+1;
end; //'*'
AnsiChar('+'):
begin
if wordflag=0 then
begin
raise Exception.Create('语法错误: 第'+inttostr(ipos)+'字节 + 号附近');
end;
if wordflag=1 then
rlist.addItem(aword);
rlist.addColumn();
wordflag:=0;
aword:='';
ipos:=ipos+1;
end; // '+'
AnsiChar('('):
begin
bracketcount:=bracketcount+1;
ipos:=ipos+1;
if wordflag=1 then
begin
rlist.addItem(aword);
wordflag:=0;
aword:='';
end;
childlist:=getRule(source);//递归
if childlist<>nil then
begin
rlist.addlist(childlist);
childlist.Free();
end
else
begin
break;
end
end; // '('
AnsiChar(')'):
begin
bracketcount:=bracketcount-1;
ipos:=ipos+1;
if(bracketcount<0) then
begin
raise Exception.Create('语法错误: 第'+inttostr(ipos-1)+'字节 ) 号附近,括号不匹配');
end;
if wordflag=1 then
begin
rlist.addItem(aword);
wordflag:=2;
aword:='';
end;
if wordflag=0 then
begin
raise Exception.Create('语法错误: 第'+inttostr(ipos-1)+'字节 ) 号附近');
end;
if rlist.Count=0 then
begin
raise Exception.Create('语法错误: 第'+inttostr(ipos-1)+'字节 ) 号附近,空括号');
end;
result:=rlist;
break;
end; // ')'
else
begin
aword:=aword+source[ipos];
wordflag:=1;
ipos:=ipos+1;
end; //else
end; //case
end; //while
//showMessage(inttostr(bracketcount)+' '+rlist.getRule()); //调试信息
if (bracketcount<>0) and (ipos>=length(source)) then
begin
raise Exception.Create('语法错误:结束时括号不匹配');
end;

if (bracketcount=0) and (ipos>length(source)) then //遍历完成,正常返回
begin
if wordflag=1 then
begin
rlist.addItem(aword);
wordflag:=0;
end;
result:=rlist;
end;
//else 未完成(出错,或是递归返回)

except
on Exception do
begin
if rlist<>nil then
begin
rlist.Free();
end;
raise; //重发
end;
end;//except
end; //function getRule

begin
ipos:=1;
rulelist:=nil;
wordflag:=0;
aword:='';
bracketcount:=0;
try
rulelist:=getRule(source); //获得规则
if rulelist<>nil then
begin
result:=rulelist.getRule();
rulelist.Free();
end
except
on e:Exception do
showMessage(e.Message);
end;
end; //function getResult


procedure TForm1.Button1Click(Sender: TObject);
begin
Edit2.Text:=getResult(Edit1.Text);
end;
soyol 2004-08-12
  • 打赏
  • 举报
回复
多谢 sliant() ( )
说得很清楚了
那位高人帮忙实现一下,练练手。

---------------------------------------
而我的方法是用一个递归直接解析成
{
{A,B,C}
{D,E}
{F,G,H }
}
这也是我要的最终形式
soyol 2004-08-12
  • 打赏
  • 举报
回复
这个贴子之所以取名"基础"!!!!
它的算法不难,而且算法很多.
但是每一种实现起来都要考虑好一阵子~~(也许是我愚钝).
还请大家多给代码.
woodtigerzizz 2004-08-12
  • 打赏
  • 举报
回复
晕了,看了半天,感觉自己是个白痴。伤自尊了!
超级大笨狼 2004-08-12
  • 打赏
  • 举报
回复
这个不难,如果看数学基础牢
那么
1,解线性方程因式分解
比如:
输入:"a^2 - 2*a*b + b^2"
输出:"(a-b)*(a-b)"

提示:好好回家看看线性代数的书哦。

2,级数:

输入:e ^ x
输出:∑ x ^ n / n!

哈哈,第一题可能答出,第二题你要苦练10年哦!!!
zzzxxxcccvvv 2004-08-11
  • 打赏
  • 举报
回复
2个递归函数

一个用来分离基本数字和符号。(两个栈)

另一个对两个栈进行合并和分解。

。。。
说就容易,做是挺难的。

估计至少用两天工作日。(1天写程序,1天测试和修复bug)
Canvas 2004-08-11
  • 打赏
  • 举报
回复
不是编译问题,顶多是优化编译问题。是一个树的遍历问题。
soyol 2004-08-11
  • 打赏
  • 举报
回复
Gfire(风之蓝歌) ( ):

要是
((a+b)*c+d)*e+f


--------------------------

我想到的方法是,用递归(分析语法)加动态的多维结构(存储多项式)实现。可是对delphi不熟,希望各位帮忙。
mythay 2004-08-11
  • 打赏
  • 举报
回复
用matlab吧,
drunkboy 2004-08-11
  • 打赏
  • 举报
回复
用栈!
Gfire 2004-08-11
  • 打赏
  • 举报
回复
分成三步不就得了,
f := a+b;
g := d+e;
f*c*g;
再把三个相乘,不就可以了,何必非得要一步
soyol 2004-08-11
  • 打赏
  • 举报
回复
对,就是去括号

yuan179 2004-08-11
  • 打赏
  • 举报
回复
如果你只是要实现去括号的问题,没有那么困难吧
cdwei80 2004-08-11
  • 打赏
  • 举报
回复
应该使用数据结构中的堆栈,用2个,一个放字符,一个放操作符。根据优先级来压栈。
我感觉应该是这样
soyol 2004-08-11
  • 打赏
  • 举报
回复
两个栈不行吧
加载更多回复(31)

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧