⑴ c語言程序設計:實現帶有括弧的四則運算
呵呵。不知道你是否過關了。我是才看到。我寫了個c++版本的。
stack_h文件
#ifndef STACK_H
#define STACK_H
#define STACK_INIT_SIZE 100
#include<iostream>
using namespace std;
template <class type>
class stack
{
public:
stack(int = STACK_INIT_SIZE);
~stack()
{
delete []stackptr;
}
bool push(const type &);
bool pop(type &);
bool isempty()const;
bool isfull()const;
type getTopValue();
private:
int size;
int top;
type* stackptr;
};
template <class type>
stack<type>::stack(int length)
{
size=length; //防止輸入不合理的數字
top=-1;
stackptr=new type[size];
}
////////////////////////////////////////////
template<class type>
bool stack<type>::isempty()const
{
return top==-1;
}
///////////////////////////////////////////
template<class type>
bool stack<type>::isfull()const
{
return top==size-1;
}
//////////////////////////////////////////
template<class type>
bool stack<type>::push(const type &data)
{
if(!isfull())
{
stackptr[++top]=data;
return true;
}
return false;
}
/////////////////////////////////////////
template<class type>
bool stack<type>::pop(type &popvalue)
{
if(!isempty())
{
popvalue=stackptr[top--];
return true;
}
return false;
}
template<class type>
type stack<type>::getTopValue()
{
type temp;
if(!isempty())
{
temp=stackptr[top];
}
return temp;
}
#endif
main.cpp
//right www
#include<iostream>
#include "stack.h"
using namespace std;
bool issign(char );//判斷c中的值是否為運算符,如果是則返回1
char Precede(char c1,char c2);//比較運算符之間的優先順序
double Operate(double a,char theta, double b);//計算a theta b 的值
double EvaluateExpression(char m[]);//表達式求值
int main()
{
char c[60];
cout<<"please input the expression and end with '=': "<<endl;
cin>>c;
double result=0;
result=EvaluateExpression(c);
cout<<"the result is :"<<result;
system("pause");
return 0;
}
//
bool issign(char c)
{
if(c!='+'&&c!='-'&&c!='*'&&c!='/'&&c!='='&&c!='('&&c!=')')
return 0;
else
return 1;
}
char Precede(char c1,char c2)
{
switch(c1)
{
case '+':if(c2=='+'||c2=='-'||c2==')'||c2=='=') return '>';
else return '<';break;
case '-':if(c2=='+'||c2=='-'||c2==')'||c2=='=') return '>';
else return '<';break;
case '*':if(c2=='(') return '<';
else return '>';break;
case '/':if(c2=='(') return '<';
else return '>';break;
case '(':if(c2==')') return '=';
else return '<';break;
case ')': return '>';break;
case '=':if(c2=='=') return '=';
else return '<';break;
default:return 0;
}
}
double Operate(double a,char theta, double b)
{
switch(theta)
{
case '+': return a+b;break;
case '-': return a-b;break;
case '*': return a*b;break;
case '/': if(b!=0) {return a/b;break;}
else cout<<"分母不能為零!,輸入錯誤"<<endl;
default: return 0;
}
}
double EvaluateExpression(char m[])
{
stack<double>number; //存放表達式的數值
stack<char>sign;//存放表達式的符號
sign.push('=');//把等號存入符號棧中,用來判斷表達式已經計算完畢
double stored_a,stored_b;//已經存入stack<int>number的值
int i=0;//m的下標
char signal;//保存符號
while( m[i]!='='||sign.getTopValue()!='=')
{
if(!issign(m[i]))
{
char*p=&m[i];
while(!issign(m[i])||m[i]=='.')
{
i++;
}
number.push(atof(p)); //如果不是運算符,則轉換為浮點型並且壓入存放數字的棧中
}
else
{
switch( Precede(sign.getTopValue() , m[i]))
{
case '<':
sign.push(m[i]);i++;break;
case '=':sign.pop(signal);i++;break;
case '>':
sign.pop(signal);
number.pop(stored_a);
number.pop(stored_b);
number.push(Operate(stored_b , signal , stored_a));
break;
}
}
}
double result;
number.pop(result);
return result;
}
絕對原創。
⑵ C語言中括弧運算符的問題
哈哈,你這是一個逗號表達式。
它將以逗號為界,從左到右依次計算每個表達式的值,最後返回最右邊的表達式的值。
阿明白??
⑶ 如何運用大一C語言基礎編寫簡單帶括弧的四則運算
利用堆棧將中綴表達式轉換為後綴表達式計算。簡單給你講一下演算法:
1.從中綴表達式中逐字元讀入操作數
2.若操作數為數字,直接輸出到後綴表達式隊列
3.若操作數為左括弧(,將其壓棧
4.若操作數為加減碼州乘除運算符,將其與棧頂元素比較:
①操作數優先順序高於棧頂元素,則將操作數壓棧;
②操作數優先順序等於或低於棧頂元素,先將棧頂元素出棧,然後將操作數壓棧。
5.若族喚操作數為右括弧),從棧頂元素開始出棧,直到遇到左括弧(為止,左括弧也出棧。若直到棧底仍然沒有發現左括弧,返回表達式匹配錯誤(說明右括弧過多)
6.表達式讀遲穗蔽取完畢,開始將棧中所有剩餘元素出棧。若出棧過程中發現有左括弧,返回表達式匹配錯誤(說明左括弧過多)
除了左括弧以外,所有出棧的元素都進入到後綴表達式隊列中。
7.根據後綴表達式計算算式結果。
⑷ 用簡單的C語言實現帶括弧的四則運算
#include<stdio.h> /*庫文件包含*/
#include<string.h> /*用於字元串操作*/
#include<stdlib.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; i<len; 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�0�8;
if(c[0]=='-')
{
start=1;
f=-1;
}
for(i=start; i<len; i++)
{
if(c[i]=='.')
{
p=i;
break;
}
temp[tempi++]=c[i]; /*將整數部分復制到temp[]中*/
}
temp[tempi]='\0';
if(p!=0)
{
for(i=p+1;i<len;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(k>0)
{
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(cc>0)
{
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(jj>0)
{
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");
}
⑸ C語言實現帶有括弧的四則運算
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
char token[61]; /*存放表達式字元串的數組*/
int n=0;
void error(void) /*報告錯誤函數*/
{
printf("ERROR!\n");
exit(1);
}
void match(char expected) /*檢查字元匹配的函數*/
{
if(token[n]==expected)
token[++n]=getchar();
else error();
}
double term(void); /*計算乘除的函數*/
double factor(void); /*處理括弧和數字的函數*/
double exp(void) /*計算加減的函數*/
{
double temp=term();
while((token[n]=='+')||(token[n]=='-'))
switch(token[n])
{
case'+':match('+');
temp+=term();
break;
case'-':match('-');
temp-=term();
break;
}
return temp;
}
double term(void)
{
double div;
double temp=factor();
while((token[n]=='*')||(token[n]=='/'))
switch(token[n])
{
case'*':match('*');
temp*=factor();
break;
case'/':match('/');
div=factor();
if(div==0) /*處理除數為零的情況*/
{
printf("The divisor is zero!\n");
exit(1);
}
temp/=div;
break;
}
return temp;
}
double factor(void)
{
double temp;
char number[61];
int i=0;
if(token[n]=='(')
{
match('(');
temp=exp();
match(')');
}
else if(isdigit(token[n])||token[n]=='.')
{
while(isdigit(token[n])||token[n]=='.') /*將字元串轉換為浮點數*/
{
number[i++]=token[n++];
token[n]=getchar();
}
number[i]='\0';
temp=atof(number);
}
else error();
return temp;
}
main()
{
double result;
FILE *data=fopen("61590_4.dat","at");
if(data==NULL)
data=fopen("61590_4.dat","wt");
if(data==NULL)
return 0;
token[n]=getchar();
result=exp();
if(token[n]=='\n')
{
token[n]='\0';
printf("%s=%g\n",token,result);
fprintf(data,"%s=%g\n",token,result);
}
else error();
fclose(data);
return 0;
getch();
}
⑹ c語言中的括弧表達式
括弧表達式計算順序是從左到右,然後整個表達式返回的是最右邊表達式的值,如第一個表達式,先算最內層的括弧表達式的最左邊的值,再把其最右邊的值返回並賦值給b,所以b在此次運算之後變為3,之後b+2=5(但5隻是一個臨時值,b值還是3),之後15+b=18,並且這個值由於是最右的表達式會作為整個大括弧表達式的返回值,即b再一次被賦值為18,然後現計算b+=18得到36;
如此第二個就是-30吧,對了,賦值表達式是從右到左賦值的
⑺ C語言中的括弧運算
理論上來說
增加括弧只會增加編譯的時間 並且對運行的時間是沒有差別的
也就是增加了把你從c/c++代碼變成exe的時間,但是不會影響exe運行的時間
而且 增加一兩個括弧 對於計算機編譯時間的影響是微乎其微的
計算機一秒計算數量以億算 怎麼會差這一個括弧呢
關於代碼運行效率 更應該注意的是演算法,而不是這些語句 那個才能從本質上提高程序運行效率
多行的代碼 運行效率就不一定比單行的要低
作為源代碼重要的一是演算法 二是可讀性 增加括弧和增加有必要的換行不但不會降低運行效率,反而會使代碼更加容易理解 減少歧義的產生
⑻ 用簡單的C語言實現帶括弧的四則運算
只是吐槽,不負法律責任。
對於四則運算的辯答處理應該屬於 AST演算法 的一個分支,如果不構建詞法分析樹的話,就難以對給定串(不一定是簡單的四則運算)進行優先順序處理。
然而居然能夠說出「不用堆棧」之類的話,看樣子樓主是基本不會什麼數據結構了,即使這樣,還奢望能夠寫出四則運算處理。。
然而語言略微有些偏激了攜前慧。
簡而言之,處理四則運算,考慮優先順序規則最簡單的方法是堆棧(不考慮優先順序的話從左到右掃一遍也是可以的),悔擾如果要復雜的方法也行,只是連堆棧都不想用的人,估計理解不了那些復雜方法。
最後一提,如果可以使用數據結構(如棧啊,隊列啊)的話,追問可以得到源代碼,否則請勿回復,並建議主動關閉問題。
⑼ 用簡單的C語言實現帶括弧的四則運算
考慮復雜的灶備困表達式,滾友不可能簡單吧。
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
void SplitK(char *str);
void SplitPrem(char *str);
void Combine(float f1,char Operate,float f2);
void StringBracket(char *str);
char str1[100],str2[100],str3[100],sub_str1[100],sub_str2[100],sub_str3[20];
char sub_str31[20],sub_str32[20],str_4[100],operate;
int pause=0,left=0,k1,k2,k3;
float f1=0.0,f2=0.0, f=0.0;
void main()
{
float temp;
printf("Please input a description :\n");
scanf("%s",&str1);
SplitK(str1);
temp=atof(str1);
printf("description value is %.2f\n",temp);
}
void SplitK(char *str)
{
int i,j,k,l,jk;
left=0;
while(*str) {
if(*str == '(') left++;
str++;
}
str2[0]='\0';
str3[0]='\0';
if(left>0)
{
StringBracket(str1);
j=strlen(str1);
for( i=0; i<j; i++)
{
if(str1[i]== '(')
{
jk=0;
for( k=i; k<j; k++)
{
if(str1[k]== ')') break;
for( l=i+1; l<k-1; l++)
{
if(str1[l]== '('){jk++; break;}
}
}
if(jk==0)
{
for(l=0; l<i; l++) str2[l]=str1[l];
str2[i]='\0';
for(l=k+1; l<j; l++) str3[l-k-1]=str1[l];
str3[j-k-1]='\0';
for(l=i+1; l<=k-1; l++) str1[l-i-1]=str1[l];
str1[k-i-1]='\0';
break;
}
}
}
}
SplitPrem(str1);
}
void SplitPrem(char *str)
{
int i,j,k,l;
f1=0.0;
f2=0.0;
pause=0;
strcpy(str1,str);
StringBracket(str1);
j=strlen(str1);
for( i=1; i<j-1; i++)
{
if((str1[i]=='*'||str1[i]=='/'))
{
strcpy(sub_str1," ");
strcpy(sub_str2," ");
strcpy(sub_str3," ");
strcpy(sub_str31," ");
strcpy(sub_str32," ");
operate=str1[i];
for( k1=i-2; k1>=0; k1--)
{
if((str1[k1]=='*'||str1[k1]=='/'||str1[k1]=='+'||str1[k1]=='-'))
{
for( l=0; l<=k1; l++) sub_str1[l]=str1[l];
sub_str1[k1+1]='\0';
break;
}
}
for( k2=i+2; k2<隱念j; k2++)
{
if((str1[k2]=='*'||str1[k2]=='/'||str1[k2]=='+'||str1[k2]=='-'))
{
for(l=k2; l<j; l++) sub_str2[l-k2]=str1[l];
sub_str2[j-k2]='\0';
break;
}
}
if(k1<0) k1=-1;
for(l=k1+1; l<i; l++) sub_str31[l-k1-1]=str1[l];
sub_str31[i-k1-1]='\0';
if(k2>j) k2=j;
for(l=i+1; l<k2; l++) sub_str32[l-i-1]=str1[l];
sub_str32[k2-i-1]='\0';
f1=atof(sub_str31);
f2=atof(sub_str32);
Combine(f1,operate,f2);
}
if(pause==1) break;
}
j=strlen(str1);
for( i=1; i<j-1; i++)
{
if((str1[i]=='+'||str1[i]=='-'))
{
strcpy(sub_str1," ");
strcpy(sub_str2," ");
strcpy(sub_str3," ");
strcpy(sub_str31," ");
strcpy(sub_str32," ");
operate=str1[i];
sub_str1[0]='\0';
k3=0;
for( k2=i+2; k2<j-1; k2++)
{
if((str1[k2]=='+'||str1[k2]=='-'))
{
k3=1;
for(l=k2; l<j; l++) sub_str2[l-k2]=str1[l];
sub_str2[j-k2]='\0';
break;
}
}
for(l=0; l<i; l++) sub_str31[l]=str1[l];
sub_str31[i]='\0';
if(k2>j) k2=j;
if( k3==0) k2=j;
for(l=i+1; l<k2; l++) sub_str32[l-i-1]=str1[l];
sub_str32[k2-i-1]='\0';
f1=atof(sub_str31);
f2=atof(sub_str32);
Combine(f1,operate,f2);
}
if(pause==1) break;
}
strcpy(str_4,str2);
strcat(str_4,str1);
strcat(str_4,str3);
strcpy(str1,str_4);
StringBracket(str1);
j=strlen(str1);
str2[0]='\0';
str3[0]='\0';
for( i=0; i<j; i++)
{
if((str1[i]=='('))
{
SplitK(str1);
break;
}
}
for( i=0; i<j-1; i++)
{
if((str1[i]=='*'||str1[i]=='/'||str1[i]=='+'||str1[i]=='-'))
{
k=1;
if(str1[0]=='-')
{
k=0;
for( l=1; l<j-1; l++)
{
if((str1[l]=='*'||str1[l]=='/'||str1[l]=='+'||str1[l]=='-'))
{
k=1;
break;
}
}
}
if(k==0) break;
if(k==1)
{
SplitPrem(str1);
break;
}
}
}
}
void Combine(float f1,char Operate,float f2)
{
int i,j,k,l;
f=0.0;
switch (Operate) {
case '+':
f=f1+f2;
break;
case '-':
f=f1-f2;
break;
case '*':
f=f1*f2;
break;
case '/':
if(f2!=0)
f=f1/f2;
break;
}
sprintf(sub_str3,"%5.3f",f);
strcpy(str1,sub_str1);
strcat(str1,sub_str3);
strcat(str1,sub_str2);
StringBracket(str1);
j=strlen(str1);
for( i=0; i<j-1; i++)
{
if((str1[i]=='*'||str1[i]=='/'||str1[i]=='+'||str1[i]=='-'))
{
k=1;
if(str1[0]=='-')
{
k=0;
for( l=1; l<j-1; l++)
{
if((str1[l]=='*'||str1[l]=='/'||str1[l]=='+'||str1[l]=='-'))
{
k=1;
break;
}
}
}
if(k==0) break;
if(k==1)
{
SplitPrem(str1);
break;
}
}
}
pause=1;
strcpy(str_4,str2);
strcat(str_4,str1);
strcat(str_4,str3);
strcpy(str1,str_4);
str2[0]='\0';
str3[0]='\0';
StringBracket(str1);
j=strlen(str1);
for( i=0; i<j; i++)
{
if((str1[i]=='('))
{
SplitK(str1);
break;
}
}
}
void StringBracket(char *str)
{
int i,j,len;
len=strlen(str);
j=0;
for(i=0; i<len; i++)
{
if(str[i]!=' ')
{
str[j]=str[i];
j=j+1;
}
}
str[j]='\0';
if(j>0 && str[j-1]=='.')
{
str[j-1]='\0';
j=j-1;
}
}