当前位置:   article > 正文

【华为OD机试真题2023 C&D卷 Python&C++】符号运算_od考c++可以使用python答题吗

od考c++可以使用python答题吗

华为OD2023(C&D卷)机试题库全覆盖,刷题指南点这里

符号运算

时间限制:1s 空间限制:32MB 限定语言:不限

题目描述:

给定一个表达式,求其分数计算结果 
 

表达式的限制如下:

1. 所有的输入数字皆为正整数(包括0)

2. 仅支持四则运算(+-*/)和括号

3. 结果为整数或分数, 分数必须化为最简格式(比如6, 3/4, 7/8, 90/7)

4. 除数可能为0,如果遇到这种情况,直接输出"ERROR"

5. 输入和最终计算结果中的数字都不会超出整型范围

用例的输入一定合法, 不会出现括号不匹配的情况

输入描述:

字符串格式的表达式,仅支持+-*/,数字可能超过两位,可能带有空格,没有负数

长度小于200个字符

输出描述:

表达式结果,以最简格式表达
如果结果为整数,那么直接输出整数

如果结果为分数,那么分子分母不可再约分,可以为假分数,不可表达为带分数

结果可能是负数, 负号放在最前面

示例1

输入:

1 + 5 * 7 / 8

输出:

43/8

示例2

输入:

1 / (0 - 5)

输出:

-1/5

说明:

负号需要提到最前面

示例3

输入:

1 * (3*4/(8-(7+0)))

输出:

12

说明:

注意括号可以多重嵌套

解题思路:

这道题主要还是在处理分数逻辑上有点乱。需要求最小公倍数和最大公约数来处理分子分母。我们的算法思路就是将所有的数字全部转化为分数,在分数的基础上进行加减乘除。

