本文目錄一覽:
編寫程序對表達式求值C語言
#include “stdio.h”
#include “malloc.h”
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
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;
}
//判斷是否為空棧
Status StackEmpty(SqStack S){
if(S.top == S.base)
return TRUE;
else
return FALSE;
}
//用e返回S的頂元素
Status GetTop(SqStack S, SElemType *e){
if(S.top == S.base)
return ERROR;
*e = *(S.top-1);
return OK;
}
//插入e為新的頂元素
Status Push(SqStack *S, SElemType 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;
S-top++;
return OK;
}
//刪除S的頂元素,並用e返回其值
Status Pop(SqStack *S, SElemType *e){
if(S-top == S-base)
return ERROR;
S-top–;
*e = *(S-top);
return OK;
}
//從棧底到棧頂依次對S的每個元素調用函數Visit(),一旦失敗操作無效
Status ListTraverse(SqStack S,Status (*visit)(SElemType)){
SElemType *p;
p=S.base;
for(p=S.base;pS.top;p++)
(*visit)(*p);
return OK;
}
//輸出元素e
Status output(SElemType e){
printf(“%d “,e);
return OK;
}
實現表達式求值的代碼:
/*計算整數表達式的值
*表達式必須以#結束
*表達式中可以出現多位數字,
*表達式中可以出現空格
*運算符包括+,-,*,/,(,)
*運算結果可以是多位整數,並以整數的形式返回
*/
typedef int SElemType; /*放入堆棧的元素的類型*/
#include ctype.h
#include “stack_s.c”
/*判斷輸入的某個字元是否是運算符
*c表示輸入的字元
*op數組中存放系統能識別的運算符
*/
Status in(char c,char op[]){
char *p;
p=op;
while(*p != ‘\0’){
if(c == *p)
return TRUE;
p++;
}
return FALSE;
}
/*比較兩個運算符的優先順序
*a,b中存放待比較的運算符
*”表示ab
*’0’表示不可能出現的比較
*/
char Precede(char a, char b){
int i,j;
char pre[][7]={
/*運算符之間的優先順序製作成一張表格*/
{”,”,”,”,”,”,”},
{”,”,”,”,”,”,”},
{”,”,”,”,”,”,”},
{”,”,”,”,”,”,”},
{”,”,”,”,”,’=’,’0′},
{”,”,”,”,’0′,”,”},
{”,”,”,”,”,’0′,’=’}};
switch(a){
case ‘+’: i=0; break;
case ‘-‘: i=1; break;
case ‘*’: i=2; break;
case ‘/’: i=3; break;
case ‘(‘: i=4; break;
case ‘)’: i=5; break;
case ‘#’: i=6; break;
}
switch(b){
case ‘+’: j=0; break;
case ‘-‘: j=1; break;
case ‘*’: j=2; break;
case ‘/’: j=3; break;
case ‘(‘: j=4; break;
case ‘)’: j=5; break;
case ‘#’: j=6; break;
}
return pre[i][j];
}
/*進行實際的運算
*a,b中分別以整數的形式存放兩個待運算的操作數
*theta中存放代表操作符的字元
*結果以整數的形式返回
*/
int Operate(int a, char theta, int b){
int i,j,result;
i=a;
j=b;
switch(theta) {
case ‘+’: result = i + j; break;
case ‘-‘: result = i – j; break;
case ‘*’: result = i * j; break;
case ‘/’: result = i / j; break;
}
return result;
}
/*從輸入緩衝區中獲得下一個整數或運算符,並通過n帶回到主調函數
*返回值為1表示獲得的是運算符
*返回值為0表示獲得的是整形操作數
*/
int getNext(int *n){
char c;
*n=0;
while((c=getchar())==’ ‘); /*跳過一個或多個空格*/
if(!isdigit(c)){ /*通過函數判斷如果字元不是數字,那麼只能是運算符*/
*n=c;
return 1;
}
do { /*能執行到該條語句,說明字元是數字,此處用循環獲得連續的數字*/
*n=*n*10+(c-‘0’); /*把連續的數字字元轉換成相對應的整數*/
c=getchar();
} while(isdigit(c)); /*如果下一個字元是數字,進入下一輪循環*/
ungetc(c,stdin); /*新讀入的字元不是數字,可能是運算符,為了不影響下次讀入,把該字元放回到輸入緩衝區*/
return 0;
}
int EvaluateExpression(){
int n;
int flag;
int c;
char x,theta;
int a,b;
char OP[]=”+-*/()#”;
SqStack OPTR;
SqStack OPND;
InitStack(OPTR);
Push(OPTR,’#’);
InitStack(OPND);
flag=getNext(c);
GetTop(OPTR, x);
while(c!=’#’ || x != ‘#’)
{
if(flag == 0)
{
Push(OPND,c);
flag = getNext(c);
} else
{
GetTop(OPTR, x);
switch(Precede(x, c))
{
case ”://棧頂元素優先順序低
Push(OPTR,c);
flag = getNext(c);
break;
case ‘=’://脫括弧並接受下一字元
Pop(OPTR,x);
flag = getNext(c);
break;
case ”:// 退棧並將運算結果入棧
Pop(OPTR, theta);
Pop(OPND,b);
Pop(OPND,a);
Push(OPND, Operate(a, theta, b));
break;
}
}
GetTop(OPTR, x);
}
GetTop(OPND, c);
return c;
}
void main(){
int c;
printf(“Please input one expression:”);
c=EvaluateExpression();
printf(“Result=%d\n”,c);
getch();
}
C語言編程(數據結構):表達式求值
/*在TC2 和 VC6下都可以順利運行。
做了一個下午。一定要用我這個噢。
有簡單的輸入錯誤檢測。有完整的說明和
注釋*/
#includestdio.h /*庫文件包含*/
#includestring.h /*用於字元串操作*/
#includestdlib.h /*用於exit函數*/
/**************************************************************************
int check(char *c)
輸入參數:
char *c: 輸入的字元串
返回參數:
0:字元串中有不符合規定的字元
1: 字元串字元符合規定,沒有不符合規定的字元.
功能:
檢查字元串中有否除了 0-9, +,-,*,/,(,),之外的其他字元,
如果有,則返回0, 表示出現錯誤。
若沒有,則返回1,表式字元串符合規定。
**************************************************************************/
int check(char *c)
{
int k=0;
while(*c!=’\0′)
{
if((*c=’0′ *c=’9′) || *c==’+’ ||
*c==’-‘ || *c==’*’ || *c==’/’ ||
*c==’.’ || *c=='(‘ || *c==’)’ )
{
}
else
{
printf(“input error, there have the char not the math expression char!\n”);
return 0;
}
if(*c=='(‘)
k++;
else if(*c==’)’)
k–;
c++;
}
if(k!=0)
{
printf(“input error, there is not have correct bracket ‘()’!\n”);
return 0;
}
return 1;
}
/**************************************************************************
void move(char *f, double *s,int p)
輸入參數:
char *f : 運算符數組
double *s: 數值數組
int p: 當前運算符數組位置。
返回參數:
無
功能:
將當前已經完成運算的運算符消去,同時將數值數組的位置調整以進行下一次運算。
傳入值p若為3
則當前符號的數組位置為3.
f[3]=f[3+1]…….f[len-2]=f[len-1] f[len-1]=’\0′;
s[i]=s[i+1]…….s[len-1]=s[len] 因為數值比運算符多一個。
***************************************************************************/
void move(char *f, double *s,int p)
{
int i=0,len=strlen(f);
for(i=p; ilen; i++) /*將已經運算過的符號,空出來的位置用後面的符號來填充,*/
{ /*即把乘和除號的位置用後面的加和減號填充*/
f[i]=f[i+1];
s[i]=s[i+1];
}
s[i]=s[i+1];
f[len-1]=’\0′;
}
/**************************************************************************
double convnum(char *c)
輸入參數:
char *c :由數字和小數點組成的字元,用以轉換成double型的數值。
返回參數:
num:返迴轉換好的值。
功能:
將輸入的字元串先將其小數點以前的部分複製到temp[]數組中,
若有小數點,則將小數點之後的數值,也就是小數部分先進行計算,值存入num中
計算完成後,再對整數部分進行計算,值加上小數部分的值,存入num中。
***************************************************************************/
double convnum(char *c)
{
double num=0.0;
double a=1.0;
int i=0,p=0,len=0;
char temp[100];
int tempi=0;
int start=0;
int f=1; /*正負符號指示器,若為1則為正數,為-1,此數為負數*/
len=strlen©;
if(c[0]==’-‘)
{
start=1;
f=-1;
}
for(i=start; ilen; i++)
{
if(c[i]==’.’)
{
p=i;
break;
}
temp[tempi++]=c[i]; /*將整數部分複製到temp[]中*/
}
temp[tempi]=’\0′;
if(p!=0)
{
for(i=p+1;ilen;i++) /*將小數部分計算出來*/
{
if(c[i]==’.’) /*如果有多餘的小數點,則表示輸入錯誤*/
{
printf(“there is more that one dot ‘.’ in number!error!\n”);
exit(0);
}
a=a*0.1;
num+=(a*(c[i]-48));
}
}
a=1.0;
len=strlen(temp); /*計算整數部分*/
for(i=len-1;i=0; i–)
{
num=num+(a*(temp[i]-48));
a*=10;
}
num=num*f;
return num;
}
/**************************************************************************
double good(char *c)
輸入參數:
char *c :即將進行運算的字元串型數學表達式。如3.5+(2*3/5)
返回參數:
s[0]:計算結果將放入s[0]中
功能:
將輸入的字元串中的數字分別調用convnum(char *c)函數進行數值變換,再將其依
次存入doulbe s[i]中,將加減乘除運算符依次存入字元串符號數組 char f[i]中,
然後如果遇到括弧,則將括弧內的字元串存入另一字元數組中,然後用此
good(char *c) 遞歸函數進行遞歸運算。 然後根據先乘除,後加減的順序對已
存入數組的數值根 據存入字元串符號數組的運算符進行運算。結果存入s[0]中。
返回最終結果。
***************************************************************************/
double good(char *c) /*可遞歸函數*/
{ /*取得數值字元串,並調用convnum轉換成double*/
char g[100],number[30]; /*g,保存當前的表達式串,number保存一個數的所有字元*/
char f[80]; /*保存所有的符號的堆棧*/
int fi=0; /*保存符號的位置指針*/
double s[80]; /*保存當前所有的數的一個堆棧*/
int si=0; /*保存數字位置指針*/
int k=0; /* 若k=1則表示有一對括弧*/
int num=0,i=0; /*num保存新括弧內的字元數,i 保存number里的字元位置*/
int cc=0; /*乘除符號數量*/
int jj=0; /*加減符號數量*/
while(*c!=’\0′)/*當p==1 和k==0時,表示已經把括弧里的內容全部複製到g[100]中了*/
{
k=0;
num=0;
switch(*c)
{
case ‘+’: /*當前字元為+-乘除時則表示*/
case ‘-‘:
case ‘*’:
case’/’:
f[fi++]=*c;
if(*c==’*’ || *c==’/’)
cc++;
else
jj++;
if(*(c-1)!=’)’)
{
number[i]=’\0′;
i=0;/*完成一個數字的複製,其位置指針i=0*/
s[si++]=convnum(number);
}
break;
case'(‘: /*有括弧,則將當前括弧作用範圍內的全部字元保存,作為*/
k++; /*一個新的字元表達式進行遞歸調用good函數計算。*/
while(k0)
{
c++;
g[num]=*c;
num++;
if(*c==’)’)
{
k–;
}
else if(*c=='(‘)
{
k++;
}
}
g[num-1]=’\0′;
num=0;/*完成一個括弧內容的複製,其位置指針num=0*/
s[si++]=good(g);
break;
default:
number[i++]=*c;
if(*(c+1)==’\0′)
{ number[i]=’\0′;
s[si++]=convnum(number);
}
break;
}
c++;
}
f[fi]=’\0′;
i=0;
while(cc0)
{
switch(f[i])
{
case ‘*’: cc–;
s[i+1]=s[i]*s[i+1];
move(f,s,i);
break;
case ‘/’: cc–;
s[i+1]=s[i]/(float)s[i+1];
move(f,s,i);
break;
default:
i++;
break;
}
}
i=0;
while(jj0)
{
switch(f[i])
{
case ‘+’: s[i+1]=s[i]+s[i+1];
jj–;
move(f,s,i);
break;
case ‘-‘: s[i+1]=s[i]-s[i+1];
jj–;
move(f,s,i);
break;
default:
printf(“operator error!”);
break;
}
}
return s[0];
}
void main()
{
char str[100];
double sum=0;
int p=1;
while(1)
{
printf(“enter expression: enter ‘exit’ end of program\n”);
scanf(“%s”,str);
p=strcmp(str,”exit”);
if(p==0)
break;
p=check(str);
if(p==0)
continue;
sum=good(str);
printf(“%s=%f”,str,sum);
printf(“\n”);
}
printf(“good bye!\n”);
}
例:
enter expression: enter ‘exit’ end of program
3.5+(12.3*15+8-(3/2+1))*2+(3.2*3-5)/6(輸入)
3.5+(12.3*15+8-(3/2+1))*2+(3.2*3-5)/6=384.266667
enter expression: enter ‘exit’ end of program
china(輸入)
input error, there have the char not the math expression char!
enter expression: enter ‘exit’ end of program
exit(輸入)
good bye!
用C語言編寫程序「算術表達式求值」
#include stdio.h
#include math.h
enum state
;
int ctoi( char c)
bool isNum( char a)
bool isOp(char op)
{
switch(op)
{
case ‘+’:
return true;
break;
case ‘-‘:
return true;
break;
case ‘*’:
return true;
break;
case ‘/’:
return true;
break;
default:
return false;
break;
}
}
bool isDot(char dot)
int checkString( char str[], double *a, double * b, char* op, int num)
{
enum state s = BEGIN;
int a_i = 0;
int b_i = 0;
double num1 = 0;
double num2 = 0;
int pointNum = 0;
for( int i = 0; i num; ++i)
{
if(str[i] == ‘ ‘)continue;
switch(s)
{
case BEGIN:
if(isNum(str[i]))
elses = ERROR;
break;
case P2:
if(isNum(str[i]))
else if(isDot(str[i]))
{
s = P3;
}
else if(isOp(str[i]))
{
*op = str[i];
s = P5;
}
else
s = ERROR;
break;
case P3:
if(isNum(str[i]))
{
num1 = num1 + ctoi(str[i]) * pow(0.1, ++pointNum) ;
s = P4;
}
else
s = ERROR;
break;
case P4:
if(isNum(str[i]))
{
num1 = num1 + ctoi(str[i]) * pow(0.1, ++pointNum);
s = P4;
}
else if(isOp(str[i]))
{
*op = str[i];
s = P5;
}
else
s = ERROR;
break;
case P5:
if(isNum(str[i]))
{
num2 = num2 * 10 + ctoi(str[i]);
s = P6;
}
else
s = ERROR;
break;
case P6:
pointNum = 0;
if(isNum(str[i]))
{
num2 = num2 * 10 + ctoi(str[i]);
s = P6;
}
else if(isDot(str[i]))
{
s = P7;
}
else
s = END;
break;
case P7:
if(isNum(str[i]))
{
num2 = num2 + ctoi(str[i]) * pow(0.1, ++pointNum);
s = P8;
}
else
s = END;
break;
case 8:
if(isNum(str[i]))
{
num2 = num2 + ctoi(str[i]) * pow(0.1, ++pointNum);
s = P8;
}
else if(isOp(str[i]))
{
s = END;
}
else
s = END;
break;
case ERROR:
printf(“express error. \n”);
break;
}
if (s == END || s == ERROR)
break;
}
if(s==END)
else
}
int main()
{
char op;
double a;
double b;
char string[128] = ;
scanf(“%s”, string);
printf(“the expression you input is : %s. \n”, string);
getchar();
if (-1 == checkString(string, a, b, op, 128))
{
printf(“error occur while checking expression. Be sure no space in your expression when input\n”);
getchar();
return 0;
}
double result;
switch(op)
{
case ‘+’:
result = a + b;
break;
case ‘-‘:
result = a – b;
break;
case ‘*’:
result = a * b;
break;
case ‘/’:
if(b != 0)
result = a / b;
else
{
printf(” error! %d/%d”, a, b);
return -1;
}
break;
default:
printf(“undefined expression.\n”);
break;
}
printf(“%f %c %f = %f\n”, a, op, b, result);
return 0;
}
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/244050.html