如何转化为可计算的表达式?

shuilong 2004-08-04 10:26:44
如何将VCL标准组件TEDIT里的TEXT属性转变为可计算的表达式(假设Edit->Text为1+1)?
...全文
293 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
onemonth 2004-09-24
  • 打赏
  • 举报
回复
贴的这些代码完全没法扩展。还是不用的好。
houing_0123 2004-09-23
  • 打赏
  • 举报
回复

#include"conio.h"
#include "stdio.h"
#include "stdlib.h"
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef char SElemType;
typedef int Status;
#define OK 1
#define OVERFLOW 0
#define ERROR 0
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;

Status InitStack(SqStack &s){//构造一个空栈
s.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!s.base)exit(OVERFLOW);
s.top=s.base;
s.stacksize=STACK_INIT_SIZE;
return OK;
}//InitStack

SElemType Getop(SqStack s){//若栈不空,则返回用e返回s栈元素
SElemType e;
if(s.top==s.base)return ERROR;
e=*(s.top-1);
return e;
}//Getop

Status Push(SqStack &s,SElemType e){//插入元素e为新的栈顶元素
if(s.top-s.base>=s.stacksize){//栈满,追加存储空间
s.base=(SElemType *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!s.base)exit(OVERFLOW);//存储分配失败
s.top=s.base+s.stacksize;
s.stacksize+=STACKINCREMENT;
}
*s.top++=e;
return OK;
}//Push

Status Pop(SqStack &s,SElemType &e){
//若栈不空,则删除s的栈顶元素,用e 返回其值,并
//返回OK,否则返回ERROR
if(s.top==s.base)return ERROR;
e=*--s.top;
return OK;
}//Pop

char Precede(char e,char c){//比较运算任符的优先权
if(e=='+')
{ if(c=='+'||c=='-'||c==')'||c=='#')
return '>';
return '<';
}
else if(e=='-')
{
if(c=='+'||c=='-'||c==')'||c=='#')
return '>';
return '<';
}
else if(e=='*')
{
if(c=='(')
return '<';
return '>';
}
else if(e=='/')
{
if(c=='(')
return '<';
return '>';
}
else if(e=='(')
{
if(c==')')
return '=';
else if(c=='+'||c=='-'||c=='*'||c=='/'||c=='(')
return '<';
}
else if(e==')')
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c==')'||c=='#')
return '>';
}
else if(e=='#')
{ if(c=='#')
return '=';
else if(c=='+'||c=='-'||c=='*'||c=='/'||c=='(')
return '<';
}
return 0;
}

int Operate(char b,char theta,char a) {//运算
int temp;
// b-=48;a-=48;
if(theta=='+')
temp =b+a;
else if(theta=='*')
temp=b * a;
else if(theta=='-')
temp=b-a;
else if(theta=='/')
temp=b/a;
return temp;
}

char OP[]={'+','-','*','/','(',')','#'};
int In(char c,char OP[])//比较是否为运算符
{ int i;
for(i=0;i<=6;i++)
if(c==OP[i])
return 1;
return 0;
}

char EvluateExpression(){
//算术表达式求值的算符优先算法.设OPTR和OPND分别为运算栈和运算数栈,
//OP为运算任集合
SqStack OPTR,OPND;char a,b,c,x,theta;
InitStack(OPTR); Push(OPTR,'#');
InitStack(OPND);c=getchar();
while(c!='#'||Getop(OPTR)!='#'){
if(!In(c,OP)){Push(OPND,c-48);c=getchar();}//不是运算符则进栈
else
switch(Precede(Getop(OPTR),c)){
case '<'://栈顶元素优先权低
Push(OPTR,c);c=getchar();break;
case '='://脱括号并接收下一字符
Pop(OPTR,x);c=getchar();break;
case '>'://退栈并将运算结果入栈
Pop(OPTR,theta);
Pop(OPND,b);Pop(OPND,a);
Push(OPND,Operate(a,theta,b));
break;
}//switch
}//while
return Getop(OPND);
}//EvluateExpression

