c语言解一元一次方程(及一元高次方程)

c语言解一元一次方程(及一元高次方程)

首先,这里使用的方法是中缀表达式转后缀表达式,其次代码中紧展示了一元一次方程的解法过程,但是一元高次方程和该方法是同样的原理,

目录
第一部分:中缀转后缀
第二部分:方程的解法向中缀表达式的转换(本文重点)

第一部分:中缀转后缀表达式
中缀表达式转后缀表达式的逻辑参考下面链接:中缀转后缀,这里防止链接失效,再copy了一份
如下:

1.初始化两个栈:运算符栈s1和储存中间结果的栈s2;
2.从左至右扫描中缀表达式;
3.遇到操作数时,将其压s2;
4.遇到运算符时,比较其与s1栈顶运算符的优先级:
 (1)如果s1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
 (2)否则,若优先级比栈顶运算符的高,也将运算符压入s1;
 (3)否则,将s1栈顶的运算符弹出并压入到s2中,再次转到(4.1)与s1中新的栈顶运算符相比较;
5.遇到括号时: 
(1)如果是左括号"(",则直接压入s1 
(2)如果是右括号")",则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃6.重复步骤2至5,直到表达式的最右边
7.将s1中剩余的运算符依次弹出并压入s2
8.依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式
案例分析:
将中缀表达式 “1+((2+3)*4)-5” 转换为后缀表达式的过程如下:
在这里插入图片描述

下面是我写的c代码
注意:我写的代码中并没有对负号和减号进行区分,只能识别减号,出现负号的话将会出错,可以在负号前加个0解决这个问题;并且表达式中只能出现整数,不可以出现小数

double ToSuffixExpression(char* buf)   //buf指需要传进去的字符串表达式
{
    double number[50];   //数字栈
    char op[50] = {'\0'};   //运算符栈
    int m = 0, n = 0;   //m是number的栈顶,n是运算符栈顶
    int i = 0;
    while(buf[i] != '\0')
    {
        if(isdigit(buf[i]))    //遇到数字的处理方式
        {
            int temp = buf[i] - '0';
            while(isdigit(buf[i+1]))
            {
                temp *= 10;
                temp += buf[++i] - '0';
            }
            number[m++] = (double)temp;
        }
        else if(buf[i] == '+' || buf[i] == '-' || buf[i] == '*' || buf[i] == '/')   //是操作符的处理方式
        {
            if(n == 0 || op[n-1] == '(')   //步骤4.1的处理
                op[n++] = buf[i];
            else if((buf[i] == '*' || buf[i] == '/') && (op[n-1] == '+' || op[n-1] == '-'))   //步骤4.2的处理
                op[n++] = buf[i];
            else   //步骤4.3的处理
            {   //这里不将操作符推入数字栈,而是直接将局部结果计算出来
                if(op[n-1] == '+')
                    number[m-2] += number[m-1];
                else if(op[n-1] == '-')
                    number[m-2] -= number[m-1];
                else if(op[n-1] == '*')
                    number[m-2] *= number[m-1];
                else
                    number[m-2] /= number[m-1];
                op[--n] = '\0';
                --m;
                continue;
            }
        }
        else if(buf[i] == '(' || buf[i] == ')')    //是'('和')'的处理方式
        {
            if(buf[i] == '(')   //步骤5.1的处理
                op[n++] = '(';
            else   //步骤5.2的处理
            {   //这里不将操作符推入数字栈,而是直接将局部结果计算出来
                while(op[n-1] != '(')
                {
                    if(op[n-1] == '+')
                        number[m-2] += number[m-1];
                    else if(op[n-1] == '-')
                        number[m-2] -= number[m-1];
                    else if(op[n-1] == '*')
                        number[m-2] *= number[m-1];
                    else
                        number[m-2] /= number[m-1];
                    op[--n] = '\0';
                    --m;
                }
                op[--n] = '\0';
            }
        }
        ++i;
    }
    while(n > 0)
    {   //这里不将操作符推入数字栈,而是直接将局部结果计算出来
        if(op[n-1] == '+')
            number[m-2] += number[m-1];
        else if(op[n-1] == '-')
            number[m-2] -= number[m-1];
        else if(op[n-1] == '*')
            number[m-2] *= number[m-1];
        else
            number[m-2] /= number[m-1];
        --m;
        --n;
    }
    return number[0];   //正确运行的话number栈肯定只有一个数字
}