代码(Python):

  1. from collections import deque
  2. def main():
  3. #str = input()
  4. str = '1 / 2 / 3 / 4 / (5 / 6) / 7 / 8 / 9 / 10'
  5. len_str = len(str)
  6. deque_str = deque()
  7. num = ''
  8. isError = False
  9. for i in range(len_str):
  10. c = str[i]
  11. # 如果是数字
  12. if c.isdigit():
  13. num += c
  14. if i == len_str - 1:
  15. # 判断符号
  16. fuhao = deque_str[-1] if deque_str else ''
  17. # 如果符号是乘除,则需要计算
  18. if fuhao == '*' or fuhao == '/':
  19. if fuhao == '/' and num == '0':
  20. isError = True
  21. break
  22. fuhao = deque_str.pop()
  23. deque_str.append(jisuan(deque_str.pop(), fuhao, num))
  24. else:
  25. deque_str.append(num)
  26. elif c == '(':
  27. deque_str.append(c)
  28. elif c == ')':
  29. if num == '':
  30. sum = deque_str.pop()
  31. else:
  32. sum = num
  33. num = ''
  34. while deque_str[-1] != '(':
  35. fuhao = deque_str.pop()
  36. temp = deque_str.pop()
  37. sum = jisuan(temp, fuhao, sum)
  38. # 左括号删除
  39. deque_str.pop()
  40. # 判读左括号前的符号
  41. fuhao = deque_str[-1] if deque_str else ''
  42. # 如果符号是乘除,则需要计算
  43. if fuhao and (fuhao == '*' or fuhao == '/'):
  44. if fuhao == '/' and sum == '0':
  45. isError = True
  46. break
  47. fuhao = deque_str.pop()
  48. deque_str.append(jisuan(deque_str.pop(), fuhao, sum))
  49. else:
  50. deque_str.append(sum)
  51. elif c == ' ':
  52. continue
  53. else:
  54. # 判断符号
  55. fuhao = deque_str[-1] if deque_str else ''
  56. # 如果符号是乘除,则需要计算
  57. if fuhao and (fuhao == '*' or fuhao == '/'):
  58. if fuhao == '/' and num == '0':
  59. isError = True
  60. break
  61. fuhao = deque_str.pop()
  62. deque_str.append(jisuan(deque_str.pop(), fuhao, num))
  63. elif num != '':
  64. deque_str.append(num)
  65. # 本次的符号也需要加入
  66. deque_str.append(c)
  67. # num置空
  68. num = ''
  69. if isError:
  70. print('ERROR')
  71. else:
  72. res = deque_str.popleft()
  73. while deque_str:
  74. res = jisuan(res, deque_str.popleft(), deque_str.popleft())
  75. print(res)
  76. def jisuan(a, fuhao, b):
  77. as_ = zhuanhua(a)
  78. aFZ = int(as_[0])
  79. aFM = int(as_[1])
  80. bs = zhuanhua(b)
  81. if fuhao == '/':
  82. # 除号需要倒置分子分母
  83. bFZ = int(bs[1])
  84. bFM = int(bs[0])
  85. else:
  86. bFZ = int(bs[0])
  87. bFM = int(bs[1])
  88. # 最小公约数
  89. yueshu, fenzi, fenmu = 0, 0, 0
  90. if fuhao == '*' or fuhao == '/':
  91. fenzi = aFZ * bFZ
  92. fenmu = aFM * bFM
  93. else:
  94. gongbeishu_ = gongbeishu(aFM, bFM)
  95. fenmu = gongbeishu_
  96. aFZ = gongbeishu_ // aFM * aFZ
  97. bFZ = gongbeishu_ // bFM * bFZ
  98. if fuhao == '+':
  99. fenzi = aFZ + bFZ
  100. else:
  101. fenzi = aFZ - bFZ
  102. if fenzi == 0:
  103. return '0'
  104. max_ = max(abs(fenmu), abs(fenzi))
  105. min_ = min(abs(fenmu), abs(fenzi))
  106. yueshu = zuixiaogongyueshu(max_, min_)
  107. fenzi = fenzi // yueshu
  108. fenmu = fenmu // yueshu
  109. if fenzi % fenmu == 0:
  110. return str(fenzi // fenmu)
  111. else:
  112. if fenmu < 0:
  113. # 分母是负数,则需要将负号移到分子
  114. fenmu = -fenmu
  115. fenzi = -fenzi
  116. return str(fenzi) + '/' + str(fenmu)
  117. # 将数字转化为分子分母格式
  118. def zhuanhua(shuzi):
  119. shuzis = shuzi.split('/')
  120. szFenzi = shuzis[0]
  121. szFenmu = shuzis[1] if len(shuzis) == 2 else '1'
  122. return [szFenzi, szFenmu]
  123. def zuixiaogongyueshu(a, b):
  124. while a % b != 0:
  125. b = a % b
  126. return b
  127. def gongbeishu(a, b):
  128. gongyueshu = zuixiaogongyueshu(a, b)
  129. return a // gongyueshu * b // gongyueshu * gongyueshu
  130. if __name__ == '__main__':
  131. main()

代码(C++):

  1. #include <iostream>
  2. #include <deque>
  3. #include <sstream>
  4. using namespace std;
  5. string jisuan(string a, string fuhao, string b);
  6. string* zhuanhua(string shuzi);
  7. int zuixiaogongyueshu(int a, int b);
  8. int gongbeishu(int a, int b);
  9. int main() {
  10. string str;
  11. getline(cin, str);
  12. //string str = "1 / 2 / 3 / 4 / (5 / 6) / 7 / 8 / 9 / 10";
  13. int len = str.length();
  14. deque<string> deque;
  15. string num = "";
  16. bool isError = false;
  17. for (int i = 0; i < len; i++) {
  18. char c = str[i];
  19. //如果是数字
  20. if (isdigit(c)) {
  21. num += c;
  22. if (i == len - 1) {
  23. //判断符号
  24. string fuhao = deque.back();
  25. //如果符号是乘除,则需要计算
  26. if (fuhao == "*" || fuhao == "/") {
  27. if (fuhao == "/" && num == "0") {
  28. isError = true;
  29. break;
  30. }
  31. fuhao = deque.back();
  32. deque.pop_back();
  33. deque.push_back(jisuan(deque.back(), fuhao, num));
  34. } else {
  35. deque.push_back(num);
  36. }
  37. }
  38. } else if (c == '(') {
  39. deque.push_back(string(1, c));
  40. } else if (c == ')') {
  41. string sum;
  42. if (num == "") {
  43. sum = deque.back();
  44. deque.pop_back();
  45. } else {
  46. sum = num;
  47. num = "";
  48. }
  49. while (deque.back() != "(") {
  50. string fuhao = deque.back();
  51. deque.pop_back();
  52. string temp = deque.back();
  53. deque.pop_back();
  54. sum = jisuan(temp, fuhao, sum);
  55. }
  56. //左括号删除
  57. deque.pop_back();
  58. //判读左括号前的符号
  59. string fuhao = deque.back();
  60. //如果符号是乘除,则需要计算
  61. if (fuhao != "" && (fuhao == "*" || fuhao == "/")) {
  62. if (fuhao == "/" && sum == "0") {
  63. isError = true;
  64. break;
  65. }
  66. fuhao = deque.back();
  67. deque.pop_back();
  68. deque.push_back(jisuan(deque.back(), fuhao, sum));
  69. } else {
  70. deque.push_back(sum);
  71. }
  72. } else if (c == ' ') {
  73. continue;
  74. } else {
  75. //判断符号
  76. string fuhao = deque.back();
  77. //如果符号是乘除,则需要计算
  78. if (fuhao != "" && (fuhao == "*" || fuhao == "/")) {
  79. if (fuhao == "/" && num == "0") {
  80. isError = true;
  81. break;
  82. }
  83. fuhao = deque.back();
  84. deque.pop_back();
  85. deque.push_back(jisuan(deque.back(), fuhao, num));
  86. } else if (num != "") {
  87. deque.push_back(num);
  88. }
  89. //本次的符号也需要加入
  90. deque.push_back(string(1, c));
  91. //num置空
  92. num = "";
  93. }
  94. }
  95. if (isError) {
  96. cout << "ERROR" << endl;
  97. } else {
  98. string res = deque.front();
  99. deque.pop_front();
  100. while (!deque.empty()) {
  101. res = jisuan(res, deque.front(), deque[1]);
  102. deque.pop_front();
  103. deque.pop_front();
  104. }
  105. cout << res << endl;
  106. }
  107. return 0;
  108. }
  109. string jisuan(string a, string fuhao, string b) {
  110. string* as = zhuanhua(a);
  111. int aFZ = stoi(as[0]);
  112. int aFM = stoi(as[1]);
  113. string* bs = zhuanhua(b);
  114. int bFZ, bFM;
  115. if (fuhao == "/") {
  116. //除号需要倒置分子分母
  117. bFZ = stoi(bs[1]);
  118. bFM = stoi(bs[0]);
  119. } else {
  120. bFZ = stoi(bs[0]);
  121. bFM = stoi(bs[1]);
  122. }
  123. //最小公约数
  124. int yueshu, fenzi, fenmu;
  125. if (fuhao == "*" || fuhao == "/") {
  126. fenzi = aFZ * bFZ;
  127. fenmu = aFM * bFM;
  128. } else {
  129. int gongbeishu = gongbeishu(aFM, bFM);
  130. fenmu = gongbeishu;
  131. aFZ = gongbeishu / aFM * aFZ;
  132. bFZ = gongbeishu / bFM * bFZ;
  133. if (fuhao == "+") {
  134. fenzi = aFZ + bFZ;
  135. } else {
  136. fenzi = aFZ - bFZ;
  137. }
  138. }
  139. if (fenzi == 0) {
  140. return "0";
  141. }
  142. int max = max(abs(fenmu), abs(fenzi));
  143. int min = min(abs(fenmu), abs(fenzi));
  144. yueshu = zuixiaogongyueshu(max, min);
  145. fenzi = fenzi / yueshu;
  146. fenmu = fenmu / yueshu;
  147. if (fenzi % fenmu == 0) {
  148. return to_string(fenzi / fenmu);
  149. } else {
  150. if (fenmu < 0) {
  151. //分母是负数,则需要将负号移到分子
  152. fenmu = -fenmu;
  153. fenzi = -fenzi;
  154. }
  155. return to_string(fenzi) + '/' + to_string(fenmu);
  156. }
  157. }
  158. string* zhuanhua(string shuzi) {
  159. stringstream ss(shuzi);
  160. string* shuzis = new string[2];
  161. getline(ss, shuzis[0], '/');
  162. if (ss.peek() != EOF) {
  163. getline(ss, shuzis[1], '/');
  164. } else {
  165. shuzis[1] = "1";
  166. }
  167. return shuzis;
  168. }
  169. int zuixiaogongyueshu(int a, int b) {
  170. while (a % b != 0) {
  171. b = a % b;
  172. }
  173. return b;
  174. }
  175. int gongbeishu(int a, int b) {
  176. int gongyueshu = zuixiaogongyueshu(a, b);
  177. return a / gongyueshu * b / gongyueshu * gongyueshu;
  178. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/853980?site
推荐阅读
相关标签
  

闽ICP备14008679号