void main()
{ char temp;
temp=EvluateExpression();
printf("%d\n",temp);
return;
}




COpyFRee 2004-09-23
  • 打赏
  • 举报
回复
参见编译原理中的关于逆波兰表达式的部分!
lonelyegg 2004-09-23
  • 打赏
  • 举报
回复
受益匪浅啊
penu 2004-08-20
  • 打赏
  • 举报
回复
简单的表达式计算啊,类似的帖子很多了。
lidawen 2004-08-20
  • 打赏
  • 举报
回复
String __fastcall TForm1::CalculateFromStr(String str)
{ //计算简单的算术式(该函数只能计算含有"("、")"、"*"、"/"、"+"、"-"的表达式)
String pstr0="";
if(str.Length()<=0)
return pstr0;
//先括号,*/,+-
int i=0;
// pstr0=str;
char p0[300];
char p1[200];
String pstr1;
char p2[200];
String pstr2;
char p3[200];
String pstr3;

float a1=0;
float a2=0;

int left=0; //左括号的个数
bool haveleft=false;
int firstleft=0; //第一(的位置
int tofirstright=0; //对应第一个(的)的位置

//// (((((((())))))))))) 1.括号 start
bool flag =false ;
bool change = false;
memset(p0,0,sizeof(p0));
sprintf(p0,"%s",str.c_str()) ;
memset(p1,0,sizeof(p1));
memset(p2,0,sizeof(p2));
memset(p3,0,sizeof(p3));
for(i=0;i<strlen(p0);i++)
{
if(p0[i]=='(')
{
left++ ;
haveleft = true ;
if(1==left)
firstleft=i ;
}
else if(p0[i]==')')
{
left-- ;
if(0==left)
tofirstright=i;
}

if(0==left && haveleft)
{
flag=true ;
memcpy(p1,p0,firstleft);
memcpy(p2,p0+firstleft+1,i-firstleft-1);
if((i+1)==strlen(p0))
memset(p3,0,sizeof(p3));
else
memcpy(p3,p0+i+1,strlen(p0)-(i+1));
haveleft=false;
}

if(flag)
{
if(firstleft==0)
pstr0 =CalculateFromStr(p2)+p3;
else
pstr0 =p1+ CalculateFromStr(p2)+p3 ;

flag = false ;
//重新循环+p3

memset(p0,0,sizeof(p0));
sprintf(p0,"%s",pstr0.Trim().c_str());
i=-1;
firstleft=0;
left=0;
memset(p1,0,sizeof(p1));
memset(p2,0,sizeof(p2));
memset(p3,0,sizeof(p3));
}
}
//// (((((((())))))))))) end

//*************//////////// start
//运算*/
firstleft=0; //第一个*/的位置
int firstdata=0; //第一乘数或除数的位置
int number=0;
bool haveride=false;
bool havediv =false;
memset(p1,0,sizeof(p1)); // 第一个乘数或除数
memset(p2,0,sizeof(p2)); //
memset(p3,0,sizeof(p3));

for(i=0;i<=strlen(p0);i++)
{
if('*'==p0[i] )
{
if(number==0)
{
haveride=true;
firstleft=i;
}
number++ ;

if(1==number)
memcpy(p1,p0+firstdata,i-firstdata);
else
memcpy(p2,p0+firstleft+1,i-(firstleft+1));
}
else if('/'==p0[i] )
{
if(number==0)
{
havediv=true;
firstleft=i ;
}
number++;

if(1==number)
memcpy(p1,p0+firstdata,i-firstdata);
else
memcpy(p2,p0+firstleft+1,i-(firstleft+1));
}
else if('-'==p0[i] || '+'==p0[i] || i==strlen(p0))
{
if(1==number)
{
memcpy(p2,p0+firstleft+1,i-(firstleft+1));
number++ ;
}
if(0==number)
firstdata = i+1 ;
}

if(2==number)
{ //算出乘法或除法,更新p0 重新循环
a1=atof(p1);
a2=atof(p2);
if(haveride)
a1*=a2;
else
{
try
{
a1/=a2;
}catch(...){}
}
memset(p1,0,sizeof(p1));
memset(p2,0,sizeof(p2));
memset(p3,0,sizeof(p3));
if(firstdata!=0)
memcpy(p1,p0,firstdata) ;
sprintf(p2,"%-12.2f",a1);
memcpy(p3,p0+i,strlen(p0)-i);
pstr1=p1;
pstr2=p2;
pstr3=p3;
if(firstdata==0)
pstr0 = pstr2+pstr3;
else
pstr0 = pstr1+pstr2+pstr3;
if(i==strlen(p0))
{
memset(p0,0,sizeof(p0));
sprintf(p0,"%s",pstr0.Trim().c_str());
break ;
}
memset(p1,0,sizeof(p1));
memset(p2,0,sizeof(p2));
memset(p3,0,sizeof(p3));
memset(p0,0,sizeof(p0));
sprintf(p0,"%s",pstr0.Trim().c_str());
i=-1;
firstleft=0;
firstdata=0;
number=0;
haveride=false;
havediv =false;
}
}
//*************//////////// send

//+++++++++++++-------------- start
//对于+-运算
//程序运行到这步全是+-运算,
firstleft=0; //第一个+/的位置
number=0; //出现的个数
bool haveadd=false;
bool havesub=false;

memset(p1,0,sizeof(p1));
memset(p2,0,sizeof(p2));
memset(p3,0,sizeof(p3));

for(i=0;i<=strlen(p0);i++)
{
if('+'==p0[i] )
{
if(number==0)
{
haveadd=true;
firstleft=i;
}
number++ ;

if(1==number)
memcpy(p1,p0,firstleft);
else
memcpy(p2,p0+firstleft+1,i-firstleft-1);
}
else if('-'==p0[i] && i!=0)
{
if(number==0)
{
firstleft=i ;
havesub=true;
}
number++;

if(1==number)
memcpy(p1,p0,firstleft);
else
memcpy(p2,p0+firstleft+1,i-firstleft-1);
}
if(i==strlen(p0))
{
if(number==0)
{
pstr0=p0;
return pstr0.Trim();
}
else
{
memcpy(p2,p0+firstleft+1,i-firstleft-1);
number++ ;
}
}

if(number>1)
{//计算并更新p0
a1=atof(p1);
a2=atof(p2);
if(haveadd)
a1+=a2;
else
a1-=a2;
memset(p1,0,sizeof(p1));
sprintf(p1,"%12.2f",a1);
if(i==strlen(p0))
{
pstr0=p1;
return pstr0.Trim();
}
memset(p2,0,sizeof(p2));
memcpy(p2,p0+i,strlen(p0)-3);
pstr1=p1;
pstr2=p2;
pstr0= pstr1+pstr2;

memset(p1,0,sizeof(p1));
memset(p2,0,sizeof(p2));
memset(p3,0,sizeof(p3));
memset(p0,0,sizeof(p0));
sprintf(p0,"%s",pstr0.Trim().c_str());
i=-1;
firstleft=0;
number=0;
haveadd=false;
havesub=false;
}
}
//+++++++++++++-------------- end

return pstr0.Trim();
}
lidawen 2004-08-17
  • 打赏
  • 举报
