课程设计题一:四则变量表达式计算

该博客介绍了如何实现一个简单的计算程序,它能接收单字符变量名及其数值,构建线性表,并处理包含四则运算的表达式。程序通过中缀表达式转后缀表达式的方法进行计算,支持括号和优先级处理。同时提出了扩展功能,如增加绝对值、平方根、最大值和最小值等函数计算的思考。
摘要由CSDN通过智能技术生成

输入一组单字符变量名及其对应数值存入线性表,再输入一个关于这些变量的四则运算表达式,代入其数值计算表达式的最终结果并显示。

设计要求:

1.单字符变量名与取值必须成对输入某结构体元素,再建立这些元素构成的线性表。

2.变量名与取值输入后立即显示变量信息,如“A=3,B=6,……”。

3.四则运算表达式必须以一个完整的字符串输入后,计算得出最终结果并显示。比如,运行阶段“(A+B)*3 回车”后,换行显示“=27”。

4.思考:若为四则运算增添函数计算功能,使其支持绝对值函数abs()、平方根函数sqr()、较大值函数max()、较小值函数min()等,表达式如A+abs(C+D)+max(E,F),应如何处理整个计算过程?
代码:

#include<stdio.h>
#include<string.h>
#define Size 30
#define OK 1
#define ERROR 0

typedef struct
{
    char elem;
    int data;

}sqlist;//定义一个线性表储存变量值
sqlist arr[Size];

typedef struct stack
{
    char data[Size];
    int top;
}sqstack;

栈的基本操作

void Inition(sqstack* s)//初始化栈
{
    s->top = -1;
}
void push(sqstack* s, char elem)//入栈
{
    s->top++;
    s->data[s->top] = elem;

}
char pop(sqstack* s)//出栈
{

    return s->data[s->top--];
}

比较运算符优先级

int Judge(char a, char b)
{
    //判断两个运算符优先级
    int value1, value2;
    value1 = value2 = 0;
    switch (a)
    {
    case '(':value1 = 1; break;
    case '+':value1 = 3; break;
    case '-':value1 = 3; break;
    case '*':value1 = 5; break;
    case '/':value1 = 5; break;
    case '^':value1 = 7; break;
    case ')':value1 = 9; break;
    }
    switch (b)
    {
    case '(':value2 = 1; break;
    case '+':value2 = 3; break;
    case '-':value2 = 3; break;
    case '*':value2 = 5; break;
    case '/':value2 = 5; break;
    case '^':value2 = 7; break;
    case ')':value2 = 9; break;
    }
    //优先级a<b则ERROR
    if (value1 <= value2)
        return ERROR;
    else
        return OK;
}

后缀表达式求值

int SuffixValue(sqstack* s1, sqstack* s2)//后缀表达式求值
{
    int e;
    while (s1->top > -1)
    {
        push(s2, pop(s1));//转出后缀表达式
    }
    while (s2->top > -1)
    {
        while (s2->data[s2->top] >= 0 && s2->data[s2->top] <= 9)
        {
            push(s1, pop(s2));
        }
        if (s2->data[s2->top] == '+')
        {
            (s2->top)--;
            e = pop(s1) + pop(s1);
            push(s1, e);
        }
        else if (s2->data[s2->top] == '-')
        {
            (s2->top)--;
            e = pop(s1);
            push(s1, pop(s1) - e);
        }
        else if (s2->data[s2->top] == '*')
        {
            (s2->top)--;
            e = pop(s1) * pop(s1);
            push(s1, e);
        }
        else if (s2->data[s2->top] == '/')
        {
            (s2->top)--;
            e = pop(s1);
            push(s1, pop(s1) / e);
        }

    }
    return s1->data[s1->top];//返回最终计算结果
}

主函数实现将算式表达式转化成操作数和运算符,放入栈中,完成中缀转后缀。

