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

春节刷题计划(三)| 一题双解,搞定求解方程

你好,我是朱涛。初二过年好!
在上节课里,我给你留了一个作业,那就是:用 Kotlin 来完成 LeetCode 的 640 号题《求解方程》。那么这节课,我就来讲讲我的解题思路,我们互相学习。
这道题也非常容易理解,程序的输入是一个“一元一次方程”,我们需要根据输入的方程,计算出正确的结果。根据输入方程的不同,结果可能有三种情况:
方程仅有一个解,这时,我们只需要按照格式返回结果即可,比如输入“2x=4”,那么输出就应该是“x=2”。
方程有无数个解,比如输入“x=x”,那么输出就应该是“Infinite solutions”。
方程无解,比如输入“x=x+5”,那么输出结果就应该是“No solution”。
另外,对于程序的输入格式,其实我们还有几个问题需要弄清楚。只有弄清楚了这些问题,我们才能开始写代码:
方程当中的未知数只会用 x 表示,不会是 y,也不会是大写的“X”。
方程当中不会出现空格,比如“2x=4”,不会出现“2x = 4 ”的情况。
方程当中只会有加减法,不会出现乘除法。
方程当中的数字,一定是整数,不会出现分数、小数。
输入的方程一定是一个正确的方程,不会出现“x=…”之类的脏数据。
好,问题的细节都弄清楚了,下面我们来分析一下解题的思路。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何使用Kotlin编写程序来解决一元一次方程的求解问题。作者首先解释了方程的三种可能情况:有一个解、无数个解和无解,并明确了输入方程的格式要求。然后,作者详细阐述了解题思路,包括移项、合并同类项和系数化为一等三个步骤。接着,作者提供了两种解法:命令式和函数式,并分别给出了代码示例。在命令式解法中,作者使用了分割等号、遍历左右两边的等式、移项和合并同类项等步骤来完成方程的求解。最后,作者总结了整体的代码逻辑,并展示了偏函数式的代码写法。整体而言,本文通过清晰的解题思路和具体的代码示例,帮助读者了解了如何使用Kotlin解决一元一次方程的求解问题。文章还对比了命令式和函数式两种解法的优劣,指出了函数式代码逻辑相对清晰、运用了大量Kotlin库函数且不容易出错的优势。读者可以通过本文快速了解Kotlin解决一元一次方程问题的两种实现方式,并根据自身需求选择合适的方法。

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