回复
上面函數是針對計算金額來設計的(保留2位小數),你可以根據自己的情況稍作修改即可.
lidawen 2004-08-17
  • 打赏
  • 举报
回复
String __fastcall TfrmQuery::CalculateFromStr(String str)
{ //计算简单的算术式(该函数只能计算含有"("、")"、"*"、"/"、"+"、"-"的表达式)
String pstr0="";
if(str.Length()<=0)
return pstr0;
//先括号,*/,+-
int i=0;
// pstr0=str;
char p0[300];
char p1[200];
String pstr1;
char p2[200];
String pstr2;
char p3[200];
String pstr3;

float a1=0;
float a2=0;

int left=0; //左括号的个数
bool haveleft=false;
int firstleft=0; //第一(的位置
int tofirstright=0; //对应第一个(的)的位置

//// (((((((())))))))))) 1.括号 start
bool flag =false ;
bool change = false;
memset(p0,0,sizeof(p0));
sprintf(p0,"%s",str.c_str()) ;
memset(p1,0,sizeof(p1));
memset(p2,0,sizeof(p2));
memset(p3,0,sizeof(p3));
for(i=0;i<strlen(p0);i++)
{
if(p0[i]=='(')
{
left++ ;
haveleft = true ;
if(1==left)
firstleft=i ;
}
else if(p0[i]==')')
{
left-- ;
if(0==left)
tofirstright=i;
}

if(0==left && haveleft)
{
flag=true ;
memcpy(p1,p0,firstleft);
memcpy(p2,p0+firstleft+1,i-firstleft-1);
if((i+1)==strlen(p0))
memset(p3,0,sizeof(p3));
else
memcpy(p3,p0+i+1,strlen(p0)-(i+1));
}

if(flag)
{
if(firstleft==0)
pstr0 =CalculateFromStr(p2)+p3;
else
pstr0 =p1+ CalculateFromStr(p2)+p3 ;

flag = false ;
//重新循环+p3

memset(p0,0,sizeof(p0));
sprintf(p0,"%s",pstr0.Trim().c_str());
i=-1;
firstleft=0;
left=0;
memset(p1,0,sizeof(p1));
memset(p2,0,sizeof(p2));
memset(p3,0,sizeof(p3));
}
}
//// (((((((())))))))))) end

//*************//////////// start
//运算*/
firstleft=0; //第一个*/的位置
int firstdata=0; //第一乘数或除数的位置
int number=0;
bool haveride=false;
bool havediv =false;
memset(p1,0,sizeof(p1)); // 第一个乘数或除数
memset(p2,0,sizeof(p2)); //
memset(p3,0,sizeof(p3));

for(i=0;i<=strlen(p0);i++)
{
if('*'==p0[i] )
{
if(number==0)
{
haveride=true;
firstleft=i;
}
number++ ;

if(1==number)
memcpy(p1,p0+firstdata,i-firstdata);
else
memcpy(p2,p0+firstleft+1,i-(firstleft+1));
}
else if('/'==p0[i] )
{
if(number==0)
{
havediv=true;
firstleft=i ;
}
number++;

if(1==number)
memcpy(p1,p0+firstdata,i-firstdata);
else
memcpy(p2,p0+firstleft+1,i-(firstleft+1));
}
else if('-'==p0[i] || '+'==p0[i] || i==strlen(p0))
{
if(1==number)
{
memcpy(p2,p0+firstleft+1,i-(firstleft+1));
number++ ;
}
if(0==number)
firstdata = i+1 ;
}

if(2==number)
{ //算出乘法或除法,更新p0 重新循环
a1=atof(p1);
a2=atof(p2);
if(haveride)
a1*=a2;
else
{
try
{
a1/=a2;
}catch(...){}
}
memset(p1,0,sizeof(p1));
memset(p2,0,sizeof(p2));
memset(p3,0,sizeof(p3));
if(firstdata!=0)
memcpy(p1,p0,firstdata) ;
sprintf(p2,"%-12.2f",a1);
memcpy(p3,p0+i,strlen(p0)-i);
pstr1=p1;
pstr2=p2;
pstr3=p3;
if(firstdata==0)
pstr0 = pstr2+pstr3;
else
pstr0 = pstr1+pstr2+pstr3;
if(i==strlen(p0))
{
memset(p0,0,sizeof(p0));
sprintf(p0,"%s",pstr0.Trim().c_str());
break ;
}
memset(p1,0,sizeof(p1));
memset(p2,0,sizeof(p2));
memset(p3,0,sizeof(p3));
memset(p0,0,sizeof(p0));
sprintf(p0,"%s",pstr0.Trim().c_str());
i=-1;
firstleft=0;
firstdata=0;
number=0;
haveride=false;
havediv =false;
}
}
//*************//////////// send

//+++++++++++++-------------- start
//对于+-运算
//程序运行到这步全是+-运算,
firstleft=0; //第一个+/的位置
number=0; //出现的个数
bool haveadd=false;
bool havesub=false;

memset(p1,0,sizeof(p1));
memset(p2,0,sizeof(p2));
memset(p3,0,sizeof(p3));

for(i=0;i<=strlen(p0);i++)
{
if('+'==p0[i] )
{
if(number==0)
{
haveadd=true;
firstleft=i;
}
number++ ;

if(1==number)
memcpy(p1,p0,firstleft);
else
memcpy(p2,p0+firstleft+1,i-firstleft-1);
}
else if('-'==p0[i] && i!=0)
{
if(number==0)
{
firstleft=i ;
havesub=true;
}
number++;

if(1==number)
memcpy(p1,p0,firstleft);
else
memcpy(p2,p0+firstleft+1,i-firstleft-1);
}
if(i==strlen(p0))
{
if(number==0)
return p0;
else
{
memcpy(p2,p0+firstleft+1,i-firstleft-1);
number++ ;
}
}

if(number>1)
{//计算并更新p0
a1=atof(p1);
a2=atof(p2);
if(haveadd)
a1+=a2;
else
a1-=a2;
memset(p1,0,sizeof(p1));
sprintf(p1,"%12.2f",a1);
if(i==strlen(p0))
return p1;
memset(p2,0,sizeof(p2));
memcpy(p2,p0+i,strlen(p0)-3);
pstr1=p1;
pstr2=p2;
pstr0= pstr1+pstr2;

memset(p1,0,sizeof(p1));
memset(p2,0,sizeof(p2));
memset(p3,0,sizeof(p3));
memset(p0,0,sizeof(p0));
sprintf(p0,"%s",pstr0.Trim().c_str());
i=-1;
firstleft=0;
number=0;
haveadd=false;
havesub=false;
}
}
//+++++++++++++-------------- end

return pstr0;
}
qiuafa 2004-08-17
  • 打赏
  • 举报