第二部分:方程向中缀表达式的转换
步骤一:将方程等号右侧全部移到等号左侧,变成等号右侧为0的形式。这一步很简单。
步骤二:如果能把方程化简成ax+b=0的形式问题就解决了,将步骤一的等号左侧表达式所有变量赋值成0,变成一个新的中缀表达式,经过ToSuffixExpression()计算的结果就是b。同样的方法,再将所有的变量赋值成1计算一次,计算结果记作sum,那么a = sum - b,问题解决。

#include <stdio.h>
#include <ctype.h>
double ToSuffixExpression(char* buf);
int main()
{
    char var;
    char buf[100] = {'\0'}, buf1[100] = {'\0'}, buf2[100] = {'\0'};
    //buf1是将变量赋值成1的字符串,buf2是将变量赋值成0的字符串
    gets(buf);
    /*去除表达式的空格*/
    // int p = 0, q = 0;
    // while(buf[p] != '\0')
    // {
    //     while(buf[p] == ' ') ++p;
    //     buf[q++] = buf[p++];
    // }
    // buf[q] = '\0';
    /*上述注释代码是去掉表达式中的空格,如果表达式有空格,就不可以注释*/
    int i = 0, loc1 = 0, loc2 = 0;
    if(buf[0] == '-')
    {
        buf1[loc1++] = '0';
        buf2[loc2++] = '0';
    }
    while(buf[i] != '\0')
    {
        if(isalpha(buf[i]))
        {
            var = buf[i];     //var字符记录变量名
            if(i == 0 || (i > 0 && !isdigit(buf[i-1])))    //处理当前位置是字母(未知数),但是前一个字符不是数字,也即自变量的系数是1省略的情况
            {
                buf1[loc1++] = '1';    //直接将该变量换成1
                buf2[loc2++] = '0';    //直接将该变量换成0
            }
            else       //自变量的系数不是1的情况
            {
                buf1[loc1++] = '*';
                buf1[loc1++] = '1';
                buf2[loc2++] = '*';
                buf2[loc2++] = '0';
            }
        }
        else if(buf[i] == '=')   //当前位置是'='的情况
        {
            buf1[loc1++] = '-';
            buf1[loc1++] = '(';
            buf2[loc2++] = '-';
            buf2[loc2++] = '(';
            if(buf[i+1] == '-' || buf[i+1] == '+')   //如果等号后第一个符号是负号'-'或正号'+',在其前加一个0
            {
                buf1[loc1++] = '0';
                buf2[loc2++] = '0';
            }
        }
        else if(buf[i] == '(' && (buf[i+1] == '-' || buf[i+1] == '+'))   //如果出现"(-"或者"(+",在中间加个'0'
        {
            buf1[loc1++] = '(';
            buf2[loc2++] = '(';
            buf1[loc1++] = '0';
            buf2[loc2++] = '0';
        }
        else
        {
            buf1[loc1++] = buf[i];
            buf2[loc2++] = buf[i];
        }
        ++i;
    }
    buf1[loc1] = ')';   //末尾加')'
    buf2[loc2] = ')';
    //printf("%s\n", buf1);   //打印变量变成1的表达式
    //printf("%s\n", buf2);   //打印变量变成0的表达式
    double sum = ToSuffixExpression(buf1);
    double b = ToSuffixExpression(buf2);
    double a = sum - b;
    printf("%c=%.3f\n",var, (-b/a));
    return 0;
}

举个例子,运行结果如下:
在这里插入图片描述
通过一元一次方程的解法,可以拓展一下,高次方程也可以进行赋值0或1来计算各项系数。
在这里插入图片描述
通过上述赋值方式,可以计算a = sum1 - c,b = sum2 - c,然后使用二次函数的求根公式即可。

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值