全部留言(5)

  • 最新
  • 精选
  • qinsi
    尝试用正则分割 ```kotlin // 根据“+”、“-”分割式子 private fun splitByOperator(list: String) = list.split(Regex("(?=[+-])")).filter { it.isNotEmpty() } ``` 或者 ```kotlin // 根据“+”、“-”分割式子 private fun splitByOperator(list: String): Sequence<String> = Regex("""[+-]?(\d*x|\d+)""").findAll(list).map { it.value } ```

    作者回复: 这种思路也很巧妙,值得大家学习。

    2022-02-02
    1
  • 郑峰
    ```Kotlin fun fractionAddition(expression: String): String { // Split the expression to several pairs of numerator and denominator val numbers = expression .replace("-", "+-") .split("+") .filter { it.isNotEmpty() } .map { it.split("/").take(2).map(String::toInt) } // Calculate the lcm of all denominators val rawDenominator = numbers.map { it[1] }.fold(1) { x, y -> lcm(x, y) } // Calculate the sum of all numerators val rawNumerator = numbers.sumOf { it[0] * rawDenominator / it[1] } // Reformat numerator and denominator through their gcd val gcd = abs(gcd(rawNumerator, rawDenominator)) val denominator = rawDenominator / gcd val numerator = rawNumerator / gcd return "$numerator/$denominator" } fun gcd(x: Int, y: Int): Int = if (y == 0) x else gcd(y, x % y) fun lcm(x: Int, y: Int): Int = x * y / gcd(x, y) ```

    作者回复: 这代码很不错,比我提供的解法更加的简洁。这种不拘泥与特定编程范式,并且融合双方优势的写法,看起来真的很舒服。

    2022-02-02
    2
    1
  • 白乾涛
    fun solveEquation(equation: String): String { // x+5-3+2x=6+x-2 var xCount = 0 // 移到左边的 x 系数之和 var addValue = 0 // 移到右边的数字之和 val equalIndex = equation.indexOf('=') // 等号的位置 var i = 0 while (i < equation.length) { val fromIndex = i if (i == 0) { i++ } for (j in i until equation.length) { val c: Char = equation[j] if (c == '+' || c == '-' || c == '=') { break } i++ } var subString = equation.substring(if (fromIndex == 0) fromIndex else fromIndex - 1, i) subString = if (subString.startsWith("=")) subString.substring(1) else subString println("值为:$subString") if (subString.endsWith("x")) { subString = subString.substring(0, subString.length - 1) val tempCount = if (subString.isEmpty()) 1 // x else { if (subString.length == 1 && (subString.startsWith("+") || subString.startsWith("-"))) { // +x 或 -x if (subString[0] == '+') 1 else -1 } else subString.toInt() // +5x 或 5x 或 53x 或 -2x } xCount = if (i > equalIndex) xCount - tempCount else xCount + tempCount // 左正右负 } else if (subString.isNotEmpty()) { // 过滤掉 = 产生的一个空字符串 val tempValue = subString.toInt() addValue = if (i > equalIndex) addValue + tempValue else addValue - tempValue // 左负右正 } i++ } println("结果:${xCount}x = $addValue") return if (xCount == 0) if (addValue == 0) "Infinite solutions" else "No solution" else "x=" + addValue / xCount }

    作者回复: 很符合直觉的思路,不过略显繁琐。

    2022-03-02
  • Geek_Adr
    符号处理复杂了,其它与 @郑峰 略同 // 分数的数据结构 symbol为-1 1 // 注意分子/分母为正整数 data class Fraction(val numerator: Int, val denominator: Int, val symbol: Int) fun fractionAddition(expression: String): String { return expression.replace("-", "+-") // "-"前增加+,方便split处理 .split("+") // 按"+"分隔 .filter { it.isNotBlank() } // 去掉可能为空的部分 .map { // 处理成分数实例 var symbol = if (it.startsWith("-")) -1 else 1 val ss = it.replace("-", "").split("/") Fraction(ss[0].toInt(), ss[1].toInt(), symbol) }.run { // 算出分母的最小公倍数,作为分母 val denominator = map { it.denominator }.reduce { a, b -> lcm(a, b) } // 按最小公倍数计算分子结果 var numerator = map { it.symbol * it.numerator * denominator / it.denominator }.reduce { a, b -> a + b } val symbol = if (numerator < 0) -1 else 1 numerator *= symbol // 转正 val gcd = gcd(numerator, denominator) // 结果可能可约分 Fraction(numerator / gcd, denominator / gcd, symbol) }.run { "${if (symbol < 0) "-" else ""}${numerator}/${denominator}" } } // 最小公倍数 private fun lcm(m: Int, n: Int): Int { return m * n / gcd(m, n) } // 最大公约数 private fun gcd(m: Int, n: Int): Int { return if (m % n == 0) n else gcd(n, m % n) }

    作者回复: 代码写的挺好的,大家可以参考看看。

    2022-02-20
  • 春夏秋冬
    class Solution { fun solveEquation(equation: String): String = equation.split("=") .map(this::statistics) .calculate() private fun statistics(expr: String): Pair<Int, Int> = expr.replace("-", "+-") .split("+") .fold(Pair(0, 0)) { ans, s -> if (s.contains("x")) { ans.copy(first = ans.first + s.substring(0, s.length-1).toValue()) } else { ans.copy(second = ans.second + if (s.isEmpty()) { 0 } else {s.toValue()}) } } private fun String.toValue(): Int = when(this) { "" -> 1 "-" -> -1 else -> this.toInt() } private fun List<Pair<Int,Int>>.calculate(): String { val left = this[0] val right = this[1] return if (left.first == right.first) { if (left.second == right.second) "Infinite solutions" else "No solution" } else { val x = left.first - right.first val v = right.second - left.second "x=${v / x}" } } }
    2022-11-05归属地:北京
收起评论
显示
设置
留言
5
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部