回复

难人的问题呀,就是多。
befree 2004-08-17
  • 打赏
  • 举报
回复
问题不清
constantine 2004-08-17
  • 打赏
  • 举报
回复
还要就看数据结构了,里面抄就行了,早就跟你说了,你也不听,这年头,哎
djchao 2004-08-17
  • 打赏
  • 举报
回复
数据结构的书,就有例子啦。
HWHuang 2004-08-14
  • 打赏
  • 举报
回复
关注一下!!
Maconel 2004-08-14
  • 打赏
  • 举报
回复
记得前一段给谁回答了这么一个问题,还写了代码的,可以去搜一下,不过俺的代码很简陋,也不全面,需要再加工。
shuilong 2004-08-13
  • 打赏
  • 举报
回复
还有别的吗
magicsnake 2004-08-07
  • 打赏
  • 举报
回复
建议看编译原理
庄鱼 2004-08-07
  • 打赏
  • 举报
回复
晕!函数会自动变成寒暑的
庄鱼 2004-08-07
  • 打赏
  • 举报
回复
可以自己做一个函数解析程序:但是会比较麻烦
首先你的准备几个函数:一个是词法分割寒暑,用来将数字与操作幅分割开来,另一个是堆栈仿真寒暑,用来将数字与操作符按数组的形式进行压栈处理,再有一个就是运算寒暑,通过case语句进行分支计算,大体思想就是这样,你可以先做做,不行的话再拿出来讨论。
shuilong 2004-08-07
  • 打赏
  • 举报
