Here's one implementation.
It's slightly more general, allowing the terms to be in any order, and to have surrounding whitespace. But it still assumes that the polynomial is valid, that the powers are non-negative and all different, and that there's at least one term.
You didn't specify the order of coefficients, so this returns them in increasing power (starting with that of x^0, then x^1, &c).
private fun coeffs(polynomial: String): List<Int> {
val terms = polynomial.split(Regex("(?=[+-])")).associate{ term ->
val s = term.split(Regex("x\\^?"))
val coeff = s[0].replace(" ", "")
.let{ when (it){ "", "+" -> 1; "-" -> -1; else -> it.toInt() }}
val power = s.getOrNull(1)?.trim()
.let{ when (it){ null -> 0; "" -> 1; else -> it.toInt() }}
power to coeff
}
val highestPower = terms.keys.max()!!
return (0..highestPower).map{ terms[it] ?: 0 }
}
Sample results:
- coeffs("x^2+2x-1") = [-1, 2, 1]
- coeffs("2x^3 - 3x^4 - x + 4") = [4, -1, 0, 2, -3]
- coeffs("x") = [0, 1]
- coeffs("-2") = [-2]
It starts by splitting the string into terms. ((?=[+-])
is a lookahead, which matches an empty string if it's followed by +
or -
. Full documentation on Java/Kotlin regular expressions is here.)
It then splits each term into a coefficient and power, converts them to numbers, and creates a Map
from term to coefficient. (That's quite awkward, as it has to handle several special cases where the numbers and/or signs are missing.) Using a map handles missing powers (and also powers that aren't in order).
Finally, it finds the largest power, and converts the map to a list of coefficients in increasing powers, filling in 0 for missing powers.
I've kept the code short, to show the principle. If it were to be used in production, you should probably make it safer and more efficient, e.g. by checking for invalid input such as empty string, invalid characters, or duplicate powers; and by putting the Regex
s in properties so that they don't have to be recreated each time. Some unit tests wouldn't be a bad thing, either!