다항식 p(x) 를 1차 다항식 x - a 로 나눌 때의 몫과 나머지를 구하는 조립제법을
Scala 언어로 구현해 보았다. 조립제법은 일명 Horner의 방법이라고도 불리우는데, 이는
x = a 에서 다항식 p(x)의 값 p(a)을 계산하는 가장 빠른 알고리즘이기도 하다.
p(x) = (x - a)q(x) + r
여기서 r은 나머지이며 r = p(a) 이다. 또 q(x)는 몫이다.
[참고]
* 온라인으로 조립제법 표 만들기 손으로 계산하는 조립제법 표
* 온라인으로 구하는 다항식의 도함수: 조립제법을 이용한 다항식의 도함수
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Scala 언어로 구현해 보았다. 조립제법은 일명 Horner의 방법이라고도 불리우는데, 이는
x = a 에서 다항식 p(x)의 값 p(a)을 계산하는 가장 빠른 알고리즘이기도 하다.
p(x) = (x - a)q(x) + r
여기서 r은 나머지이며 r = p(a) 이다. 또 q(x)는 몫이다.
[참고]
* 온라인으로 조립제법 표 만들기 손으로 계산하는 조립제법 표
* 온라인으로 구하는 다항식의 도함수: 조립제법을 이용한 다항식의 도함수
- /*
- * Filename: testSyntheticDivision.scala
- *
- * Purpose: Find the quotient and remainder when some polynomial is
- * divided by a monic polynomial of the first degree.
- * 이 소스는 그루비 소스 testSyntheticDivision.groovy 를
- * 스칼라 소스로 변환한 것이다.
- *
- * Execute: scala -encoding MS949 testSyntheticDivision.scala -2 1 3 3 1
- *
- */
- // 사용법 표시
- def printUsage() {
- println("사용법: scala testSyntheticDivision.scala [수] [피제식의 계수들]")
- println("조립제법(synthetic method)에 의한 다항식 나눗셈 결과를 보여준다.")
- }
- // 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
- def simplify(v: Double) : String = {
- var t : String = "" + v
- if (t.endsWith(".0"))
- t = t.substring(0, t.length - 2)
- return t
- }
- // 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
- // 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
- def simplify(v: Double, width: Int) : String = {
- var t : String = "" + v
- if (t.endsWith(".0"))
- t = t.substring(0, t.length - 2)
- var len : Int = t.length
- if (len < width)
- t = " ".substring(0, width - len) + t
- return t;
- }
- // 다항식을 내림차순의 스트링 표현으로 반환
- def toPolyString(c : Array[Double]) : String = {
- var t : String = ""
- var sc0 : String = simplify(c(0))
- if (c.length > 2) {
- if (sc0 == "1")
- t += "x^" + (c.length-1)
- else if (sc0 == "-1")
- t += "-x^" + (c.length-1)
- else
- t += sc0 + " x^" + (c.length-1)
- }
- else if (c.length == 2) {
- if (sc0 == "1")
- t += "x"
- else if (sc0 == "-1")
- t += "-x"
- else
- t += sc0 + " x"
- }
- else if (c.length == 1) {
- t += sc0
- }
- for (i <- List.range(1, c.length)) {
- def k = c.length - 1 - i
- def sc = simplify(c(i))
- if (k > 1) {
- if (c(i) > 0.0) {
- if (sc == "1")
- t += " + " + "x^" + k
- else
- t += " + " + sc + " x^" + k
- }
- else if (c(i) < 0.0) {
- if (sc == "-1")
- t += " - " + "x^" + k
- else
- t += " - " + simplify(Math.abs((i))) + " x^" + k
- }
- }
- else if (k == 1) {
- if (c(i) > 0.0) {
- if (sc == "1")
- t += " + " + "x"
- else
- t += " + " + sc + " x"
- }
- else if (c(i) < 0.0) {
- if (sc == "-1")
- t += " - " + "x"
- else
- t += " - " + simplify(Math.abs(c(i))) + " x"
- }
- }
- else if (k == 0) {
- if (c(i) > 0.0) {
- t += " + " + sc
- }
- else if (c(i) < 0.0)
- t += " - " + simplify(Math.abs(c(i)))
- }
- }
- return t
- }
- // 다항식 나눗셈 결과를
- // (피제식) = (제식)(몫) + (나마지)
- // 형태로 출력
- def printDivisionResult(a : Double, c : Array[Double], b : Array[Double]) {
- print(" " + toPolyString(c))
- println()
- print(" = ( " + toPolyString( Array(1.0, -a) ) + " )")
- var tmp : Array[Double] = new Array[Double](b.length - 1)
- for (i <- List.range(0, tmp.length)) {
- tmp(i) = b(i)
- }
- print("( " + toPolyString(tmp) + " )")
- var r : Double = b(b.length - 1)
- if (r > 0.0)
- print(" + " + simplify(r))
- else if (r < 0.0)
- print(" - " + simplify(Math.abs(r)))
- println()
- }
- // 조립제법 계산표 출력 함수
- def printSyntheticTable(a : Double, c : Array[Double], s : Array[Double], q : Array[Double]) {
- print(" | ")
- print(simplify(c(0), 6))
- for (i <- List.range(1, c.length)) {
- print(" " + simplify(c(i), 6))
- }
- println()
- print(simplify(a, 6) + " | ")
- print(" ")
- print(simplify(s(1), 6))
- for (i <- List.range(2, s.length)) {
- print(" " + simplify(s(i), 6))
- }
- println()
- print(" |-")
- for (i <- List.range(0, q.length)) {
- print("--------")
- }
- println()
- print(" ")
- print(simplify(q(0), 6))
- for (i <- List.range(1, q.length)) {
- print(" " + simplify(q(i), 6))
- }
- println()
- }
- // 실행 시작 지점
- if (args.length < 3) {
- printUsage()
- System.exit(1)
- }
- var a : Double = args(0).toDouble
- var c : Array[double] = new Array[Double](args.length - 1)
- var s : Array[double] = new Array[Double](c.length)
- var b : Array[double] = new Array[Double](c.length)
- for (i <- List.range(0, c.length)) {
- c(i) = args(i + 1).toDouble
- }
- s(0) = 0.0
- b(0) = c(0)
- for (i <- List.range(1, c.length)) {
- s(i) = b(i-1)*a
- b(i) = c(i) + s(i)
- }
- print("몫의 계수는 ")
- for (i <- List.range(0, b.length - 2)) {
- print(simplify(b(i)) + ", " )
- }
- print(simplify(b(b.length - 2)))
- println(" 이고, 나머지는 " + simplify(b(b.length - 1)) + " 이다.")
- println()
- printSyntheticTable(a, c, s, b)
- println()
- printDivisionResult(a, c, b)
scala 명령으로 아래와 같이 실행하여 보았다.
실행> scala -encoding MS949 testSyntheticDivision.scala 1 2 3 4 5
몫의 계수는 2, 5, 9 이고, 나머지는 14 이다.
| 2 3 4 5
1 | 2 5 9
|---------------------------------
2 5 9 14
2 x^3 + 3 x^2 + 4 x + 5
= ( x - 1 )( 2 x^2 + 5 x + 9 ) + 14
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
'프로그래밍 > Scala' 카테고리의 다른 글
황금비율(golden ratio) 구하기 with Scala (0) | 2009.03.09 |
---|---|
현재 시각 알아내기 for Scala (0) | 2009.03.09 |
80컬럼 컨솔에 19단표 출력하기 예제 for Scala (0) | 2008.05.18 |
(최대공약수 구하기) while... 반복문 예제 for Scala (0) | 2008.05.17 |
if...else... 조건문 사용 예제 for Scala (0) | 2008.05.17 |