다항식 p(x) 를 1차 다항식 x - a 로 나눌 때의 몫과 나머지를 구하는 조립제법을 Go 언어로 구현해 보았다. 조립제법(synthetic division)은 일명 Horner의 방법이라고도 불리우는데, 이는
다항식 p(x)의 x = a 일 때의 값 p(a)을 계산하는 가장 빠른 알고리즘이기도 하다.
         p(x) = (x - a)q(x) + r
여기서 r은 나머지이며 r = p(a) 이다. 또 q(x)는 몫이다.
[참고]
    * 온라인으로 조립제법 표 만들기 손으로 계산하는 조립제법 표 
    * 온라인으로 구하는 다항식의 도함수: 조립제법을 이용한 다항식의 도함수 
아래의 소스파일은 go run 명령을 사용하면 컴파일 과정 없이 그대로 실행된다.
(실행 예:  go run testSyntheticDivision.go 1 2 3 4 5  )
- /*
 - * Filename: testSyntheticDivision.go
 - *
 - * Purpose: Find the quotient and remainder when some polynomial is
 - * divided by a monic linear polynomial.
 - *
 - * Execute: go run testSyntheticDivision.go -2 1 3 3 1
 - *
 - * or
 - *
 - * Compile: go build testSyntheticDivision.go
 - * Execute: ./testSyntheticDivision -2 1 3 3 1
 - */
 - package main
 - import (
 - "fmt"
 - "os"
 - "strconv"
 - "math"
 - )
 - func print(str string) {
 - fmt.Printf("%s", str);
 - }
 - func println(str string) {
 - fmt.Printf("%s\n", str);
 - }
 - // 사용법 표시
 - func printUsage() {
 - /// println("사용법: testSyntheticDivision [수] [피제식의 계수들]");
 - /// println("조립제법(synthetic method)에 의한 다항식 나눗셈 결과를 보여준다.");
 - println("Usage: testSyntheticDivision [number] [coefficients of dividend]");
 - println("Show the result of synthetic division.");
 - }
 - // 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
 - // 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
 - func simplify(v float64, width int) string {
 - var n int
 - var slen int
 - var t string = " ";
 - var tmp string = " ";
 - t = fmt.Sprintf("%g", v);
 - n = len(t);
 - if (n > 2) && (t[n - 2] == '.') && (t[n - 1] == '0') {
 - t = t[0:n-2]
 - }
 - slen = len(t);
 - tmp = t
 - if (slen < width) {
 - t = " "
 - t = t[0:width - slen]
 - t = t + tmp
 - }
 - return t
 - }
 - // 다항식을 내림차순의 문자열로로 반환하는 함수
 - func toPolyString(c []float64, size int) string {
 - var SIZE int = size;
 - var i int;
 - var t string = ""
 - var tmp string
 - var pc string = simplify(c[0], -1);
 - var pci string
 -     if SIZE > 2 { 
if (len(pc) == 1 && pc[0] == '1') { - t = fmt.Sprintf("x^%d", SIZE - 1);
 - } else if (len(pc) == 2 && pc[0] == '-' && pc[1] == '1') {
 - t = fmt.Sprintf("-x^%d", SIZE - 1);
 - } else {
 - t = fmt.Sprintf("%s x^%d", simplify(c[0], -1), SIZE - 1);
 - }
 - } else if SIZE == 2 {
 - if (len(pc) == 1 && pc[0] == '1') {
 - t = "x"
 - } else if (len(pc) == 2 && pc[0] == '-' && pc[1] == '1') {
 - t = "-x"
 - } else {
 - t = fmt.Sprintf("%s x", simplify(c[0], -1));
 - }
 - } else if SIZE == 1 {
 - t = fmt.Sprintf("%s", simplify(c[0], -1));
 - }
 - for i = 1; i < SIZE; i++ {
 - pci = simplify(c[i], -1);
 - if SIZE - 1 - i > 1 {
 - if c[i] > 0.0 {
 - if len(pci) == 1 && pci[0] == '1' {
 - tmp = fmt.Sprintf(" + x^%d", SIZE - 1 - i);
 - t += tmp
 - } else {
 - tmp = fmt.Sprintf(" + %s x^%d", simplify(c[i], -1), SIZE - 1 - i);
 - t += tmp
 - }
 - } else if c[i] < 0.0 {
 - if len(pci) == 2 && pci[0] == '-' && pci[1] == '1' {
 - tmp = fmt.Sprintf(" - x^%d", SIZE - 1 - i);
 - t += tmp
 - } else {
 - tmp = fmt.Sprintf(" - %s x^%d", simplify(math.Abs(c[i]), -1), SIZE - 1 - i);
 - t += tmp
 - }
 - }
 - } else if SIZE - 1 - i == 1 {
 - if c[i] > 0.0 {
 - if len(pci) == 1 && pci[0] == '1' {
 - t += " + x"
 - } else {
 - tmp = fmt.Sprintf(" + %s x", simplify(c[i], -1));
 - t += tmp
 - }
 - } else if c[i] < 0.0 {
 - if len(pci) == 2 && pci[0] == '-' && pci[1] == '1' {
 - t += " - x"
 - } else {
 - tmp = fmt.Sprintf(" - %s x", simplify(math.Abs(c[i]), -1));
 - t += tmp
 - }
 - }
 - } else if SIZE - 1 - i == 0 {
 - if c[i] > 0.0 {
 - tmp = fmt.Sprintf(" + %s", simplify(c[i], -1));
 - t += tmp
 - } else if (c[i] < 0.0) {
 - tmp = fmt.Sprintf(" - %s", simplify(math.Abs(c[i]), -1));
 - t += tmp
 - }
 - }
 - }
 - return t
 - }
 - // 다향식 나눗셈 결과를
 - // (피제식) = (제식)(몫) + (나마지)
 - // 형태로 출력
 - func printDivisionResult(a float64, c []float64, b []float64, size int) {
 - var SIZE int = size;
 - var i int
 - var r float64
 - var monic []float64 = []float64 { 1.0, 0.0 };
 - print(" ");
 - print(toPolyString(c, SIZE));
 - println("");
 - print(" = ( ");
 - monic[1] = -a;
 - print(toPolyString( monic, 2 ));
 - print(" )")
 - var pTmpPoly []float64 = make([]float64, SIZE);
 - for i = 0; i < SIZE - 1; i++ {
 - pTmpPoly[i] = b[i];
 - }
 - print("( ");
 - print(toPolyString(pTmpPoly, SIZE - 1));
 - print(" )");
 - r = b[SIZE - 1];
 - if r > 0.0 {
 - print(" + ");
 - print(simplify(r, -1));
 - } else if (r < 0.0) {
 - print(" - ");
 - print(simplify(math.Abs(r), -1));
 - }
 - println("");
 - }
 - // 조립제법 계산표 출력 함수
 - func printSyntheticTable(a float64, c []float64, s []float64, q []float64, size int) {
 - var SIZE int = size;
 - var i int
 - print(" | ");
 - print(simplify(c[0], 6));
 - for i = 1; i < SIZE; i++ {
 - print(" ");
 - print(simplify(c[i], 6));
 - }
 - println("");
 - print(simplify(a, 6));
 - print(" | ");
 - print(" ");
 - print(simplify(s[1], 6));
 - for i = 2; i < SIZE; i++ {
 - print(" ");
 - print(simplify(s[i], 6));
 - }
 - println("");
 - print(" |-");
 - for i = 0; i < SIZE; i++ {
 - print("--------");
 - }
 - println("");
 - print(" ");
 - print(simplify(q[0], 6));
 - for i = 1; i < SIZE; i++ {
 - print(" ");
 - print(simplify(q[i], 6));
 - }
 - println("");
 - }
 - // Go 언어 프로그램의 실행 시작 지점
 - func main() {
 - var i int
 - var SIZE = len(os.Args) - 2
 - var a float64
 - var c []float64 = make([]float64, SIZE + 2)
 - var s []float64 = make([]float64, SIZE + 2)
 - var b []float64 = make([]float64, SIZE + 2)
 - if len(os.Args) < 4 {
 - printUsage()
 - return
 - }
 - //////////////////////////////////////////////////////
 - // 피제식은 c_0 x^n + c_1 x^(n -1) + ... + c_n
 - // 제식은 x - a
 - a, _ = strconv.ParseFloat(os.Args[1], 64)
 - for i = 0; i < SIZE; i++ {
 - c[i], _ = strconv.ParseFloat(os.Args[i + 2], 64)
 - }
 - //////////////////////////////////////////////////////
 - // 조립제법의 주요 부분
 - s[0] = 0.0;
 - b[0] = c[0];
 - for i = 1; i < SIZE; i++ {
 - s[i] = b[i-1]*a;
 - b[i] = c[i] + s[i];
 - }
 - //////////////////////////////////////////////////////
 - // 몫의 계수와 나머지를 출력한다.
 - /// print("몫의 계수는 ");
 - print("The coefficients of the quotient are ");
 - for i = 0; i < SIZE - 2; i++ {
 - print(simplify(b[i], -1));
 - print(", ");
 - }
 - print(simplify(b[SIZE - 2], -1));
 - // print(" 이고, 나머지는 ");
 - print("\nand the remainder is ");
 - print(simplify(b[SIZE - 1], -1));
 - /// println(" 이다.");
 - println(".");
 - println("");
 - //////////////////////////////////////////////////////
 - // 조립제법 표를 출력한다.
 - printSyntheticTable(a, c, s, b, SIZE);
 - println("");
 - //////////////////////////////////////////////////////
 - // (피제식) = (제식) x (몫) + (나머지)
 - printDivisionResult(a, c, b, SIZE);
 - }
 
실행> go run testSyntheticDivision.go 1 2 3 4 5
The coefficients of the quotient are 2, 5, 9
and the remainder is 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
또는
컴파일> go build testSyntheticDivision.go
실행> ./testSyntheticDivision 1 2 3 4 5
The coefficients of the quotient are 2, 5, 9
and the remainder is 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
 
'프로그래밍 > Go' 카테고리의 다른 글
| Go 프로그램 언어로 긴 자리 정수 계산하기 (0) | 2012.06.18 | 
|---|---|
| 현재 시각 알아내기 with Go (0) | 2012.06.17 | 
| 80컬럼 컨솔에 19단표 출력하기 예제 with Go (0) | 2012.06.16 | 
| (최대공약수 구하기) while... 반복문 예제 with Go (0) | 2012.06.15 | 
| if...else... 조건문 사용 예제 with Go (0) | 2012.06.15 |