C++实现简单表达式求值

该程序实现了从用户输入的中缀表达式(如5+3,2*(5/4+(2+1)))转换为后缀表达式,并进行计算。主要功能包括读取输入、转换表达式、计算值。转换过程中使用了堆栈来处理运算符的优先级,计算部分则通过另一个堆栈处理操作数。最后,输出结果保留两位小数。用户输入q退出程序。
摘要由CSDN通过智能技术生成

一、运行效果

Enter the expression(q to quit): 5+3
8.00
Next expression(q to quit): 2*(5/4+(2+1))
8.50
Next expression(q to quit): q
Bye!

二、函数分析

(1) main( )

读取用户的输入,检查输入是否有效;
然后使用ConvertEnd()和Compute()函数对其进行转换和计算;
继续读取输入,直到用户输入“q”退出;
使用setiosflags()和setprecision()将输出格式化为两位小数。

int main() {
    string front;
    vector<char> end;

    // Read input
    cout << "Enter the expression(q to quit): ";
    while (getline(cin, front) && front[0] != 'q') {
        if (!isdigit(front[0])) {
            cout << "Please enter the correct expression:";
            end.clear(); continue;
        }

        // Conver to the end format
        ConvertEnd(front, end);

        // Calculate the value
        cout << setiosflags(ios::fixed) << setprecision(2);
        cout << Compute(end) << endl;
        end.clear();
        cout << "Next expression(q to quit): ";
    }
    cout << "Bye!\n";
    return 0;
}

(2)ConvertEnd( )

接受用户输入的中缀表示法并将其转换为后缀表示法;
它使用堆栈来跟踪中缀表示法中的运算符,
并根据操作顺序重新排列它们以生成后缀表示法

void ConvertEnd(const string & front, vector<char> & end) {
    stack<char> s;

    for (int i = 0; i < front.length(); i++) {
        if (isdigit(front[i]) || front[i] == '.') end.push_back(front[i]);
        else if (IsOp(front[i])) {
            end.push_back(' ');
            if (s.empty()) s.push(front[i]);
            else if (front[i] == ')') {
                while (s.top() != '(') {
                    end.push_back(s.top()); s.pop();
                } 
                s.pop();
            } else {
                if (IsBig(front[i], s.top())) s.push(front[i]);
                else {
                    while (!s.empty() && s.top() != '(' && !IsBig(front[i], s.top())) {
                        end.push_back(s.top()); s.pop();
                    }
                    s.push(front[i]);
                }
            }
        }
    }
    while (!s.empty()) {
       end.push_back(s.top()); s.pop();
    }
}

(3)Compute( )

计算ConvertEnd()函数生成的后缀表达式;
它使用另一个堆栈来跟踪操作数和运算符,并将运算符应用于操作数以产生最终输出。

float Compute(const vector<char> & end) {
    // Compute the value through the end format
    stack<float> s;

    for (int i = 0; i < end.size(); i++) {
        if (isdigit(end[i])) {
            float temp = 0;
            i += FindValue(temp, end, i);
            s.push(temp);
        } else if (IsOp(end[i])) {
            s.push(SigComp(TopFloat(s), TopFloat(s), end[i]));
        }
    }

    if (!s.empty()) {
        return s.top();
    } else { cout << "Error!\n"; return 0; }
}

(4)IsOp( )

检查给定字符是否为运算符;
( ‘+’、 ‘-’、 ‘*’、 ‘/’、 ‘(’ 、 ‘)’ )

bool IsOp(char ch) {
    return (ch == '+') || (ch == '-') 
        || (ch == '*') || (ch == '/')
        || (ch == '(') || (ch == ')');
}

(5)IsBig( )

检查一个运算符的优先级是否大于另一个。
它用于确定从中缀表示法转换为后缀表示法时应重新排列运算符的顺序

bool IsBig(char ch0, char ch1) {
    switch (ch0) {
        case '+':
        case '-': return false;
            break;
        case '/':
        case '*': return (ch1 == '+') || (ch1 == '-');
            break;
        case '(': return (ch1 == '+') || (ch1 == '-')
                        || (ch1 == '*') || (ch1 == '/');
            break;
        default: cout << "Error!" << endl;
            return false;
    }
}

(6)FindValue( )

在给定的字符数组中查找计算数值(整数或小数)的值

int FindValue(float & value, const vector<char> & arr, int start) {
    int i, j, p; value = 0;
    bool isDecimal = false;
    float integer = 0, decimal = 0;

    for (i = start; i < arr.size() && (isdigit(arr[i]) || arr[i] == '.' || arr[i] == ' '); i++) {
        if (arr[i] == ' ') break;
        if (arr[i] == '.') { isDecimal = true; break; }
        integer = (integer * 10) + (arr[i] - '0');         
    }
    if (isDecimal == true) {
        for (j = i + 1, p = -1; j < arr.size() && isdigit(arr[j]); j++) {
            decimal += (arr[j] - '0') * pow(10.0, p);
            p--;
        }
    }
    value = integer + decimal;

    return isDecimal ? j - start - 1 : i - start - 1;
}

(7)TopFloat()

返回浮点数堆栈中的顶部值。

