计算化学公社

 找回密码 Forget password
 注册 Register
Views: 3817|回复 Reply: 6
打印 Print 上一主题 Last thread 下一主题 Next thread

[C/C++] 请问大拿这道题该怎么写?

[复制链接 Copy URL]

609

帖子

2

威望

4351

eV
积分
5000

Level 6 (一方通行)

跳转到指定楼层 Go to specific reply
楼主
怎么用C++实现下面这道题?
写一个计算器,支持三个运算数。
比如用户输入 2 * 3 + 2,应输出:8
注意要保证乘除先运算。没有括号。



1043

帖子

0

威望

4112

eV
积分
5155

Level 6 (一方通行)

2#
发表于 Post on 2019-9-18 20:50:46 来自手机 | 只看该作者 Only view this author
首先parse输入字符串为5个fields,第1,3,5个转为数字a,b,c,第2,4个是运算符x,y。因为一共只有两个运算,所以很容易比较出先算axb还是先算byc

138

帖子

0

威望

443

eV
积分
581

Level 4 (黑子)

3#
发表于 Post on 2019-9-19 10:42:30 | 只看该作者 Only view this author
(1) 先将a保存在一个数组中,然后读入符号
(2) 判断符号是加减还是乘除
      如果是乘除:直接运算数组最后一位与新加入数字的乘积然后替换数组最后一位
      如果是加减:将新加入的数字添加到数组最后
(3) 全部读取完毕后累加整个数组

以你的题目为例,数组如下一步步变化:
[2]
[6]
[6,2]

以1+2*3+4*5为例:
[1]
[1,2]
[1,6]
[1,6,4]
[1,6,20]
上海交通大学计算化学与分子生物信息学实验室
Shanghai JiaoTong University
Computational Chemistry and Molecular Bioinformatics Laboratory

CCMBI of SJTU
点击访问个人主页

545

帖子

0

威望

3125

eV
积分
3670

Level 5 (御坂)

4#
发表于 Post on 2019-9-19 11:13:14 | 只看该作者 Only view this author
就加减和乘除两个优先级的话你压个栈就好了啊。加减就压栈,乘除就弹出上一个,算数,再压进去。然后最后再把栈内元素累加。
哦你就算仨数,那算了。

3622

帖子

3

威望

1万

eV
积分
18442

Level 6 (一方通行)

第一原理惨品小作坊

5#
发表于 Post on 2019-9-20 10:07:55 | 只看该作者 Only view this author
存3个数字和2个足矣,能计算任意长度的计算。这里用python写了个草稿在上面加了注释。C++版本和Fortran90版本放在附件里面,尽管编程语言不同编程的思想没啥差别。当然python确实有更简单的做法,当然最简单的大概就是exec或ast.literal_eval了,那也就没啥好讨论的了。
  1. #作者:卡开发发
  2. #日期:2019-9-20
  3. #计算加减乘除


  4. #给定a、b两个数和当中的计算符号,返回计算结果。
  5. def calc(a,string,b):
  6.         if string=='+':
  7.                 return a+b
  8.         if string=='-':
  9.                 return a-b
  10.         if string=='*':
  11.                 return a*b
  12.         if string=='/':
  13.                 return a/b

  14. #键盘输入获取计算的表达式。
  15. string=input('input the expression:')
  16. #保存三个数和两个符号,
  17. #例如a+b*c会被保存为tmp=[a,b,c],sign=['+','*']。
  18. tmp=[0,0,0]
  19. sign=['+','+']

  20. #遍历所输入的字符串
  21. for i in range(len(string)):
  22.         s=string[i]
  23.         #遇到数字就x10+新的数字,这样就将连续的数字构成的字符数组转化为数字,
  24.         #即'abc..'=str(10*(10*a+b)+c...)
  25.         #通过ASCII来判断是否为数字。
  26.         if ord(s)>=48 and ord(s)<=57:
  27.                 tmp[2]=float(tmp[2]*10+ord(s)-48)
  28.         #遇到符号就对前面三个数和两个符号进行计算。
  29.         if s=='*' or s=='/'or s=='+' or s=='-':
  30.                 #如果第二个符号是乘除号,直接计算这乘法,
  31.                 #这样就相当于将tmp[1]和tmp[2]还有sign[1]合并为一个新的tmp[2]。
  32.                 #例如a+b*c+d...,表示为tmp=[a,b,c],sign=['+','*'],
  33.                 #现在遇到字符是第三个符号'+',则计算b*c,
  34.                 #计算后的结果就变成了tmp=[a,a,b*c],sign=['+','+']。
  35.                 if sign[1]=='*' or sign[1]=='/':
  36.                         tmp[2]=calc(tmp[1],sign[1],tmp[2])
  37.                         tmp[1]=tmp[0]
  38.                         sign[1]=sign[0]
  39.                 else:
  40.                         #如果两个符号都是加减号,直接计算第一个加减法,
  41.                         #这样就相当于将tmp[0]和tmp[1]还有sign[0]合并为一个新的tmp[1]。
  42.                         #例如a+b+c*d...,表示为tmpp=[a,b,c],sign=['+','+'],
  43.                         #现在遇到字符是第三个符号'*',则计算a+b,
  44.                         #计算后结果变成tmp=[a,a+b,c],sign=['+','+']。
  45.                         if (sign[1]=='+' or sign[1]=='-') and \
  46.                         (sign[0]=='+' or sign[0]=='-'):
  47.                                 tmp[1]=calc(tmp[0],sign[0],tmp[1])
  48.                 #扔掉tmp[0]和sign[0],
  49.                 #tmp[2]设置为0用来存放新的数字,
  50.                 #sign[1]用来存放当前读取到的符号。
  51.                 tmp[0]=tmp[1]
  52.                 tmp[1]=tmp[2]
  53.                 tmp[2]=0
  54.                 sign[0]=sign[1]
  55.                 sign[1]=s

  56. #读取到字符串末尾后,表达式就会变成三个数的运算。
  57. #如果加号在前面,如a+b*c,先计算b*c,其余情况按照顺序计算。
  58. if sign[0]=='+' or sign[0]=='-':
  59.         result=calc(tmp[0],sign[0],calc(tmp[1],sign[1],tmp[2]))
  60. else:
  61.         result=calc(calc(tmp[0],sign[0],tmp[1]),sign[1],tmp[2])
  62. #输出计算结果。
  63. print(string+'='+str(result))
