| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 977 人关注过本帖
标题:万用计算器函数,接受数学算式字符串为参数——考虑运算顺序、可无限嵌套括 ...
只看楼主 加入收藏
taozztzz
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:85
专家分:180
注 册:2008-12-21
结帖率:83.33%
收藏
 问题点数:0 回复次数:0 
万用计算器函数,接受数学算式字符串为参数——考虑运算顺序、可无限嵌套括号、支持加、减、乘、除、乘方运算!
使用方法:long SzCal(const char* const sz), 其中sz为算式,如"15+6" "589*78"等。乘方符号为^, 如2的16次方表示为"2^16"。
            返回值为运算结果。例: long lResult = SzCal("(1*(5-6)+4)^3"); // lResult == 27

代码如下(头文件<cmath>):
由于是以字符串为参数,所以无论是console还是windows程序都能使用,只是一些console标准流的输出在windows程序中需稍稍修改(如cerr改为MessageBox)。
需声明using namespace std;


const long SzCal(const char* const sz)
{
    int i = 0;
    return SzCal(sz, i);
}
const long SzCal(const char* const sz, int& i)
{
    long n1 = 0, n2 = 0;
    char szTemp[500] = {0};
    int j = 0, k = 0;
    char op = 0;
   
    if (sz[i] == '(')                    // 若是左括号,则递归处理,并将括号值付给操作数1
    {
        i++;
        n1 = SzCal(sz, i);
    }
    else
    {
        for (j = 0; isdigit(sz[i]); i++, j++)                    // 读入操作数1
            szTemp[j] = sz[i];
        szTemp[j] = '\0';
        n1 = atol(szTemp);
    }

    while (sz[i] != '\0' && sz[i] != ')')
    {
        op = sz[i];                    // 获取运算符
        i++;

        if (sz[i] == '(')                    // 若是左括号,则递归处理,并将括号值付给操作数2
        {
            i++;
            n2 = SzCal(sz, i);
        }
        else
        {
            for (j = 0; isdigit(sz[i]); i++, j++)                    // 读入操作数2
                szTemp[j] = sz[i];
            szTemp[j] = '\0';
            n2 = atol(szTemp);
        }
        
        switch (op)                    // 运算
        {
            case '+':
                DoAdd(sz, i, n1, n2);
                break;
            case '-':
                DoSubtract(sz, i, n1, n2);
                break;
            case '*':
                DoMultiply(sz, i, n1, n2);
                break;
            case '/':
                DoDivide(sz, i, n1, n2);
                break;
            case '%':
                DoMod(sz, i, n1, n2);
                break;
            case '^':
                n1=pow((double)n1, (double)n2);
                break;
            default:
                cerr << "\aError: Operator error \n";
                exit(1);
        }
    }

    i += sz[i] == ')' ? 1 : 0;                    // 跳过右括号

    return n1;
}

void DoMultiply(const char* const sz, int& i, long& n1, long& n2)
{
    long n3 = 0;
    int j = 0;
    char op = 0;
    char szTemp[500] = {0};

    if (sz[i] == '^')                    // ^的优先级更高
    {
        op = sz[i];
        
        while (op == '^')
        {
            i++;
            if (sz[i] == '(')
                n3 = SzCal(sz, i);
            else
            {
                for (j=0; isdigit(sz[i]); i++, j++)
                    szTemp[j] = sz[i];
                szTemp[j] = '\0';
                n3 = atol(szTemp);
            }
            n2 = pow((double)n2, (int)n3);
            op = sz[i];
        }
        n1 *= n2;
    }
    else
        n1 *= n2;
}

