#include "stdafx.h"
#include <conio.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
typedef struct stack_trungto
{ char kt;
struct stack_trungto *tiep;
} tt;
typedef struct list_hauto
{ char kt[10];
double bien;
struct list_hauto *lui;
struct list_hauto *tiep;
} ht;
typedef struct stack_giatribien
{ char tenbien[100];
double gtr;
struct stack_giatribien *tiep;
}gtb;
//////////////////////////////////////////////////////////////////////////
const double PI
=acos(-1); typedef char xau[100];
typedef char xau1[256];
tt *dau1=NULL;
ht *dau2=NULL;
gtb *dau3=NULL;
int i,j,n,m;
bool stop=true;
//////////////////////////////////////////////////////////////////////////
//Cac ham phuc vu viec tinh bieu thuc.
void pushtt(char x);
void pushht(xau x,double var);
char pop();
char lay();
int dut(char x);
void dsbien(xau tenbien,double giatri);
int ktkt(char x);
int ktbien(xau x,gtb **vt);
int ktra(xau x);
int ktbieuthuc(xau1 x);
double match(ht *dau);
void tinhbieuthuc();
double giaithua(double x);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// CAC HAM DUNG DE PHAN TICH VA TINH BIEU THUC TOAN HOC
//////////////////////////////////////////////////////////////////////////
// ham dua gia tri vao stack trung to.
void pushtt(char x)
{ tt * moi;
moi->kt=x;
moi->tiep=dau1;
dau1=moi;
};
//////////////////////////////////////////////////////////////////////////
// ham dua gia tri vao list hau to.
void pushht(xau x,double var)
{ ht *moi;
if(dau2==NULL)
{ moi
=(ht
*)malloc(sizeof(ht
)); moi->bien=var;
moi->tiep=NULL;
moi->lui =NULL;
dau2=moi;
}
else
{ moi=dau2;
while(moi->tiep!=NULL) moi=moi->tiep;
moi
->tiep
=(ht
*)malloc(sizeof(ht
)); moi->tiep->lui=moi;
moi=moi->tiep;
moi->tiep=NULL;
moi->bien=var;
};
};
//////////////////////////////////////////////////////////////////////////
// ham lay gia tri khoi stack trung to.
char pop()
{ tt *moi;
char k;
moi=dau1;
dau1=dau1->tiep;
k=moi->kt;
return k;
};
//////////////////////////////////////////////////////////////////////////
// lay gia tri dau tien cua stack trung to ra sanh.
char lay()
{ char k;
k=dau1->kt;
return k;
};
//////////////////////////////////////////////////////////////////////////
// ham xet do uu tien cua toan hang.
int dut(char x)
{ char k;
k=x;
if((k=='+')||(k=='-')||(k==')')) return 1;
else if((k=='*')||(k=='/')||(k=='^')) return 2;
else if(k=='(') return 3;
else return 0;
};
//////////////////////////////////////////////////////////////////////////
// dua bien vao danh sach bien.
void dsbien(xau tenbien,double giatri)
{ gtb *moi;
moi
=(gtb
*)malloc(sizeof(gtb
)); moi->gtr=giatri;
if(dau3==NULL)
{ moi->tiep=NULL;
dau3=moi;
}
else
{ moi->tiep=dau3;
dau3=moi;
};
};
//////////////////////////////////////////////////////////////////////////
// ham kiem tra xem bien nhap vao co hop le hay khong?
int ktbien(xau x,gtb **vt)
{ gtb *pp;
int k;
k=0;
if(dau3==NULL) k=0;
else
{ pp=dau3;
while(pp!=NULL)
{ if(strcmp(pp
->tenbien
,x
)==0) { k=1;
*vt=pp;
}
pp=pp->tiep;
};
};
return k;
};
//////////////////////////////////////////////////////////////////////////
//ham kiem tra ki tu.
int ktkt(char x)
{ int d;
d=x;
if(((d>=65)&&(d<=90))||((d>=97)&&(d<=122))||((d>=48)&&(d<=57))||(d==46)) return 1;
else if((d==33)||(d==37)||((d>=40)&&(d<=43))||((d==45)||(d==47))||(d==94)||(d==32)||(d==61)) return 2;
else return 0;
};
//////////////////////////////////////////////////////////////////////////
// ham kiem tra bieu thuc nhap vao co hop le hay khong?
int ktbieuthuc(xau1 x)
{ int k,m,i,l,j,d,t,y,b,h,v,z,p;
xau tg;
k=0;l=0;i=0;b=0;z=0;
while((i<=m-1)&&(l>=0))
{
if(ktkt(x[i])==0) return 0;
while((x[i]==' ')&&(i<=m-1)) i=i+1;
if((ktkt(x[i])==2)&&(x[i]!='(')&&(x[i]!=')'))
{
for(k=0;k<=m-1;k++) if(ktkt(x[k])==1) z=1;
if(z==0) return 0;
k=0;
while((ktkt(x[i])==2)&&(i<=m-1)&&(x[i]!='(')||(x[i]=='.'))
{ if(ktkt(x[i])==0) return 0;
tg[k]=x[i];
k=k+1;
i=i+1;
}; tg[k]='\0';
if(k>1) return 0;
if((k==1)&&(tg[0]!='+')&&(tg[0]!='-')&&(tg[0]=='.')) return 0;
};
if(x[i]=='(')
{ l=l+1;
j=i+1;
while((x[j]==' ')&&(j<=m-1)) j=j+1;
if(x[j]==')') return 0;
if(x[j]=='.') return 0;
if(j==m) return 0;
if(ktkt(x[j])==2)
{
if(j==m-1) return 0;
k=0;
while((j<=m-1)&&(ktkt(x[j])==2)&&(x[j]!='(')&&(x[j]!=')')||(x[j]=='.'))
{
if(ktkt(x[j])==0)return 0;
if(x[j]=='.') return 0;
tg[k]=x[j];
k=k+1;
j=j+1;
}; tg[k]='\0';
while((x[j]==' ')&&(j<=m-1)) j=j+1;
if(j==m) return 0;
if(k>1) return 0;
if((tg[0]!='+')&&(tg[0]!='-')&&(k!=0)) return 0;
};
i=j;
};
if(x[i]==')')
{ l=l-1;
j=i+1;
while((x[j]==' ')&&(j<=m-1)) j=j+1;
if((ktkt(x[j])==1)||(x[j]=='(')) return 0;
else if(x[j]!=')')
{ k=0;
if((j==m-1)&&(x[j]!='!')) return 0;
while((ktkt(x[j])==2)&&(j<=m-1)&&(x[j]!='(')&&(x[j]!=')')||(x[j]=='.'))
{
if(ktkt(x[j])==0) return 0;
tg[k]=x[j];
k=k+1;
j=j+1;
}; tg[k]='\0';
while((x[j]==' ')&&(j<=m-1)) j=j+1;
if((j==m)&&(k!=0)&&(tg[0]!='!')) return 0;
if(k>3) return 0;
else
{
if(k==2)
{ if(tg[1]=='!') return 0;
if((tg[1]!='+')&&(tg[1]!='-')) return 0;
};
if(k==3)
{ if(tg[0]!='!') return 0;
else if((tg[1]=='!')||((tg[2]!='+')&&(tg[2]!='-'))) return 0;
else return 0;
};
};
};
i=j;
};
if(ktkt(x[i])==1)
{
j=i-1;
k=0;
while((ktkt(x[i])==1)&&(i<=m-1)||(x[i]=='.'))
{ tg[k]=x[i];
k=k+1;
i=i+1;
};
tg[k]='\0';
if((strcmp(tg
,"sin")==0)||(strcmp(tg
,"cos")==0)||(strcmp(tg
,"tan")==0)||(strcmp(tg
,"acsin")==0)||(strcmp(tg
,"accos")==0)||(strcmp(tg
,"actan")==0)||(strcmp(tg
,"sqrt")==0)||(strcmp(tg
,"ln")==0)||(strcmp(tg
,"lg")==0)||(strcmp(tg
,"exp")==0)||(strcmp(tg
,"abs")==0)) { b=b+1;
while((x[i]==' ')&&(i<=m-1)) i=i+1;
if(ktkt(x[i])==0) return 0;
if(i==m) return 0;
if(x[i]=='.') return 0;
if((ktkt(x[i])==2)&&(x[i]!='+')&&(x[i]!='-')&&(x[i]!='(')) return 0;
}
else
{
while(k<=v-1)
{ if((isdigit(tg
[k
])!=0)||(tg
[k
]=='.')) { if(tg[k]=='.') h=h+1;
k=k+1;
}
else break;
};
if((h==1)&&(x[i-1]=='.')&&( (x[i]=='(')||(x[i]==')')||(ktkt(x[i])==2)||(i==m))) return 0;
if(h>1) return 0;
k=0; h=0;
for(k=0;k<=m-1;k++) if(tg[k]=='.') h=h+1;
if(h!=0) return 0;
b=b+1;
p=0;
while((x[i]==' ')&&(i<=m-1)) { i=i+1; p=p+1;};
y=0;
while((x[i]=='.')||((ktkt(x[i])!=1)&&(i<=m-1)&&(x[i]!='(')&&(x[i]!=')')))
{
if(x[i]!=' ')
{ if(ktkt(x[i])==0) return 0;
if(x[i]=='.') return 0;
if((x[i]=='=')&&((b>1)||(y!=0))) return 0;
tg[y]=x[i];
y=y+1;
};
i=i+1;
};
if(x[i]=='.') return 0;
tg[y]='\0';
if((p!=0)&&(y==0)&&(x[i]!=')')&&(i!=m) )return 0;
if(y>4) return 0;
if((y<=4)&&(y!=0))
{
if((tg
[0]=='=')&&(strlen(tg
)>1)) else if((tg[1]!='+')&&(tg[1]!='-')) return 0;
};
if(tg[0]=='!')
{ if(y>3) return 0;
if((y==2)&&(tg[1]=='!')) return 0;
if((y==3)&&(tg[2]!='+')&&(tg[2]!='-')||(tg[1]=='!')) return 0;
};
if((tg[0]!='!')&&(y==1)&&((x[i]==')')||(i==m))) return 0;
if(((i==m)||(x[i]==')'))&&(ktkt(x[i])!=1)&&(y>=2))
{ if(y>2) return 0;
if((tg[0]!='+')&&(tg[0]!='-')) return 0;
if(((tg[0]=='+')||(tg[0]=='-'))&&(tg[1]!=tg[0])) return 0;
};
if(((ktkt(x[i])==1)||(x[i]=='('))&&(y>1))
{ if((tg[0]=='*')||(tg[0]=='/')||(tg[0]=='^'))
{ if(y>2) return 0;
else if((ktkt(tg[1])==2)&&(tg[1]!='+')&&(tg[1]!='-')) return 0;
};
if(tg[0]=='+')
{ if((tg[1]=='-')&&(y>2)) return 0;
if((tg[1]=='+')&&(d>2))
{
if((d==4)&&(tg[3]!='+')&&(tg[3]!='-')) return 0;
}
else
{
for(t=1;t<=d-1;t++)
if((tg[t]!='+')&&(tg[t]!='-')) return 0;
};
};
if(tg[0]=='-')
{
if((tg[1]=='+')&&(y>2)) return 0;
if((tg[1]=='-')&&(d>2))
{
if((d==4)&&(tg[3]!='+')&&(tg[3]!='-')) return 0;
}
else
{
for(t=1;t<=d-1;t++)
if((tg[t]!='+')&&(tg[t]!='-')) return 0;
};
};
};
};
};
};
};
if((l!=0)||(l<0)) return 0;
return 1;
};
//////////////////////////////////////////////////////////////////////////
// kiem tra xem xau X la ham hay toan hang ?
int ktra(xau x)
{
else if((strcmp(x
,"sin")==0)||(strcmp(x
,"cos")==0)||(strcmp(x
,"tan")==0)||(strcmp(x
,"acsin")==0)||(strcmp(x
,"accos")==0)||(strcmp(x
,"actan")==0)||(strcmp(x
,"ln")==0)||(strcmp(x
,"lg")==0)||(strcmp(x
,"sqrt")==0)||(strcmp(x
,"exp")==0)||(strcmp(x
,"!")==0)) return 2; else return 0;
};
//////////////////////////////////////////////////////////////////////////
// ham tinh giai thua .
double giaithua(double x)
{double y,t;
if(x==0) return 1;
t=0;y=1;
while(t<x)
{ t=t+1;
y=y*t;
};
return y;
};
//////////////////////////////////////////////////////////////////////////
// ham phan tich bieu thuc
void tinhbieuthuc()
{ tt *p;
ht *p1,*truocp;
gtb *vt;
bool g,pi;
char gan[100],tg[100],bt[256];
int l,j,k,t,s;
double var,c;
{
i=0;s=1;
if(ktbieuthuc
(bt
)==0) printf("\n bieu thuc toan hoc nhap sai !"); { m=0; g=false;
while(i<=n-1)
{
while((bt[i]==' ')&&(i<=n-1)) i=i+1;
if(ktkt(bt[i])==1)
{ l=0;
while(ktkt(bt[i])==1)
{ tg[l]=bt[i];
l=l+1;
i=i+1;
}; tg[l]='\0';
while((bt[i]==' ')&&(i<=n-1)) i=i+1;
// kiem tra xem co phai la ham khong.
{ pushtt(' ');
while(l>0)
{ l=l-1;
pushtt(tg[l]);
};
m=m+1;
}
{ pushtt(' ');
while(l>0)
{ l=l-1;
pushtt(tg[l]);
};
m=m+1;
}
{ pushtt(' ');
while(l>0)
{ l=l-1;
pushtt(tg[l]);
};
m=m+1;
}
{ pushtt(' ');
while(l>0)
{ l=l-1;
pushtt(tg[l]);
};
m=m+1;
}
{ pushtt(' ');
while(l>0)
{ l=l-1;
pushtt(tg[l]);
};
m=m+1;
}
{ pushtt(' ');
while(l>0)
{ l=l-1;
pushtt(tg[l]);
};
m=m+1;
}
else if(strcmp(tg
,"accos")==0) { pushtt(' ');
while(l>0)
{ l=l-1;
pushtt(tg[l]);
};
m=m+1;
}
else if(strcmp(tg
,"acsin")==0) { pushtt(' ');
while(l>0)
{ l=l-1;
pushtt(tg[l]);
};
m=m+1;
}
else if(strcmp(tg
,"actan")==0) { pushtt(' ');
while(l>0)
{ l=l-1;
pushtt(tg[l]);
};
m=m+1;
}
{ pushtt(' ');
while(l>0)
{ l=l-1;
pushtt(tg[l]);
};
m=m+1;
}
{ pushtt(' ');
while(l>0)
{ l=l-1;
pushtt(tg[l]);
};
m=m+1;
}
else
{ // dua bien vao day hau to.
// kiem tra xem neu la so thi dua luon vao hau to.
{ pushht("0",PI);
m++;
}
while(l<=t-1)
{ if((isdigit(tg
[l
])!=0)||(tg
[l
]=='.')) l
=l
+1; else
{ k=1;
break;
};
};
if(k==0)
{ while((bt[i]==' ')&&(i<=n-1)) i=i+1;
if(bt[i]=='=')
{ printf("\n hang so khong duoc gan"); s=0;
break;
}
k=0;j=i;
while((ktkt(bt[j])==2)&&(j<=n-1)&&(bt[j]!='(')&&(bt[j]!=')'))
{ if(k==3) i=j-1;
if(bt[j]!=' ')
{ tg[k]=bt[j];
k=k+1;
};
j=j+1;
};tg[k]='\0';
// Kiem tra toan tu tang giam ++ ,--
if(k>2)
{ printf("\n khong duoc thay doi gia tri hang so"); s=0;
break;
};
while((j<=n-1)&&(bt[j]==' ')) j=j+1;
if((k==2)&&((bt[j]==')')||(j==n)))
{ i=j;
printf("\n khong duoc thay doi gia tri hang so"); s=0;
break;
};
pushht("0",var);
m=m+1;
}
else
{
while((bt[i]==' ')&&(i<=n-1)) i=i+1;
if(bt[i]=='=') // xu ly voi toan tu gan .
{
s=0;
break;
}
else
{ i=i+1;
g=true;
}
}
else
{ // Kiem tra bien nhap vao co trong danh sach bien hay khong,neu co thi dua gia tri vao day hau to.
if((ktbien
(tg
,&vt
)!=0)||(strcmp(tg
,"PI")==0)) { k=0;j=i;
if(strcmp(tg
,"PI")==0) pi
=false
; else pi=true;
while((ktkt(bt[j])==2)&&(j<=n-1)&&(bt[j]!='(')&&(bt[j]!=')'))
{ if(k==3) i=j-1;
if(bt[j]!=' ')
{ tg[k]=bt[j];
k=k+1;
};
j=j+1;
};tg[k]='\0';
if(pi==true)var=vt->gtr;
// Kiem tra toan tu tang giam ++ ,--
if(k>2)
{ if(pi==false)
s=0;
break;
}
if((tg[0]=='+')&&(tg[1]=='+')) var=var+1;
if((tg[0]=='-')&&(tg[1]=='-')) var=var-1;
};
while((i<=n-1)&&(bt[i]==' ')) i=i+1;
if((k==2)&&((bt[j]==')')||(j==n)))
{ if(pi==false)
s=0;
break;
}
i=j;
if(tg[0]=='+') var=var+1;
if(tg[0]=='-') var=var-1;
if(pi==true) vt->gtr=var;
};
if(pi==true)pushht("0",var);
if(pi==true) m=m+1;
}
else
{ printf("\n bien chua khai bao"); s=0;
break;
};
}
};
// xu ly toan hang mot ngoi (vd sin -a).
if((dau1!=NULL)&&((lay()=='/')||(lay()=='*')))
{ p=dau1->tiep;
if((p!=NULL)&&(ktkt(p->kt)==1))
{ tg[0]=pop();
tg[1]='\0';
pushht(tg,1);
};
};
// kiem tra neu co ham trong day trung to thi dua vao.
while((dau1!=NULL)&&(ktkt(lay())==1))
{ l=0;
while(lay()!=' ')
{ tg[l]=pop();
l=l+1;
};
tg[l]='\0';
pushht(tg,1);
if(lay()==' ') dau1=dau1->tiep;
};
};
}
else
{
// xu ly voi phep tinh giai thua.
if(bt[i]=='!')
{ p1=dau2;
while(p1!=NULL)
{truocp=p1;
p1=p1->tiep;
}
if(truocp->lui!=NULL)
if(((strcmp(truocp
->lui
->kt
,"*")==0)&&(truocp
->lui
->lui
->bien
==-1))||(truocp
->lui
->bien
==-1)) {printf("\n loi sai gia tri"); s=0;
break;
}
pushht("!",1);
i=i+1;
m=m+1;
};
// kiem tra xem toan hang co phai la toan hang mot ngoi khong
if((bt[i]=='-')||(bt[i]=='+'))
{
if(i==0) j=i;
if((i>0)&&(bt[i]!=')')&&(bt[i])!='(') j=i-1;
if((i<n-1)&&(bt[i]!='(')&&(bt[i]!=')')) k=i+1;
while((bt[j]==' ')&&(j>=0)) j=j-1;
while((bt[k]==' ')&&(k<=n-1)) k=k+1;
// xu ly toan hang mot ngoi dang a*-b...
if((bt[j]=='*')||(bt[j]=='/'))
{ if(bt[i]=='-')
{pushht("0",-1);
m=m+1;
}
else
{pushht("0",1);
m=m+1;
};
// dua toan hang * hoac / vao hau to.
tg[0]=bt[j];
tg[1]='\0';
pushht(tg,1);
i=i+1;
};
// xu ly toan hang mot ngoi dang a+-b,-(a+b...),sin -a...
if((j==-1)||(bt[j]=='=')||(bt[j]=='+')||(bt[j]=='-')||(bt[j]=='(')||(bt[j]=='^')||((dau1!=NULL)&&(ktkt(lay())==1)))
{ if(bt[i]=='-')
{pushht("0",-1);
m=m+1;
}
else
{pushht("0",1);
m=m+1;
};
pushtt('*');
i=i+1;
};
};
// truong gap toan hang dong ngoac tien hanh dua cac toan hang con lai trong day trung to den khi gap toan hanh '('.
if((bt[i]!=')')&&(ktkt(bt[i])!=1))
{ if((dau1!=NULL)&&(ktkt(lay())==2)&&(dut(bt[i])<=dut(lay()))&&(lay()!='('))
{ tg[0]=pop();
tg[1]='\0';
pushht(tg,1);
};
pushtt(bt[i]);
i=i+1;
};
if(bt[i]==')')
{ i=i+1;
while(lay()!='(')
{ tg[0]=pop();
tg[1]='\0';
pushht(tg,1);
};
if(dau1->tiep!=NULL) dau1=dau1->tiep;
// xu ly dang bieu thuc co dang -(a+b...)
if((lay()=='/')||(lay()=='*'))
{ p=dau1->tiep;
if((p!=NULL)&&(ktkt(p->kt)==1))
{ tg[0]=pop();
tg[1]='\0';
pushht(tg,1);
};
};
// kiem tra bieu thuc co thuoc ham hay khong ,neu co ham trong day trung to thi dua ham vao day hau to.
while((dau1!=NULL)&&(ktkt(lay())==1))
{ l=0;
while(lay()!=' ')
{ tg[l]=pop();
l=l+1;
};
tg[l]='\0';
pushht(tg,1);
if(lay()==' ') dau1=dau1->tiep;
}; if((dau1!=NULL)&&(lay()==' ')) dau1=dau1->tiep;
};
};
while((dau1!=NULL)&&(i>n-1))
{ tg[0]=pop();
tg[1]='\0';
pushht(tg,1);
};
};
};
// truong hop trong qua trinh xu ly phat hien bieu thuc bi sai ,sau do phai tien hanh giai phong day hau to va trung to
if(s==0)
{ p1=dau2;
while(p1!=NULL)
{ dau2=p1;
p1=p1->tiep;
};
p=dau1;
while(p!=NULL)
{ dau1=p;
p=p->tiep;
};
dau1=NULL;
dau2=NULL;
};
// tien hanh tinh toan voi day hau to duoc tao ra.Dung ket qua tinh duoc hoac de hien thi hoac de dung de giai pt va hpt
if((m!=0)&&(dau2!=NULL)&&(s!=0))
{ c=match(dau2);
if(stop==true)
// gan gia tri tim duoc cho bien muon gan
if(g==true)
{ if(ktbien(gan,&vt)==0)
{ var=c;
dsbien(gan,var); // truong bien chua co!
}
else vt->gtr=c; // truong hop bien da co trong danh sach.
};
}
else printf("\n loi sai gia tri!");
};
};
};
//////////////////////////////////////////////////////////////////////////
// ham tinh toan day hau to.
double match(ht * dau)
{ ht *p,*p1,*p2,*d=dau,*q1,*truocq;
tt *q2;
xau s;
int v1,v2,k;
double var,a,b,x;
stop= true;
k=1;
if(m==1) var=dau->bien;
p=dau;
while(m>1)
{ v1=0;
v2=0;
while((p!=NULL)&&(ktra(p->kt)==0)) p=p->tiep;
if((p!=NULL)&&(ktra(p->kt)==1))
p1=p->lui;
b=p1->bien;
p2=p1->lui;
a=p2->bien;
{ if(b!=0) var=a/b;
else
{ stop=false;
break;
};
};
p2->bien=var;
p2->tiep=p->tiep;
if(p->tiep!=NULL) p->tiep->lui=p2;
p=p2;
m=m-1;
};
if((p!=NULL)&&(ktra(p->kt)==2))
p1=p->lui;
a=p1->bien;
else
{ stop=false;
break;
};
};
else
{ stop=false;
break;
};
};
else
{ stop=false;
break;
};
};
else
{ stop=false;
break;
};
};
else
{ stop=false;
break;
};
};
{ if(a<0) var=-a;
else var=a;
};
{ x=1; q1=p;
while(q1!=NULL)
{ truocq=q1;
q1=q1->lui;
}
while((a>1)&&(x<a)) x++;
if((a<1)||(x>a)||(a>120))
{stop=false;
break;
}
else var=giaithua(a);
}
p1->bien=var;
p1->tiep=p->tiep;
if(p->tiep!=NULL) p->tiep->lui=p1;
p=p1;
m=m-1;
};
};
q1=dau2;
while(q1!=NULL)
{ dau2=q1;
q1=q1->tiep;
};
q2=dau1;
while(q2!=NULL)
{ dau1=q2;
q2=q2->tiep;
};
dau1=NULL;
dau2=NULL;
if(stop==true) return var;
else return 1;
};
main()
{
tinhbieuthuc();
getch();
return 0;
}