复制代码
calculator.f90 (1.18 KB, 下载次数 Times of downloads: 1)

calculator.cpp (1.14 KB, 下载次数 Times of downloads: 2)
日常打哑谜&&探寻更多可能。
原理问题不公开讨论,非商业性质讨论欢迎私聊。
本周忙

1043

帖子

0

威望

4112

eV
积分
5155

Level 6 (一方通行)

6#
发表于 Post on 2019-9-20 12:19:15 来自手机 | 只看该作者 Only view this author
卡开发发 发表于 2019-9-20 10:07
存3个数字和2个足矣,能计算任意长度的计算。这里用python写了个草稿在上面加了注释。C++版本和Fortran90版 ...

还得考虑输入数字可能是浮点数和负数吧?

3622

帖子

3

威望

1万

eV
积分
18442

Level 6 (一方通行)

第一原理惨品小作坊

7#
发表于 Post on 2019-9-20 12:51:20 | 只看该作者 Only view this author
本帖最后由 卡开发发 于 2019-9-20 13:19 编辑
granvia 发表于 2019-9-20 12:19
还得考虑输入数字可能是浮点数和负数吧?

负数不影响,浮点数的话就把读取数字部分做一下处理就行了,没有多复杂。22行下面:
  1. sign=['+','+']
  2. frac=False
  3. frac_len=0
复制代码
30行下面:
  1.     if ord(s)>=48 and ord(s)<=57 or s=='.':
  2.         if s=='.':
  3.             frac=True
  4.             s='0'
  5.         if not frac:
  6.             tmp[2]=float(tmp[2]*10+ord(s)-48)
  7.         else:
  8.             tmp[2]=float(tmp[2]+(ord(s)-48)/10**frac_len)
  9.             frac_len+=1
复制代码
57行下面:
  1.         tmp[2]=0
  2.         frac=False
  3.         frac_len=0
复制代码

其他语言的代码修改思路是一样的,就不再写一遍了。


日常打哑谜&&探寻更多可能。
原理问题不公开讨论,非商业性质讨论欢迎私聊。
本周忙

本版积分规则 Credits rule

手机版 Mobile version|北京科音自然科学研究中心 Beijing Kein Research Center for Natural Sciences|京公网安备 11010502035419号|计算化学公社 — 北京科音旗下高水平计算化学交流论坛 ( 京ICP备14038949号-1 )|网站地图

GMT+8, 2024-11-27 13:56 , Processed in 0.185354 second(s), 24 queries , Gzip On.

快速回复 返回顶部 返回列表 Return to list