朱涛 · Kotlin 编程第一课
朱涛
Google 认证的 Kotlin、Android 开发者专家,博客“Kotlin Jetpack 实战”作者
6717 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
朱涛 · Kotlin 编程第一课
15
15
1.0x
00:00/00:00
登录|注册

春节刷题计划(四)| 一题三解,搞定分式加减法

你好,我是朱涛。今天是初四了,在过年的节日氛围里你还能来坚持学习,这里也跟优秀的你说声感谢。
在上节课里呢,我给你留了一个作业:用 Kotlin 来完成 LeetCode 的 592 号题《分数加减运算》。那么今天这节课,我们就一起来看看它的解题思路吧。
这其实也是一道典型的模拟题,分式的加减法这样的题目,我们小学就知道怎么做了,核心解题思路主要是这几步:
第一步,求出分母的最小公倍数。比如,2 和 3 的最小公倍数就是 6。
第二步,根据计算出来的最小公倍数,将分数进行通分。举个例子:“1/2-1/6”,如果把它们两个通分,就会变成“3/6-1/6”。
第三步,将分子进行加减法,计算出分子的结果。比如,“3/6-1/6”计算过后,就会变成“2/6”。
最后一步,将计算结果转换成“最简分数”,比如“2/6”化成最简分数以后,应该是“1/3”。
经过这四个步骤,我们就可以计算出“1/2-1/6=1/3”。不过呢,这道题里,我们除了要计算分数的加减法以外,还要先完成分数的解析。程序的输入是字符串“1/2-1/6”,但它是不会帮我们自动解析的,所以,解析这一步也需要我们来做。
所以,自然而然地,我们就会定义一个分数的数据类 Expression
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Kotlin编程技术:解决分式加减法问题 本文介绍了在春节刷题计划中,通过三种解法来搞定分式加减法的题目。作者首先介绍了问题的解题思路,然后分别给出了命令式和函数式两种解法的代码实现。在命令式解法中,作者详细解释了分割式子、解析分数、计算最小公倍数、通分、最简化分数等步骤,并给出了相应的代码实现。而在函数式解法中,作者通过使用Kotlin的函数式编程特性,将代码进行了重构,提高了可读性。同时,作者还介绍了辅助函数的实现逻辑。通过对比两种解法,读者可以了解到命令式和函数式两种编程思路在解决问题时的不同表现。整体而言,本文通过实际的代码实现,展示了如何利用Kotlin来解决分式加减法的问题,为读者提供了一种技术上的思路和范例。 解法三的稳定性优化避免了溢出问题,通过动图和代码示例展示了优化思路。作者对比了三种解法的可读性、时间复杂度、空间复杂度和溢出情况,指出了各自的优劣势。最后,作者鼓励读者将本文视为Kotlin刷题的起点,强调了Kotlin在不同编程范式下的优势。整体而言,本文深入浅出地介绍了Kotlin在解决算法问题时的灵活应用,为读者提供了宝贵的学习资源。 文章通过实例和对比分析,生动展现了Kotlin在解决分式加减法问题中的灵活运用,对读者学习Kotlin编程和算法解题具有一定的启发意义。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《朱涛 · Kotlin 编程第一课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(5)

  • 最新
  • 精选
  • 白乾涛
    老师好,我对方法二又做了一些修改,主要是将一堆临时方法去掉了,老师帮忙看看这种思维合不合适 fun fractionAddition(expression: String): String { var lcm: Int // 分母的最小公倍数 val addValue = expression.replace("-", "+-") // 分子加减运算的结果 .split("+") .filter { it.trim() != "" } .map { Expression(it) } // 将 String 集合转换为 Expression 集合 .also { list -> lcm = list.map { it.denominator }.reduce(::lcm) } // 最小公倍数 ① .map { it.numerator * lcm / it.denominator } // 分子通分 .reduce { a, b -> a + b } //将所有的分子相加 val gcd = gcd(abs(addValue), lcm) // 分子和分母的最大公约数 println("$lcm $addValue $gcd") return "${addValue / gcd}/${lcm / gcd}" // 简化分数 } data class Expression(val exp: String, var numerator: Int = 0, var denominator: Int = 1) { init { exp.trim() .split("/") .takeIf { it.size == 2 } ?.let { numerator = it[0].toInt(); denominator = it[1].toInt() } } }

    作者回复: 很妙,init代码段用的挺好~ PS:作为算法题解很好,生产环境还是不推荐这么写数据类哈。

    2022-03-05
    1
  • 白乾涛
    感觉用kotlin刷题意义不大,因为kotlin新增的那么多语法、特性,以及协程,都用不上,这样子的kotlin没啥优势

    作者回复: 当我们必须刷题的时候,我会更喜欢Kotlin,而不是Java,它能帮我们熟悉Kotlin的基础语法、集合API,其实这就够了。 其实,你说的也很对,要灵活运用Kotlin的特性,刷题是不够的,刷题只能打基础。丰富的语言特性,只能去实战项目当中去运用。

    2022-03-03
    1
  • jim
    朱涛老师,这个系列可以单独开一个课程,非常期待

    作者回复: 感谢你的认可,将来有机会的话,我会考虑写点相关的博客出来的。

    2022-02-07
    1
  • Geek_473933
    fun fractionAddition(expression: String): String { var lcm: Int return expression .replace("-", "+-") .split("+") .filter { it.isNotBlank() } .map { it.split("/").let { list -> list[0].toInt() to list[1].toInt() } }.also { list -> lcm = list.map { it.second }.reduce(::lcm) }.sumOf { it.first * lcm / it.second }.let { val gcd = gcd(abs(it), lcm) val pair = it / gcd to lcm / gcd "${pair.first}/${pair.second}" } } //最小公倍数 fun lcm(x: Int, y: Int): Int = x * y / gcd(x, y) //最大公约数 fun gcd(x: Int, y: Int): Int = if (y == 0) x else gcd(y, x % y)
    2023-01-16归属地:福建
  • 春夏秋冬
    class Solution { fun fractionAddition(expression: String): String = expression.replace("-", "+-") .split("+").filter { it.isNotEmpty() } .map(this::toPair) .fold(Pair(0, 1), this::sum) .string() private fun toPair(expr: String): Pair<Int, Int> = expr.split("/").let { Pair(it[0].toInt(), it[1].toInt()) } private fun sum(a: Pair<Int, Int>, b: Pair<Int, Int>): Pair<Int,Int> = lsm(a.second, b.second).let { Pair( it/a.second * a.first + it/b.second * b.first, it ) }.small() private fun gcd(a: Int, b: Int): Int = if (a % b == 0) b else gcd(b, a % b) private fun lsm(a: Int, b: Int): Int = a * b /gcd(a, b) private fun Pair<Int, Int>.small() = gcd(this.first, this.second).let { val abs = abs(it) Pair(this.first / abs, this.second / abs) } private fun Pair<Int, Int>.string() = "${this.first}/${this.second}" }
    2022-11-05归属地:北京
收起评论
显示
设置
留言
5
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部