牛客计算器的改良(Python版)


链接:https://ac.nowcoder.com/acm/contest/19306/1043
来源:牛客网

1.题目描述

NCL是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手ZL先生。为了很好的完成这个任务,ZL先生首先研究了一些一元一次方程的实例:
4+3x=8
6a-5+1=2-2a
-5+12y=0
ZL先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及+、-、=这三个数学符号(当然,符号“-”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。
你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。
编写程序,解输入的一元一次方程, 将解方程的结果(精确至小数点后三位)输出至屏幕。

2.输入描述:

一行字符串,即一个一元一次方程。

3.输出描述:

解方程的结果(精确至小数点后三位)。保证解的绝对值大于等于0.001

4.示例1

输入
复制
6a-5+1=2-2a
输出
复制
a=0.750

5.分析

首先看到这个题目如果从左到右很难解出(可能是我太差了)不好确定未知数以及运算符号,那么我们从右边往左边去识别,就比较容易判断运算符号和未知数,遇到小写字母就一直识别到遇到运算符为止,然后再将识别到的数字与运算符记录,如果是数字就直接识别直到遇到运算符终止识别,记录数字和运算符。当然了还需要初始化一个flag=1,如果是遇到了‘=’就令flag=-1,然后当每一个运算符被记录时都要乘以flag。整体思路有了,其他的就看细节了。

6.代码

def cout(s)://用于处理被识别的数字
    s = list(s)
    t = 0
    for i in range(len(s) - 1, -1, -1):
        t = t * 10 + int(s[i])
    # print(t,'t')
    return t
if __name__ == '__main__':
#     while True:
        s = list(map(str,input()))
        m = ['+', '-','=']
        num = 0
        zm = 0
        flag = 1
        para = 0
        i = len(s)
        ind=''
        while i > 0:
            ji = 0
            i-=1
            if 97 <= ord(s[i]) and ord(s[i]) <= 122://识别和处理未知数
                ind=s[i]//记录未知数
                zif = ''
                for j in range(i - 1, -1, -1)://一直循环直到遇到运算符
                    if s[j] == '-'://遇到运算符就终止,然后和数字一起处理,将参数和数字全部移到一边,所以遇到‘=’要变号,用flag记录
                        para += cout(zif) * -1 * flag
                        ji=1
                        break
                    if s[j] == '+':
                        para += cout(zif) * flag
                        ji=1
                        break
                    if s[j] == '=':
                        ji=1
                        para += cout(zif)*flag
                        flag = -1
                        break
                    if 0 <= int(s[j]) and int(s[j]) <= 9://是数字就记录
                        zif += s[j]
                if ji==0://特殊情况,如果未知数是第一个可能就没有运算符
                    para+=cout(zif)*flag
                i = j
                if i==0:
                    break
                if s[i-1]=='='://特殊情况,当遇到=-8a时我们要考虑两个运算符在一起时,‘=’要变号
                    flag=-1
                # print(s[i],'i')
            if s[i] in m://遇到运算符终止
                continue
            if i==0://如果遇到8+6a这种情况,直接将8记录节约时间
                num+=cout(s[i])*flag
                break
            ji=0
            if 0 <= int(s[i]) and int(s[i]) <= 9://识别纯数字
                zif1 = ''
                for k in range(i, -1, -1):
                    if s[k] == '-':
                        num += cout(zif1) *(-1) * flag
                        ji=1
                        break
                    if s[k] == '+':
                        num += cout(zif1) * flag
                        ji=1
                        break
                    if s[k] == '=':
                        num += cout(zif1)*flag
                        ji=1
                        flag = -1
                        break
                    if 0 <= int(s[k]) and int(s[k]) <= 9:
                        zif1 += s[k]
                if ji==0:
                    num+=cout(zif1)*flag
                i = k
                if i>0 and s[i-1]=='='://考虑6a=-5这种情况
                    flag=-1

        print('%c=%.3f'%(ind,(num*-1.0)/para))//因为这里是将参数和数字全部移到右边,所以最后运算要添个负号

7.结语

只是用于学习记录,代码写的比较烂,请大佬见谅,希望大佬多多指教

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会敲代码的破茧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值