新聞中心
該代碼僅適用于個位數(shù) (整型) 表達(dá)式求值(即表達(dá)式中進(jìn)行運(yùn)算的都是個位數(shù),并且每次運(yùn)算的結(jié)果也是個位數(shù))
運(yùn)行過程及結(jié)果?
1.首先需要有
兩個鏈棧,分別存儲表達(dá)式中的 運(yùn)算數(shù)【 OPND 】和 運(yùn)算符【 OPTR 】,既然分為兩個棧存儲,當(dāng)然還需要可以判定讀入字符的是否為運(yùn)算符或者運(yùn)算數(shù)的函數(shù)【 In() 】?
bool In(char ch){
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '#'){
return true;
}else{
return false;
}
}
2.有了存儲表達(dá)式的棧,下一步就要完成表達(dá)式的運(yùn)算:
? i.需要一個可以判斷運(yùn)算符之間優(yōu)先級的函數(shù)【 Precede() 】
char Precede(char a, char b){
if (a == '+' || a == '-'){
if (b == '+' || b == '-' || b == ')' || b == '#'){
return '>';
}else{
return '<';
}
}else if (a == '*' || a == '/'){
if (b == '+' || b == '-' || b == '*' || b == '/' || b == ')' || b == '#'){
return '>';
}else{
return '<';
}
}else if (a == '('){
if (b == ')'){
return '=';
}else if (b == '#'){ //表達(dá)式錯誤
return '?';
}else{
return '<';
}
}else if (a == '#'){
if (b == '#'){
return '=';
}else if (b == ')'){ //表達(dá)式錯誤
return '?';
}else {
return '<';
}
}
}
其實這個函數(shù)還可以根據(jù)運(yùn)算符優(yōu)先級關(guān)系圖定于成一個二維數(shù)組,直接返回兩個運(yùn)算符的優(yōu)先級大小,如下:
int change(char ch){
if (ch == '+'){
return 0;
}else if (ch == '-'){
return 1;
}else if (ch == '*'){
return 2;
}else if (ch == '/'){
return 3;
}else if (ch == '('){
return 4;
}else if (ch == ')'){
return 5;
}else if (ch == '#'){
return 6;
}
}
char Precede(char a, char b){
int A = change(a);
int B = change(b);
char judge[7][7] = {
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','?'},
{'>','>','>','>','?','>','>'},
{'<','<','<','<','<','?','='}
};
return judge[A][B];
}
感覺這個判斷方法更加清晰易懂?,比用 if 更加簡練一些
? ii.還需要可以對運(yùn)算數(shù)進(jìn)行運(yùn)算的函數(shù)【 Operate() 】
char Operate(char a, char theta, char b){
int A = a - 48;
int B = b - 48;
int C;
if (theta == '+'){
C = A + B ;
}else if (theta == '-'){
C = A - B ;
}else if (theta == '*'){
C = A * B ;
}else if (theta == '/'){
C = A / B ;
}
return C + '0';
}
將字符數(shù)字 (僅限個位數(shù)字) 轉(zhuǎn)化成整型減去48即可,將字符轉(zhuǎn)化成整型會直接轉(zhuǎn)換成其ASCII表中對應(yīng)的十進(jìn)制數(shù),對應(yīng)減去48就可以了,最后整型數(shù)字 (也僅限于個位數(shù)字) 轉(zhuǎn)化成字符加上'0'就可以了,系統(tǒng)會自動轉(zhuǎn)化
3.最重要的一步就是根據(jù)以上條件編寫一個可以實現(xiàn)表達(dá)式求解的算法函數(shù)【EvaluateExpression() 】
void EvaluateExpression(){
LinkStack OPTR,OPND;
OPTR = (LinkStack)malloc(sizeof(LinkStack)); //創(chuàng)建OPND棧(存放運(yùn)算數(shù))
OPND = (LinkStack)malloc(sizeof(LinkStack)); //創(chuàng)建OPTR棧(存放運(yùn)算符)
InitStack(&OPTR);
InitStack(&OPND);
Push(&OPTR, '#'); //將表達(dá)式起始符'#'壓入OPTR中
char ch;
scanf("%c", &ch);
while(ch != '#' || GetTop(OPTR) != '#'){
if (!In(ch)){ //判斷輸入的是否是運(yùn)算符
Push(&OPND, ch);
scanf("%c", &ch);
}else{
switch(Precede(GetTop(OPTR), ch)){ //比較OPTR的棧頂元素和ch的優(yōu)先級
case '<': //運(yùn)算符ch優(yōu)先級高,繼續(xù)壓入
Push(&OPTR,ch);
scanf("%c", &ch);
break;
case '>': //OPTR棧頂元素優(yōu)先級高,彈出運(yùn)算
char theta,a,b;
Pop(&OPTR,&theta);
Pop(&OPND,&b);
Pop(&OPND,&a);
Push(&OPND,Operate(a,theta,b)); //進(jìn)行運(yùn)算,并將結(jié)果壓入OPND
break;
case '=': //OPTR棧頂元素為'(',ch也為')'
char temp; //不會出現(xiàn)都為'#'的情況
Pop(&OPTR,&temp);
scanf("%c", &ch);
break;
case '?':
printf("表達(dá)式錯誤!");
return;
}
}
}
printf("表達(dá)式的結(jié)果為:%c", GetTop(OPND));
}
大家對代碼哪些地方有疑惑的歡迎評論區(qū)討論
???????謝謝大家的支持??!完整代碼
#include#includetypedef struct StackNode{
char data;
StackNode *next;
}*LinkStack;
void InitStack(LinkStack *S){
*S = NULL;
}
void Pop(LinkStack *S, char *ch){
*ch = (*S)->data;
*S = (*S)->next;
}
void Push(LinkStack *S, char ch){
LinkStack node = (LinkStack)malloc(sizeof(LinkStack));
node->data = ch;
node->next = *S;
*S = node;
}
char GetTop(LinkStack S){
return S->data;
}
bool In(char ch){
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '#'){
return true;
}else{
return false;
}
}
char Precede(char a, char b){
if (a == '+' || a == '-'){
if (b == '+' || b == '-' || b == ')' || b == '#'){
return '>';
}else{
return '<';
}
}else if (a == '*' || a == '/'){
if (b == '+' || b == '-' || b == '*' || b == '/' || b == ')' || b == '#'){
return '>';
}else{
return '<';
}
}else if (a == '('){
if (b == ')'){
return '=';
}else if (b == '#'){ //表達(dá)式錯誤
return '?';
}else{
return '<';
}
}else if (a == '#'){
if (b == '#'){
return '=';
}else if (b == ')'){ //表達(dá)式錯誤
return '?';
}else {
return '<';
}
}
}
char Operate(char a, char theta, char b){
int A = a - 48;
int B = b - 48;
int C;
if (theta == '+'){
C = A + B ;
}else if (theta == '-'){
C = A - B ;
}else if (theta == '*'){
C = A * B ;
}else if (theta == '/'){
C = A / B ;
}
return C + '0';
}
void EvaluateExpression(){
LinkStack OPTR,OPND;
OPTR = (LinkStack)malloc(sizeof(LinkStack));
OPND = (LinkStack)malloc(sizeof(LinkStack));
InitStack(&OPTR);
InitStack(&OPND);
Push(&OPTR, '#');
char ch;
scanf("%c", &ch);
while(ch != '#' || GetTop(OPTR) != '#'){
if (!In(ch)){
Push(&OPND, ch);
scanf("%c", &ch);
}else{
switch(Precede(GetTop(OPTR), ch)){
case '<':
Push(&OPTR,ch);
scanf("%c", &ch);
break;
case '>':
char theta,a,b;
Pop(&OPTR,&theta);
Pop(&OPND,&b);
Pop(&OPND,&a);
Push(&OPND,Operate(a,theta,b));
break;
case '=':
char temp;
Pop(&OPTR,&temp);
scanf("%c", &ch);
break;
case '?':
printf("表達(dá)式錯誤!");
return;
}
}
}
printf("表達(dá)式的結(jié)果為:%c", GetTop(OPND));
}
int main(){
printf("請輸入一個表達(dá)式(以#結(jié)束):");
EvaluateExpression();
}
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
新聞名稱:C語言表達(dá)式求值(鏈棧)-創(chuàng)新互聯(lián)
文章URL:http://www.dlmjj.cn/article/joece.html