#include<conio.h>
#include<iostream.h>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<dos.h>
#include<stdlib.h>
// ___define
#define NumOperator 12
#define Left 10
#define Top 10
#define Row 8
#define Column 4
#define ColorFrame 10
#define ColorText 12
#define BackGround 9
#define WIDTH 5
#define HEIGHT 1
//// const
char* btnControl[8][4]={
{" Cos "," Tag ","Cotag","Log"},
{" Sin "," -> "," <- ","ESC"},
{" ! "," ( "," ) ","DEL"},
{"Mod %"," a/b ","^ x^y","CLR"},
{" 7 "," 8 "," 9 "," . "},
{" 4 "," 5 "," 6 "," / "},
{" 1 "," 2 "," 3 "," * "},
{" 0 "," - "," + "," = "},
};
char* listOperator[]={ "+", "-", "*", "/","^","%","!", "sin", "cos", "tag", "cotag","log" };
char* Error="";
//// enum
enum Boolean
{
false,true
};
/// methods
void DrawRect(int left,int top,int width,int height,int color)
{
textcolor(color);
gotoxy(left,top);
putch(218);
gotoxy(left,top+height+1);
putch(192);
gotoxy(left+width+1,top);
putch(191);
gotoxy(left+width+1,top+height+1);
putch(217);
for(int i=1;i<=width;i++)
{
gotoxy(left+i,top);
putch(196);
gotoxy(left+i,top+height+1);
putch(196);
}
for(int j=1;j<=height;j++)
{
gotoxy(left,top+j);
putch(179);
gotoxy(left+width+1,top+j);
putch(179);
}
}
void DrawString(char *str,int x,int y,int forecolor)
{
textcolor(forecolor);
gotoxy(x,y);
cprintf(str);
}
void DrawFloat(long float value,int x,int y,int forecolor)
{
textcolor(forecolor);
gotoxy(x,y);
cprintf("%lf",value);
}
void ShowHelp()
{
int left=Left+28,top=Top-5,color=BLUE;
DrawRect(left,top,20,20,CYAN);
DrawString("Press key !",left+5,top+1,YELLOW);
DrawString("Esc :ESC -> Exit",left+1,top+4,color);
DrawString("S,s :Sin",left+1,top+6,color);
DrawString("C,c :Cos",left+1,top+8,color);
DrawString("T,t :Tag",left+1,top+10,color);
DrawString("O,o :Cotag",left+1,top+12,color);
DrawString("L,l :Log",left+1,top+14,color);
DrawString("D,d :DEL",left+1,top+16,color);
DrawString("Space :CLR",left+1,top+18,color);
}
void DrawFrame()
{
// textbackground(4);
ShowHelp();
//textbackground(0);
DrawRect(Left-1,Top-8,Column*6+2,Row*4-1,RED);
DrawString("My Calculator !",Left+6,Top-7,14);
DrawRect(Left,Top-6,Column*6,1,ColorFrame);
DrawRect(Left,Top-3,Column*6,1,ColorFrame);
textbackground(BackGround);
int width=5,height=1;
for(int i=0;i<Row;i++)
for(int j=0;j<Column;j++)
{
if(j==Column-1)
DrawRect(Left+j*(width+2),Top+i*(height+2),width-2,height,ColorFrame);
else
DrawRect(Left+j*(width+2),Top+i*(height+2),width,height,ColorFrame);
DrawString(btnControl[i][j],Left+j*(width+2)+1,Top+i*(height+2)+1,ColorText);
}
gotoxy(Left+1,Top-5);
//DrawString(btnControl[0][0],Left+1,Top+1,YELLOW);
}
Boolean IsOperator(char *str)
{
for (int i = 0; i < NumOperator; i++)
{
if(strcmpi(str,listOperator[i])==0)
return true;
}
return false;
}
int LevelOfOperator(char* str)
{
if(strcmpi(str,"+")==0||strcmpi(str,"-")==0)
return 1;
if(strcmpi(str,"*")==0||strcmpi(str,"/")==0||strcmpi(str,"%")==0)
return 2;
if(strcmpi(str,"^")==0)
return 3;
if(strcmpi(str,"cos")==0||strcmpi(str,"sin")==0||strcmpi(str,"tag")==0||strcmpi(str,"cotag")==0||strcmpi(str,"log")==0)
return 4;
if(strcmpi(str,"!")==0)
return 5;
return 0;
}
Boolean IsNumber(char* str)
{
Boolean has=false;
for(int i
=0;i
<strlen(str
);i
++) {
if((str[i]<'0'||str[i]>'9')&&str[i]!='.')
{
return false;
}
if(str[i]=='.')
{
if(has==false)has=true;
else
if(has==true)return false;
}
}
return true;
}
//// Class
template<class Entry>
class Queue // xay dung hang doi
{
private:
struct Node
{
Entry data;
Node *next;
Node(Entry value)
{
data=value;
next=NULL;
}
};
Node *first,*last;
int count;
public:
Queue()
{
first=last=NULL;
count=0;
}
Entry DeQueue()
{
if(first==NULL)
return NULL;
Node *temp=first;
first=first->next;
count--;
return temp->data;
}
Boolean EnQueue(Entry item)
{
Node *temp=new Node(item);
if(temp)
{if(first==NULL)
{
first=last=temp;
}
else {
last->next=temp;
last=temp;
}
count++;
return true;
}
return false;
}
int Length()
{
return count;
}
};
class Node
{
private:
char* data;
Node *left,*right,*parent;
int level;
public:
Boolean Isoperator,Isnumber;
Node(char* value)
{
data=value;
left=right=parent=NULL;
Isoperator=IsOperator(value);
Isnumber=Isoperator==true?false:true;
if(Isoperator)
level=LevelOfOperator(data);
}
void setLeft(Node *value)
{
left=value;
value->setParent(this);
}
void setRight(Node *value)
{
right=value;
value->setParent(this);
}
void setParent(Node *value)
{
parent=value;
}
int Level()
{
return level;
}
Node* getLeft()
{
return left;
}
Node* getRight()
{
return right;
}
Node* getParent()
{
return parent;
}
char* getData()
{
return data;
}
};
class TreeExpression
{
private:
char* data;
Node *root;
Queue<char*>* getQueue(char* str)
{ Queue<char*> *lst=new Queue<char*>();
char *strtemp;
int count=0;
strtemp=NULL;
int threadNum=0,threadOpe=0;
for(int i
=0;i
<strlen(str
);i
++) {
if(str[i]=='('||str[i]==')')
{
if(threadOpe)
strtemp[threadOpe]='\0';
else if(threadNum)
strtemp[threadNum]='\0';
{
if(IsNumber(strtemp)||IsOperator(strtemp))
lst->EnQueue(strtemp);
else {Error
=strcat("No support ",strtemp
);} strtemp=NULL;
}
lst->EnQueue(str[i]==')'?")":"(");
threadOpe=threadNum=0;
}
else
{
if((str[i]>='0'&&str[i]<='9')||str[i]=='.')
{
if(threadNum)
{
strtemp[threadNum]=str[i];
threadNum++;
}
else {
if(threadOpe)
{
strtemp[threadOpe]='\0';
// cout<<endl<<strtemp;
if(IsOperator(strtemp)==true)
lst->EnQueue(strtemp);
else {
Error
=strcat("No support ",strtemp
); }
threadOpe=0;
}
strtemp=new char[10];
strtemp[threadNum]=str[i];
threadNum++;
}
}
else
{ if(threadOpe)
{
strtemp[threadOpe]='\0';
if(IsOperator(strtemp))
{
lst->EnQueue(strtemp);
threadOpe=0;
strtemp=new char[10];
}
strtemp[threadOpe]=str[i];
threadOpe++;
}
else {
if(threadNum)
{
strtemp[threadNum]='\0';
// cout<<endl<<strtemp;
lst->EnQueue(strtemp);
threadNum=0;
}
strtemp=new char[10];
strtemp[threadOpe]=str[i];
threadOpe++;
}
}
}
}
if(threadOpe)
{
strtemp[threadOpe]='\0';
lst->EnQueue(strtemp);
}
else if(threadNum)
{
strtemp[threadNum]='\0';
lst->EnQueue(strtemp);
}
return lst;
}
Node* CreateTree(Queue<char*> *lst)
{
Node *root=NULL,*current=NULL;
while(lst->Length()>0)
{
char *str=lst->DeQueue();
if(strcmpi(str,"(")==0)
{
Node *getNode = CreateTree(lst);
Node *dn = new Node("()");
dn->setRight(getNode);
if(root==NULL)
root = dn;
else current->setRight(dn);
current = dn;
}
else if(strcmpi(str,")")==0)
{
return root;
}
else {
Node* temp=new Node(str);
if(root==NULL)
root=temp;
else if(IsNumber(str)||strcmpi(str,"()")==0)
current->setRight(temp);
//else if(current->Isoperator==true&¤t->Level()<temp->Level())
// current->setRight(temp);
else {
// cout<<"parent cua "<<current->getData()<<" la :"<<current->getParent()->getData();
do{
if(current->Isoperator==true)
{
if(current->Level()<temp->Level())
{
temp->setLeft(current->getRight());
current->setRight(temp);
break;
}
}
if(current->getParent()==NULL)
{
temp->setLeft(current);
root=temp;
break;
}
current=current->getParent();
}while(current!=NULL);
}
current=temp;
}
}
return root;
}
/* long double ExpressionValue(Node *root)
{
if(root->getRight()==NULL&&root->getLeft()==NULL)
{
if(IsNumber(root->getData())==false)
{
Error="Error Syntax !";
return 0;
}
return _atold(root->getData());
}
long double a=NULL,b=NULL;
if(root->getLeft()!=NULL)
a=ExpressionValue(root->getLeft());
if(root->getRight()!=NULL)
b=ExpressionValue(root->getRight());
char *str=root->getData();
if(strcmpi(str,"sin")==0)
{
cout<<"\nco vao :"<<sin(b);
return (long double)sin(b);
}
return 20;
} */
long double ExpressionValue(Node *root)
{
if(root->getRight()==NULL&&root->getLeft()==NULL)
{
if(IsNumber(root->getData())==false)
{
Error="Error Syntax !";
return 0;
}
return _atold(root->getData());
}
long double a=NULL,b=NULL;
Boolean anull=false,bnull=false;
if(root->getLeft()!=NULL)
a=ExpressionValue(root->getLeft());
else anull=true;
if(root->getRight()!=NULL)
b=ExpressionValue(root->getRight());
else bnull=true;
char *str=root->getData();
return 0;
if(strcmpi(str,"()")==0)
return b;
if(strcmpi(str,"+")==0)
{
if(bnull)
Error="Syntax Error !";
return a+b;
}
if(strcmpi(str,"-")==0)
{
if(bnull)
Error="Syntax Error !";
return a-b;
}
if(strcmpi(str,"*")==0)
{
if(anull||bnull)
Error="Syntax Error !";
return a*b;
}
if(strcmpi(str,"/")==0)
{
if(anull||bnull)
{Error="Error Syntax !";
return 0;
}
if(b==0)
{Error="Khong the chia cho 0";
return 0;
}
return a/b;
}
if(strcmpi(str,"%")==0)
{
if(anull||bnull)
{Error="Syntax Error !";
return 0;
}
return (long)a%(long)b;
}
if(strcmpi(str,"^")==0)
{
if(anull||bnull)
{
Error="Syntax Error !";
return 0;
}
}
if(strcmpi(str,"cos")==0)
{
if(bnull)
Error="Syntax Error !";
}
if(strcmpi(str,"sin")==0)
{
if(bnull)
Error="Syntax Error !";
}
if(strcmpi(str,"tag")==0)
{
if(bnull)
{Error="Syntax Error !";
return 0;
}
{
Error="Khong the chia cho 0 !";
return 0;
}
}
if(strcmpi(str,"cotag")==0)
{
if(bnull)
{Error="Syntax Error !";
return 0;
}
{ Error="Khong the chia cho 0 !";
return 0;
}
return (long double)cos(b
)/sin(b
); }
if(strcmpi(str,"!")==0)
{
if(anull)
{
Error="Syntax Error !";
return 0;
}
return (long double) CalFactorial((long)a);
}
if(strcmpi(str,"log")==0)
{
if(bnull)
{
Error="Error Syntax !";
return 0;
}
return (long double)log(b
); }
else Error
=strcat("No Support ",str
); return 0;
}
int CalFactorial(int t)
{
int result = 1;
for (int i = 2; i <= t; i++)
{
result *= i;
}
return result;
}
public:
TreeExpression(char* expression)
{
data=expression;
}
long double Calculator()
{
Queue<char*> *lst=getQueue(data);
Node *root=CreateTree(lst);
return ExpressionValue(root);
//while(lst->Length())
//cout<<"\n"<<lst->DeQueue();
//cout<<"\n Nguyn thuy :"<<data;
//return 0;
}
};
char* InsertString(char* str,char* sub,int Index)
{
char *temp=new char[500];
for(int i=0;i<Index;i++)
temp[i]=str[i];
for(int j=0;j<l2;j++)
temp[j+Index]=sub[j];
for(int k=Index;k<l1;k++)
temp[k+l2]=str[k];
temp[l1+l2]='\0';
return temp;
}
void ShowKeyPress(int row,int column)
{
int x=wherex(),y=wherey();
textbackground(BackGround);
DrawString(btnControl[row][column],Left+column*(WIDTH+2)+1,Top+row*(HEIGHT+2)+1,YELLOW);
gotoxy(x,y);
delay(80);
DrawString(btnControl[row][column],Left+column*(WIDTH+2)+1,Top+row*(HEIGHT+2)+1,ColorText);
textbackground(0);
}
Boolean CompareTo(char *str,char *sub)
{
int j=0;
for(int i
=0;i
<strlen(str
);i
++) {
if(str[i]!=32)
{
if(str[i]!=sub[j])
return false;
j++;
}
}
return true;
return false;
}
void SearchKey(char* str)
{
for(int i=0;i<Row;i++)
for(int j=0;j<Column;j++)
{
if(CompareTo(btnControl[i][j],str))
{ ShowKeyPress(i,j);
break;
}
}
}
char* DeleteChar(char *str,int index)
{
char *temp=new char[500];
for(int i=0;i<index;i++)
temp[i]=str[i];
for(int j=index+1;j<=l;j++)
temp[j-1]=str[j];
return temp;
}
void KeyInput()
{
int TopInput=Top-5,TopOutput=Top-2,maxlen=23;
int first=0,last=0,current=0;
textbackground(0);
int color=CYAN;
int row=0,column=0;
char* str=new char[500];
char* value;
str="";
char* show=new char[maxlen];
int key;
do{
key=getch();
switch(key)
{
case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
case '+':case '-':case '*':case '/':case '^':case '!':case '(':case ')':case '%':case '.':
{
value=new char[1];
value[0]=key;
value[1]='\0';
str=InsertString(str,value,first+current);
if(current<maxlen)
{ current++;
last++;
}
else {
current=maxlen;
first++;last++;
}
SearchKey(value);
break;
}
case 'c':case 'C':case 's':case 'S':case 't':case 'T':case 'o':case 'O':case 'l':case 'L':
{
if(key=='c'||key=='C')
value="Cos";
else if(key=='s'||key=='S')
value="Sin";
else if(key=='t'||key=='T')
value="Tag";
else if(key=='o'||key=='O')
value="Cotag";
else if(key=='l'||key=='L')
value="Log";
str=InsertString(str,value,first+current);
if(current+l<maxlen)
{
current+=l;
if(last+l<maxlen)
last+=l;
}
else {
int t=current+l-maxlen;
last=maxlen;
current=maxlen;
first+=(l-t);last+=(l-t);
}
SearchKey(value);
break;
}
case 75:{
if(current>0)
current--;
else if(first>0)
{
first--;last--;
}
SearchKey("<-");
break;
}
case 77:{
if(current<maxlen&¤t<last)
current++;
else
{ first++;last++;}
SearchKey("->");
break;
}
case 'd':case 'D':{
{
strcpy(str
+first
+current
,str
+first
+current
+1); if(last<maxlen)
last--;
}
SearchKey("DEL");
break;
}
case 13:{
DrawString(" ",Left+1,TopOutput,RED);
{
Error="";
TreeExpression *tree=new TreeExpression(str);
long double t=tree->Calculator();
DrawString(Error,Left+1,TopOutput,RED);
else
{
//char result[23];
//ltoa(t,result,10);
//DrawString(result,Left+1,TopOutput,RED);
DrawFloat(t,Left+1,TopOutput,RED);
}
}
else DrawString("Expression = null",Left+1,TopOutput,RED);
break;
}
case 32:{
current=0;
first=0;
last=0;
str[0]='\0';
SearchKey("CLR");
break;
}
case 27:{SearchKey("ESC");break;}
default :break;
}
int temp;
for(temp
=first
;temp
<=last
&&temp
<strlen(str
);temp
++) show[temp-first]=str[temp];
show[temp]='\0';
DrawString(" ",Left+1,TopInput,color);
DrawString(show,Left+1,TopInput,color);
gotoxy(Left+1+current,wherey());
}while(key!=27);
}
void main()
{
textbackground(0);
clrscr();
DrawFrame();
KeyInput();
}