问题标题: 调试

0
0
已解决
李致远
李致远
高级光能
高级光能

由于我的电脑网络比较差

烦请大家帮我康康这个代码可不可以正常运行

严禁抄袭!!!

//#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include "codingtang.h"
using namespace std;
const char NUM[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.'};
const char OPERATION[] = {'+', '-', '*', '/'};
const double PI = 3.14159265358979;
const double EE = 2.71828182818281;
class Fun { //处理**数学函数的类
public:
    Fun(string o, int t, double l = 0.0, double r = 0.0): op(o), type(t), lvalue(l), rvalue(r) {}
    static string FUN[];
    double calc();
private:
    int type; //666 0 1 sin90 2 3! 3 3C2
    string op; //函数类型
    double lvalue; //函数左边的值
    double rvalue; //函数右边的值
    static int FunNum;
};
int Fun::FunNum = 10;
string Fun::FUN[] = {"!", "sin", "cos", "tan", "log", "ln", "C", "A", "^", "-"};
/*
函数说明:
1:log是以10为底的工程对数
2:ln 是以e为底的自然对数
3:C 计算组合数 输入规则 如计算 3取2的组合 输入表达式 3C2
4:A 计算排列数 输入规则 如计算 3取2的排列 输入表达式 3A2
5:! 计算阶乘
6:^ x的y次方 输入 x^y
*/
int factorial(int n) { //阶乘函数
    int i, s = 1;

    for(i = 1; i <= n; i++)
        s *= i;

    return s;
}
int C(int a, int b) {
    return factorial(a) / (factorial(b) * factorial(a - b));
}
int A(int a, int b) {
    return factorial(a) / factorial(b);
}
double Fun::calc() { //计算**函数的值
    if(type == 0)
        return lvalue;
    else {
        if(op == "!")
            return factorial(lvalue);

        if(op == "sin")
            return sin(rvalue / 180 * PI);

        if(op == "cos")
            return cos(rvalue / 180 * PI);

        if(op == "tan")
            return tan(rvalue / 180 * PI);

        if(op == "log")
            return log10(rvalue);

        if(op == "ln")
            return log10(rvalue) / log10(EE);

        if(op == "C")
            return C(lvalue, rvalue);

        if(op == "A")
            return A(lvalue, rvalue);

        if(op == "^")
            return pow(lvalue, rvalue);

        if(op == "-")
            return -rvalue;
        else {
            cout << "暂时没有函数" ;
            return 0;
        }
    }
}
struct Unit { //双向链表保存运算单元
    Unit(int p, char o, string c, double v, int t, Unit * pr = NULL, Unit * n = NULL)
        : PRI(p), Operation(o), Code(c), value(v), Type(t), Pre(pr), Next(n) {}
    int PRI; //优先级
    char Operation; //**作符
    string Code; //原始代码
    double value; //数据
    int Type; //类型 **作符0 数据1 函数2
    Unit * Pre; //构成双向链表
    Unit * Next;
};
class Node { //表达式树状结构的节点
public:
    Node(char o, int p, int e = 1, double v = 0, Node * ph = NULL, Node * pl = NULL, Node * pr = NULL)
        : Operation(o), PRI(p), Expression(e), value(v), Head(ph), Left(pl), Right(pr) {}
    Node * Head; //节点的根,左树枝,右树枝
    Node * Left;
    Node * Right;
    double GetValue();
    char GetOperation() const {
        return Operation;
    }
    int GetPri() const {
        return PRI;
    }
    int IsExp() const {
        return Expression;
    }
private:
    char Operation; //**作符
    int PRI; //优先级
    int Expression; //记录该节点是否是表达式0 1
    double value; //该节点的值
};
double Node::GetValue() { //运算该节点的值
    if(IsExp()) { //该节点的值还未算出来
        double lvalue, rvalue;
        lvalue = Left->GetValue();
        rvalue = Right->GetValue();
        Expression = 0;
        char op = GetOperation();

        switch(op) {
        case '+':
            return lvalue + rvalue;

        case '-':
            return lvalue - rvalue;

        case '*':
            return lvalue * rvalue;

        case '/':
            return lvalue / rvalue;

        default:
            return 0;
        }
    } else
        return value;
}
bool Isnum(char c) {
    for(int i = 0; i < sizeof(NUM); i++) {
        if(c == NUM[i])
            return true;
    }

    return false;
}
bool Isoperation(char c) {
    for(int i = 0; i < sizeof(OPERATION); i++) {
        if(c == OPERATION[i])
            return true;
    }

    return false;
}
Unit * Analyse(string exp) { //分析表达式并生成链表
    int pri = 0; //当前优先级
    int stat = 1; //当前的读入状态 括号 0 运算符 1 其他 2
    Unit * head = NULL, * p = NULL;
    int i = 0, explen;
    explen = exp.size();

    for(i = 0; i < explen; i++) {
        char c = exp.at(i);

        if(c == '(') {
            pri += 3;
            stat = 0;
        } else if(c == ')') {
            pri -= 3;
            stat = 0;
        } else if(Isoperation(c) && stat != 1) { //**作符后的当正负号处理
            stat = 1;
            Unit * temp = p;
            int add_pri; //自身增加的优先级

            if(c == '+' || c == '-')
                add_pri = 1;
            else
                add_pri = 2;

            p->Next = new Unit(pri + add_pri, c, " ", 0, 0);
            p = p->Next;
            p->Pre = temp;
        } else { //其他的当做函数处理
            stat = 2;
            string function = "";

            while(i < explen && (c = exp.at(i), ! Isoperation(c)) && c != ')') {
                function += c;
                i++;
            }

            i--;

            if(head == NULL) {
                p = new Unit(pri, ' ', function, 0, 2);
                head = p;
            } else {
                Unit * temp = p;
                p->Next = new Unit(pri, ' ', function, 0, 2);
                p = p->Next;
                p->Pre = temp;
            }
        }
    }

    return head;
}
Unit * Calc(Unit * head) { //计算双向链表基本单元的值
    Unit * p = head;

    while(p != NULL) {
        if(p->Type != 0) { //非**作符
            string temp = p->Code;
            string op;
            double lvalue = 0, rvalue = 0;
            int l_point = 0, r_point = 0;
            int i = 0, type = 0;
            char ch;

            while(i < temp.size() && (ch = temp.at(i), Isnum(ch))) {
                if(ch == '.') {
                    l_point++;
                    i++;
                    continue;
                }

                if(! l_point)
                    lvalue *= 10;

                lvalue += (ch - '0') * pow(10, -l_point);
                i++;

                if(l_point)
                    l_point++;
            }

            while(i < temp.size() && (ch = temp.at(i), ! Isnum(ch))) {
                op += ch;
                type = 1;
                i++;
            }

            while(i < temp.size() && (ch = temp.at(i), Isnum(ch))) {
                if(ch == '.') {
                    r_point++;
                    i++;
                    continue;
                }

                if(! r_point)
                    rvalue *= 10;

                rvalue += (ch - '0') * pow(10, -r_point);
                i++;

                if(r_point)
                    r_point++;
            }

            Fun * f = new Fun(op, type, lvalue, rvalue);
            p->value = f->calc();
        }

        p = p->Next;
    }

    return head;
}
Node * Tree(Unit * head) { //生成表达式树
    Node * root = NULL, * proot = NULL, * pbranch = NULL;
    Unit * p = head;
    int now_pri; //当前优先级
    bool hadop = false;

    while(p != NULL) {
        if(p->Type == 0) { //如果是一个**作符
            hadop = true;

            if(root == NULL) {
                proot = new Node(p->Operation, p->PRI, 1);
                root = proot;
                pbranch = root;
                now_pri = p->PRI;
                proot->Left = new Node(' ', 0, 0, p->Pre->value);
                proot->Right = new Node(' ', 0, 0, p->Next->value);
            } else {
                if(p->PRI < now_pri) { //优先级低于当前优先级,树根方向
                    proot = new Node(p->Operation, p->PRI, 1); //新的树根
                    proot->Left = root; //根的变换
                    proot->Left->Head = proot;
                    proot->Right = new Node(' ', 0, 0, p->Next->value);
                    proot->Right->Head = proot;
                    root = proot;
                    pbranch = proot; //右树枝的变换
//pbranch->Right=new Node(' ',0,0,p->Pre->value); //树枝右边取值
                } else if(p->PRI == now_pri) { //优先级相同,先算左边的
                    Node * temp;
                    temp = new Node(p->Operation, p->PRI, 1);
                    temp->Left = pbranch;

                    if(pbranch->Head == NULL) {
                        proot = temp;
                        root = proot;
                        pbranch->Head = proot;
                    } else {
                        Node * temp0;
                        temp0 = pbranch->Head;
                        temp0->Right = temp;
                        temp->Head = temp0;
                        pbranch->Head = temp;
                    }

                    pbranch = temp;
                    pbranch->Right = new Node(' ', 0, 0, p->Next->value);
                    pbranch->Right->Head = pbranch;
                } else {
                    Node * temp;
                    temp = new Node(p->Operation, p->PRI, 1);
                    pbranch->Right = temp;
                    temp->Head = pbranch;
                    pbranch = pbranch->Right;
                    pbranch->Left = new Node(' ', 0, 0, p->Pre->value);
                    pbranch->Left->Head = pbranch;
                    pbranch->Right = new Node(' ', 0, 0, p->Next->value);
                    pbranch->Right->Head = pbranch;
                }

                now_pri = p->PRI;
            }
        }

        p = p->Next;
    }

    if(! hadop)
        root = new Node(' ', 0, 0, head->value);

    return root;
}
int main(void) {
    string exp;
    createConsole("函数计算器");
    cout << "简易函数计算器" << endl;
    cout << "函数说明: " << endl << 
            "1: log是以10为底的工程对数" << endl << 
            "2: ln 是以e为底的自然对数" << endl << 
            "3: C 计算组合数 输入规则 如计算 3取2的组合 输入表达式 3C2" << endl << 
            "4: A 计算排列数 输入规则 如计算 3取2的排列 输入表达式 3A2" << endl << 
            "5: ! 计算阶乘" << endl << 
            "6: ^ x的y次方 输入 x^y" << endl;

    while(! getline(cin, exp).eof()) {
        if(exp == "")
            continue;

        Unit * h = Analyse(exp);
        h = Calc(h);
        Node * root = Tree(h);
        cout << exp << "=" << root->GetValue() << endl;
    }

    return 0;
}
//createConsole("文本游戏");  

如果可以,我就分享啦︿( ̄︶ ̄)︿


0
已采纳
李锦昊
李锦昊
中级天翼
中级天翼

可以,我用DEV-C++试的

删了两行代码

显示:

简易函数计算器
函数说明:
1: log是以10为底的工程对数
2: ln 是以e为底的自然对数
3: C 计算组合数 输入规则 如计算 3取2的组合 输入表达式 3C2
4: A 计算排列数 输入规则 如计算 3取2的排列 输入表达式 3A2
5: ! 计算阶乘
6: ^ x的y次方 输入 x^y

 

李锦昊在2021-08-12 11:18:46追加了内容

也可以

0
我要回答