回复
我不和数据库相连,也不是用三个EDIT,
我只得是一个EDIT->TEXT如何转化。
constantine 2004-08-07
  • 打赏
  • 举报
回复
#include"conio.h"
#include "stdio.h"
#include "stdlib.h"
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef char SElemType;
typedef int Status;
#define OK 1
#define OVERFLOW 0
#define ERROR 0
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;

Status InitStack(SqStack &s){//构造一个空栈
s.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!s.base)exit(OVERFLOW);
s.top=s.base;
s.stacksize=STACK_INIT_SIZE;
return OK;
}//InitStack

SElemType Getop(SqStack s){//若栈不空,则返回用e返回s栈元素
SElemType e;
if(s.top==s.base)return ERROR;
e=*(s.top-1);
return e;
}//Getop

Status Push(SqStack &s,SElemType e){//插入元素e为新的栈顶元素
if(s.top-s.base>=s.stacksize){//栈满,追加存储空间
s.base=(SElemType *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!s.base)exit(OVERFLOW);//存储分配失败
s.top=s.base+s.stacksize;
s.stacksize+=STACKINCREMENT;
}
*s.top++=e;
return OK;
}//Push

Status Pop(SqStack &s,SElemType &e){
//若栈不空,则删除s的栈顶元素,用e 返回其值,并
//返回OK,否则返回ERROR
if(s.top==s.base)return ERROR;
e=*--s.top;
return OK;
}//Pop

