You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从多项式字符串中提取系数?技术实现求助

提取多项式系数的可靠实现方案

我之前也踩过用split处理多项式系数的坑——这种分割方式很难覆盖x一次项、常数项、缺项这些边界情况,用正则表达式匹配每一项再逐个解析会靠谱很多。下面给你梳理完整的实现思路和代码:

核心难点梳理

要解决这个问题,得覆盖所有可能的项格式:

  • 高次项:比如7x^4、-3x^3
  • 一次项:x(系数为1)、-x(系数为-1)、2x
  • 常数项:5、-8
  • 缺项:多项式里未出现的次数,对应系数要填0

解决方案:正则匹配+逐项解析

步骤1:用正则捕获所有项的关键信息

我们可以写一个正则表达式,一次性匹配出每个项的符号、系数、次数:

val termRegex = Regex("([+-]?)(\\d*)(x(?:\\^(\\d+))?)?")

这个正则的分组含义:

  1. 第1组:项的符号(+/-,第一个项可能没有,默认是+)
  2. 第2组:系数的数字部分(可能为空,比如x的系数就是1)
  3. 第3组:x相关部分(可能是x、x^n或者空)
  4. 第4组:次数数字(只有x^n时存在,x的话次数是1,常数项次数是0)

步骤2:预处理输入字符串

为了统一处理第一个项没有符号的情况(比如7x^4),给字符串开头补一个+:

val processedText = if (text.first() in setOf('+', '-')) text else "+$text"

步骤3:解析每一项,记录系数和次数

遍历所有匹配到的项,解析出每个项的系数和对应次数,同时记录最高次数:

val terms = termRegex.findAll(processedText)
val coefficientMap = mutableMapOf<Int, Int>()
var maxDegree = 0

for (term in terms) {
    val sign = if (term.groupValues[1] == "-") -1 else 1
    val coeffStr = term.groupValues[2]
    val xPart = term.groupValues[3]
    val degreeStr = term.groupValues[4]

    // 处理系数
    val coeff = when {
        coeffStr.isEmpty() && xPart.isNotEmpty() -> sign * 1 // 处理x/-x的情况
        coeffStr.isEmpty() && xPart.isEmpty() -> 0 // 空项,直接跳过
        else -> sign * coeffStr.toInt()
    }

    // 处理次数
    val degree = when {
        xPart.isEmpty() -> 0 // 常数项
        degreeStr.isEmpty() -> 1 // 一次项x
        else -> degreeStr.toInt()
    }

    if (coeff != 0) { // 忽略系数为0的无效项
        coefficientMap[degree] = coeff
        if (degree > maxDegree) maxDegree = degree
    }
}

步骤4:填充缺项,生成最终系数列表

从最高次数到0次依次取出系数,缺项的位置自动填充0:

val koefList = mutableListOf<Int>()
for (degree in maxDegree downTo 0) {
    koefList.add(coefficientMap.getOrDefault(degree, 0))
}

完整的Kotlin函数

把上面的步骤整合起来,完整函数如下:

private fun koef(text: String): List<Int> {
    if (text.isEmpty()) return emptyList()
    
    // 预处理:给开头补符号(如果没有的话)
    val processedText = if (text.first() in setOf('+', '-')) text else "+$text"
    val termRegex = Regex("([+-]?)(\\d*)(x(?:\\^(\\d+))?)?")
    
    val coefficientMap = mutableMapOf<Int, Int>()
    var maxDegree = 0

    termRegex.findAll(processedText).forEach { match ->
        val sign = if (match.groupValues[1] == "-") -1 else 1
        val coeffStr = match.groupValues[2]
        val xPart = match.groupValues[3]
        val degreeStr = match.groupValues[4]

        val coeff = when {
            coeffStr.isEmpty() && xPart.isNotEmpty() -> sign * 1
            coeffStr.isEmpty() && xPart.isEmpty() -> 0 // 空项,忽略
            else -> sign * coeffStr.toInt()
        }

        val degree = when {
            xPart.isEmpty() -> 0
            degreeStr.isEmpty() -> 1
            else -> degreeStr.toInt()
        }

        if (coeff != 0) {
            coefficientMap[degree] = coeff
            if (degree > maxDegree) maxDegree = degree
        }
    }

    // 生成从最高次到0次的系数列表,缺项填0
    return (maxDegree downTo 0).map { coefficientMap.getOrDefault(it, 0) }
}

测试示例

  • 输入"7x^4+3x^3-6x^2+x-8",返回[7, 3, -6, 1, -8](对应x⁴到常数项的系数)
  • 输入"x^3-5",返回[1, 0, 0, -5](自动补全x²和x项的0系数)

为什么原有方法容易出问题?

split分割的方式无法统一处理所有边界情况:比如x项没有^、开头无符号、常数项和x项混合的场景,而正则可以一次性捕获每个项的所有关键信息,解析逻辑会清晰很多。

内容的提问来源于stack exchange,提问作者Marlock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:32:39