int main()
{
    sqstack* opt=(sqstack*)malloc(sizeof(sqstack));
    sqstack* exp=(sqstack*)malloc(sizeof(sqstack));//申请内存
    char str[Size];
    int value;
    int k=0;
    int a,flag;
    flag=0;
    Inition(opt);
    Inition(exp);
    printf("往线性表里输入数据\n");
    for(;k<Size;k++)
    {
        scanf(" %c %d", &arr[k].elem, &arr[k].data);
        printf("%c=%d\n", arr[k].elem, arr[k].data);
        printf("输入1继续输数据");
         scanf("%d",&a);
        if(a!=1)
        {
            printf("跳出循环\n");
            break;
        }

    }



    printf("输入一个表达式\n");
   scanf("%s", str);
    for (int i = 0; i < strlen(str); i++)
    {
        for (int j = 0; j < Size; j++)
        {
            if (str[i] == arr[j].elem)
            {
                str[i] = arr[j].data;//给表达式里的变量赋值
                break;
            }

        }
    }

    for (int i = 0; i < strlen(str); i++)
    {
        if (str[i] == '(')
            push(exp, str[i]);
        else if (str[i] >= 0 && str[i] <= 9)
            push(opt, str[i]);//操作数直接进栈
        else if (str[i] == ')')
        {

            do
            {

                if(exp->data[exp->top] != '(')
                push(opt,pop(exp));
                 else
                 {
                     exp->top--;//括号不能进opt栈
                     flag=1;

                 }

            }while(flag==0);

        }
        else
        {
            if (Judge(str[i], exp->data[exp->top]) == 0)
            {
                push(opt, pop(exp));
                break;
            }
            if (Judge(str[i], exp->data[exp->top]) == 1)
            {
                push(exp, str[i]);
            }
        }
    }
    while (exp->top >= 0)
    {
        push(opt, pop(exp));

    }//清空exp栈
    value = SuffixValue(opt, exp);
    printf("表达式的值:\n");
    printf("%d\n", value);


}

calculator.cpp 能够实现四则运算和乘方运算、赋值及报错的计算器 2018-12-4 -------------------------------------------------- 本程序的输入有三类:指令、赋值语句和计算式 这三类输入均允许在基本元素之间添加任意数目的空格 当出现错误时,本程序会显示Error并给出报错原因 ·指令 指令包含以下三个 exit 退出程序 printvar 输出所有已定义的变量及其值 emptyvar 清除所有变量 所有变量名不能与指令重名 ·赋值语句 基本格式为 变量名=数值 其中“数值”可以是一行计算式 ·计算式 所有非指令和赋值语句都会作为计算式进行计算 本程序可以对输入的一行计算式的值进行计算并输出答案 按照目要求,若结果为整数,将输出整数;若结果为浮点数,将保留两位小数 计算式中可以包含变量、数字和运算符号 计算式直接以运算符开头会报错“出现连续的运算符”,但如果以+-直接开头会被认作数的正负符号 -------------------------------------------------- 输入的基本元素包括变量、数字和运算符号 ·变量变量名必须以字母或下划线开头,由字母、数字或下划线组成,不能与指令重名 ·数字 可以是整数或者小数,当然也包括用/表示的分数 暂不支持除十进制外其他进制的输入 支持.23这样的省略整数部分0的输入 支持32.这样的输入 但是.不会被认为是0而会报错 ·运算符号 包括 加号+ 减号- 乘号* 除号/ 括号( ) 乘方^ 其中除数不能为零 乘方的底数是负数时,指数需要是整数 零的零次幂没有意义 -------------------------------------------------- 请注意 请在输入时务必使用英文输入或选择半角字符! 当语句中出现多个错误时,只会提示最先发现的错误 与c/c++表达式计算不同的地方: 本程序输出时会将整数相除产生的浮点数自动进行类型转换成浮点数,也会将浮点数运算得到的整数自动类型转换成整数,也就是说1/2=0.50,2.0/1.0=2(c++的自动取整真的很蠢) c/c++为了避免与函数冲突,不允许a(b+c),2(3+1)这样的写法,而本程序会默认在括号前进行了乘法运算,即2(3+1)=2*(3+1)=8,a(b+c)=a*(b+c) cmath中的pow函数对于0的0次方会返回1,但是0的0次方是没有意义的,本程序会对0^0报错 鉴于c++支持+-+-+-1=-1,但是出现连+或连-时会报错的混乱情况,本程序允许在数字和变量前加一个+或-号用来变号,即2+-1 3*-x -3++2是支持的,但是多于一个的额外+-号将报错,即3+-+2 +-1是不支持的 --------------------------------------------------
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值