float TopFloat(stack<float> & s) {
    if (s.empty()) {
        cout << "Error!\n";
        return 0;
    } else {
        float temp = s.top(); s.pop();
        return temp;
    }
}

(8)SigComp( )

接受两个浮点数 ( x 和 y) 和一个op表示算术运算 ( ‘+’, ‘-’, ‘*’, ‘/’ ) 的字符运算符
然后执行相应的操作y并将结果作为 float 值返回

float SigComp(float x, float y, char op) {
    switch (op) {
        case '+': return x + y;
        case '-': return x - y;
        case '*': return x * y;
        case '/': return x / y;
        default: cout << "Error!\n";
            return 0;
    }
}

三、整体代码

#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstring>
#include <vector>
#include <string>
#include <stack>

using namespace std;

// Convert the infix expression entered by the 
// user into a suffix expression
void ConvertEnd(const string & front, vector<char> & end);

// Calculate the final value based on the suffix 
// expression from the ConvertEnd()
float Compute(const vector<char> & end);

// Return ture if ch equals 
//   '+'   '-'   '*'   '/'   '('   ')'
bool IsOp(char ch);

// Return ture if the proprity of ch0 is greater than ch1
bool IsBig(char ch0, char ch1);

// Read the number or decimal character after start and 
// convert it to a numberical value
int FindValue(float & value, const vector<char> & arr, int star);

// Return the top value in float stack 
// if the stack is not empty
float TopFloat(stack<float> & s);

// Preform a specified four arithmetic 
// operation on x and y
float SigComp(float x, float y, char op);

int main() {
    string front;
    vector<char> end;

    // Read input
    cout << "Enter the expression(q to quit): ";
    while (getline(cin, front) && front[0] != 'q') {
        if (!isdigit(front[0])) {
            cout << "Please enter the correct expression:";
            end.clear(); continue;
        }

        // Conver to the end format
        ConvertEnd(front, end);

        // Calculate the value
        cout << setiosflags(ios::fixed) << setprecision(2);
        cout << Compute(end) << endl;
        end.clear();
        cout << "Next expression(q to quit): ";
    }
    cout << "Bye!\n";
    return 0;
}

void ConvertEnd(const string & front, vector<char> & end) {
    stack<char> s;

    for (int i = 0; i < front.length(); i++) {
        if (isdigit(front[i]) || front[i] == '.') end.push_back(front[i]);
        else if (IsOp(front[i])) {
            end.push_back(' ');
            if (s.empty()) s.push(front[i]);
            else if (front[i] == ')') {
                while (s.top() != '(') {
                    end.push_back(s.top()); s.pop();
                } 
                s.pop();
            } else {
                if (IsBig(front[i], s.top())) s.push(front[i]);
                else {
                    while (!s.empty() && s.top() != '(' && !IsBig(front[i], s.top())) {
                        end.push_back(s.top()); s.pop();
                    }
                    s.push(front[i]);
                }
            }
        }
    }
    while (!s.empty()) {
       end.push_back(s.top()); s.pop();
    }
}

bool IsOp(char ch) {
    return (ch == '+') || (ch == '-') 
        || (ch == '*') || (ch == '/')
        || (ch == '(') || (ch == ')');
}

bool IsBig(char ch0, char ch1) {
    switch (ch0) {
        case '+':
        case '-': return false;
            break;
        case '/':
        case '*': return (ch1 == '+') || (ch1 == '-');
            break;
        case '(': return (ch1 == '+') || (ch1 == '-')
                        || (ch1 == '*') || (ch1 == '/');
            break;
        default: cout << "Error!" << endl;
            return false;
    }
}

float Compute(const vector<char> & end) {
    // Compute the value through the end format
    stack<float> s;

    for (int i = 0; i < end.size(); i++) {
        if (isdigit(end[i])) {
            float temp = 0;
            i += FindValue(temp, end, i);
            s.push(temp);
        } else if (IsOp(end[i])) {
            s.push(SigComp(TopFloat(s), TopFloat(s), end[i]));
        }
    }

    if (!s.empty()) {
        return s.top();
    } else { cout << "Error!\n"; return 0; }
}

int FindValue(float & value, const vector<char> & arr, int start) {
    int i, j, p; value = 0;
    bool isDecimal = false;
    float integer = 0, decimal = 0;

    for (i = start; i < arr.size() && (isdigit(arr[i]) || arr[i] == '.' || arr[i] == ' '); i++) {
        if (arr[i] == ' ') break;
        if (arr[i] == '.') { isDecimal = true; break; }
        integer = (integer * 10) + (arr[i] - '0');         
    }
    if (isDecimal == true) {
        for (j = i + 1, p = -1; j < arr.size() && isdigit(arr[j]); j++) {
            decimal += (arr[j] - '0') * pow(10.0, p);
            p--;
        }
    }
    value = integer + decimal;

    return isDecimal ? j - start - 1 : i - start - 1;
}

float TopFloat(stack<float> & s) {
    if (s.empty()) {
        cout << "Error!\n";
        return 0;
    } else {
        float temp = s.top(); s.pop();
        return temp;
    }
}

float SigComp(float x, float y, char op) {
    switch (op) {
        case '+': return x + y;
        case '-': return x - y;
        case '*': return x * y;
        case '/': return x / y;
        default: cout << "Error!\n";
            return 0;
    }
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值