void DoDivide(const char* const sz,int& i, long& n1, long& n2)
{   
    long n3 = 0;
    int j = 0;
    char op = 0;
    char szTemp[500] = {0};

    if (sz[i] == '^')                    // ^的优先级更高
    {
        op = sz[i];
        
        while (op == '^')
        {
            i++;
            if (sz[i] == '(')
                n3 = SzCal(sz, i);
            else
            {
                for (j = 0; isdigit(sz[i]); i++, j++)
                    szTemp[j] = sz[i];
                szTemp[j] = '\0';
                n3 = atol(szTemp);
            }
            n2 = pow((double)n2, (int)n3);
            op = sz[i];
        }
        if (n2 == 0)
        {
            cerr << "\aError: Divided error \n";
            exit(1);
        }
        n1 /= n2;
    }
    else
    {
        if (n2 == 0)
        {
            cerr << "\aError: Divided error \n";
            exit(1);
        }
        n1 /= n2;   
    }
}

void DoAdd(const char* const sz, int& i, long& n1, long& n2)
{
    long n3 = 0;
    int j = 0;
    char op = 0;
    char szTemp[500] = {0};

    if (sz[i] == '*' || sz[i] == '/' || sz[i] == '%' || sz[i] == '^')
    {
        op = sz[i];

        while (sz[i] == '*' || sz[i] == '/' || sz[i] == '%' || sz[i] == '^')
        {
            i++;
            if (sz[i] == '(')
                n3 = SzCal(sz, i);
            else
            {
                for (j = 0; isdigit(sz[i]); i++, j++)
                    szTemp[j] = sz[i];
                szTemp[j] = '\0';
                n3 = atol(szTemp);
            }

            switch (op)
            {
                case '*':
                    DoMultiply(sz, i, n2, n3);
                    break;
                case '/':
                    DoDivide(sz, i, n2, n3);
                    break;
                case '%':
                    DoMod(sz, i, n2, n3);
                    break;
                case '^':
                    n2 = pow((double)n2, (int)n3);
                    break;
            }
            op = sz[i];
        }
        n1 += n2;
    }
    else
        n1 += n2;
}

void DoSubtract(const char* const sz, int& i, long& n1, long& n2)
{
    long n3 = 0;
    int j = 0;
    char op = 0;
    char szTemp[500] = {0};

    if (sz[i] == '*' || sz[i] == '/' || sz[i] == '%' || sz[i] == '^')
    {
        op = sz[i];

        while (sz[i] == '*' || sz[i] == '/' || sz[i] == '%' || sz[i] == '^')
        {
            i++;
            if (sz[i] == '(')
                n3 = SzCal(sz, i);
            else
            {
                for (j = 0; isdigit(sz[i]); i++, j++)
                    szTemp[j] = sz[i];
                szTemp[j] = '\0';
                n3 = atol(szTemp);
            }

            switch (op)
            {
                case '*':
                    DoMultiply(sz, i, n2, n3);
                    break;
                case '/':
                    DoDivide(sz, i, n2, n3);
                    break;
                case '%':
                    DoMod(sz, i, n2, n3);
                    break;
                case '^':
                    n2 = pow((double)n2, (int)n3);
                    break;
            }
            op = sz[i];
        }
        n1 -= n2;
    }
    else
        n1 -= n2;
}

void DoMod(const char* const sz, int& i, long& n1, long& n2)
{
    long n3 = 0;
    int j = 0;
    char op = 0;
    char szTemp[500] = {0};

    if (sz[i] == '^')                    // ^的优先级更高
    {
        op = sz[i];
        
        while (op == '^')
        {
            i++;
            if (sz[i] == '(')
                n3 = SzCal(sz, i);
            else
            {
                for (j = 0; isdigit(sz[i]); i++, j++)
                    szTemp[j] = sz[i];
                szTemp[j] = '\0';
                n3 = atol(szTemp);
            }
            n2 = pow((double)n2, (int)n3);
            op = sz[i];
        }
        if (n2 == 0)
        {
            cerr << "\aError: Divided error \n";
            exit(1);
        }
        n1 %= n2;
    }
    else
    {
        if (n2 == 0)
        {
            cerr << "\aError: Mod error \n";
            exit(1);
        }
        n1 %= n2;   
    }
}
搜索更多相关主题的帖子: 数学 算式 嵌套 乘方 计算器 
2010-02-19 23:34
快速回复:万用计算器函数,接受数学算式字符串为参数——考虑运算顺序、可无限嵌 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017599 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved