• 【C语言刷LeetCode】592. 分数加减运算(M)


    给定一个表示分数加减运算的字符串 expression ,你需要返回一个字符串形式的计算结果。 

    这个结果应该是不可约分的分数,即最简分数。 如果最终结果是一个整数,例如 2,你需要将它转换成分数形式,其分母为 1。所以在上述例子中, 2 应该被转换为 2/1。

    示例 1:

    输入: expression = "-1/2+1/2"
    输出: "0/1"
     示例 2:

    输入: expression = "-1/2+1/2+1/3"
    输出: "1/3"
    示例 3:

    输入: expression = "1/3-1/2"
    输出: "-1/6"
     

    提示:

    输入和输出字符串只包含 '0' 到 '9' 的数字,以及 '/', '+' 和 '-'。 
    输入和输出分数格式均为 ±分子/分母。如果输入的第一个分数或者输出的分数是正数,则 '+' 会被省略掉。
    输入只包含合法的最简分数,每个分数的分子与分母的范围是  [1,10]。 如果分母是1,意味着这个分数实际上是一个整数。
    输入的分数个数范围是 [1,10]。
    最终结果的分子与分母保证是 32 位整数范围内的有效整数。

    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/fraction-addition-and-subtraction
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    思想就是分母相乘,然后计算分子,最后同时除以最大公约数。但细节很多,首先是首字符的正负号处理,然后取出分子,跳一位再接着取分母。

    这种题好几个点都做错了:

    1. sprintf中 %d%d 误写成 %s%s,导致crash

    2. 求最大公约数,分子忘了求绝对值

    3. 这种辗转相除法求最大公约数的方法要记住

    4. isdigit 判断字符是否是十进制数,不是的话返回值是0

    5. 分子是0的情况需要特殊判断,可以直接返回一个字符串

    6. sign 运算符初始化为1,lastmu上一次分母初始化为1, 这两个不要初始化为0了

    7. 用 long long

    辗转相除法求公约数

    (1)对于已知的两个数a,b

    (2)a除以b余数r

    (3)若r=0,则b就是所求的最大公约数,否则执行(4)

    (4)令a=b,b=r;重复执行(4)

    1. /*
    2. 辗转相除法求公约数
    3. (1)对于已知的两个数a,b
    4. (2)a除以b余数r
    5. (3)若r=0,则b就是所求的最大公约数,否则执行(4)
    6. (4)令a=b,b=r;重复执行(4)
    7. */
    8. int Getgys(int a, int b) // 求最大公约数
    9. {
    10. int re = a % b;
    11. while (re != 0) {
    12. a = b;
    13. b = re;
    14. re = a % b;
    15. }
    16. return b;
    17. }
    18. char * fractionAddition(char * expression){
    19. int len = strlen(expression);
    20. int i;
    21. long long fenzi = 0;
    22. long long fenmu = 0;
    23. long long lastzi = 0;
    24. long long lastmu = 1;
    25. int sign = 1; // 正数还是负数
    26. char *retarr = malloc(sizeof(char) * 70);
    27. int maxgys = 1;
    28. memset(retarr, 0, sizeof(char) * 70);
    29. while (i < len) { // 为什么选择while,因为循环内有很多 i++操作,while比for更合适
    30. fenzi = 0;
    31. fenmu = 0;
    32. sign = 1;
    33. if (isdigit(expression[i]) == 0) { // 首字符如果不是数字
    34. sign = expression[i] == '+' ? 1 : -1;
    35. i++;
    36. }
    37. // 取分子
    38. while (i < len && isdigit(expression[i])) {
    39. fenzi = fenzi * 10 + expression[i] - '0';
    40. i++;
    41. }
    42. fenzi = fenzi * sign; // 把符号算进去
    43. i++; // 跳过 '/'
    44. // 取分母
    45. while (i < len && isdigit(expression[i])) {
    46. fenmu = fenmu * 10 + expression[i] - '0';
    47. i++;
    48. }
    49. lastzi = lastzi * fenmu + fenzi * lastmu;
    50. lastmu = fenmu * lastmu;;
    51. }
    52. if (lastzi == 0) { // 分子为0情况,需要特殊讨论,陷阱!!!
    53. return "0/1"; // 直接返回字符串就行,不用传到retarr里
    54. }
    55. maxgys = Getgys(abs(lastzi), lastmu); // 求最大公约数,需要记住模板
    56. sprintf(retarr, "%d/%d", lastzi/maxgys, lastmu/maxgys);
    57. return retarr;
    58. }

  • 相关阅读:
    django对比数据并调用企业微信接口群发
    .NET餐厅管理系统user数据帮助类查询、找回密码、添加管理员
    从入门开始手把手搭建千万级Java算法测试-计算X的n次幂两种方法比较
    【AI落地应用实战】如何高效检索与阅读论文——302.AI学术论文工具评测
    什么是原生IP?原生IP与住宅IP有何区别?
    JVM(二)
    计算机网络基础知识这一篇就够了
    【AAAI2022】Efficient Non-Local Contrastive Attention for Image Super-Resolution
    【C++】内存管理
    【云原生进阶之PaaS中间件】第一章Redis-1.5.1安装配置
  • 原文地址:https://blog.csdn.net/jin615567975/article/details/126066315