char Precede(char e,char c){//比较运算任符的优先权
if(e=='+')
{ if(c=='+'||c=='-'||c==')'||c=='#')
return '>';
return '<';
}
else if(e=='-')
{
if(c=='+'||c=='-'||c==')'||c=='#')
return '>';
return '<';
}
else if(e=='*')
{
if(c=='(')
return '<';
return '>';
}
else if(e=='/')
{
if(c=='(')
return '<';
return '>';
}
else if(e=='(')
{
if(c==')')
return '=';
else if(c=='+'||c=='-'||c=='*'||c=='/'||c=='(')
return '<';
}
else if(e==')')
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c==')'||c=='#')
return '>';
}
else if(e=='#')
{ if(c=='#')
return '=';
else if(c=='+'||c=='-'||c=='*'||c=='/'||c=='(')
return '<';
}
return 0;
}

int Operate(char b,char theta,char a) {//运算
int temp;
// b-=48;a-=48;
if(theta=='+')
temp =b+a;
else if(theta=='*')
temp=b * a;
else if(theta=='-')
temp=b-a;
else if(theta=='/')
temp=b/a;
return temp;
}

char OP[]={'+','-','*','/','(',')','#'};
int In(char c,char OP[])//比较是否为运算符
{ int i;
for(i=0;i<=6;i++)
if(c==OP[i])
return 1;
return 0;
}

char EvluateExpression(){
//算术表达式求值的算符优先算法.设OPTR和OPND分别为运算栈和运算数栈,
//OP为运算任集合
SqStack OPTR,OPND;char a,b,c,x,theta;
InitStack(OPTR); Push(OPTR,'#');
InitStack(OPND);c=getchar();
while(c!='#'||Getop(OPTR)!='#'){
if(!In(c,OP)){Push(OPND,c-48);c=getchar();}//不是运算符则进栈
else
switch(Precede(Getop(OPTR),c)){
case '<'://栈顶元素优先权低
Push(OPTR,c);c=getchar();break;
case '='://脱括号并接收下一字符
Pop(OPTR,x);c=getchar();break;
case '>'://退栈并将运算结果入栈
Pop(OPTR,theta);
Pop(OPND,b);Pop(OPND,a);
Push(OPND,Operate(a,theta,b));
break;
}//switch
}//while
return Getop(OPND);
}//EvluateExpression

void main()
{ char temp;
temp=EvluateExpression();
printf("%d\n",temp);
return;
}

这个程序你参考一下
加载更多回复(8)

604

社区成员

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

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