다항식 p(x) 를 1차 다항식 ax - b 로 나눌 때의 몫과 나머지를 구하는 조립제법을
Python 언어로 구현해 보았다. 조립제법은 일명 Horner의 방법이라고도 불리우는데, 이는
x = a 에서 다항식 p(x)의 값 p(a)을 계산하는 가장 빠른 알고리즘이기도 하다.
p(x) = (ax - b)q(x) + r
여기서 r은 나머지이며 r = p(b/a) 이다. 또 q(x)는 몫이다.
[참고]
* 온라인으로 조립제법 표 만들기 손으로 계산하는 조립제법 표
* 온라인으로 구하는 다항식의 도함수: 조립제법을 이용한 다항식의 도함수
아래의 소스파일은 파일 testSyntheticDivision.py 를 수정한 것이다.
python 대신 jython이나 IronPython 으로도 수정 없이 그대로 실행된다.
Python 언어로 구현해 보았다. 조립제법은 일명 Horner의 방법이라고도 불리우는데, 이는
x = a 에서 다항식 p(x)의 값 p(a)을 계산하는 가장 빠른 알고리즘이기도 하다.
p(x) = (ax - b)q(x) + r
여기서 r은 나머지이며 r = p(b/a) 이다. 또 q(x)는 몫이다.
[참고]
* 온라인으로 조립제법 표 만들기 손으로 계산하는 조립제법 표
* 온라인으로 구하는 다항식의 도함수: 조립제법을 이용한 다항식의 도함수
아래의 소스파일은 파일 testSyntheticDivision.py 를 수정한 것이다.
python 대신 jython이나 IronPython 으로도 수정 없이 그대로 실행된다.
- # coding: MS949
- # Filename: testSyntheticDivision2.py
- #
- # Purpose: Find the quotient and remainder when some polynomial is
- # divided by a monic polynomial of the first degree.
- #
- # Execute: python testSyntheticDivision2.py 5 -4 7 8 6 8
- # Or jython testSyntheticDivision2.py 5 -4 7 8 6 8
- import sys
- # 사용법 표시
- def printUsage():
- print("사용법: python testSyntheticDivision2.py [제식의 계수] [피제식의 계수들]")
- print("조립제법(synthetic method)에 의한 다항식 나눗셈 결과를 보여준다.")
- # 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
- # 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
- def simplify(v, width=None):
- t = "%g" % v
- tlen = len(t)
- if t[tlen-2:tlen-1] == ".0":
- t = t[0, -2]
- if width != None:
- if tlen < width:
- t = " "[0: width - tlen] + t
- return t
- # "/수" 표시하기
- # 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
- # 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
- def simplifyReciprocal(v, width=None):
- t = "/%g" % v
- tlen = len(t)
- if t[tlen-2:tlen-1] == ".0":
- t = t[0, -2]
- if width != None:
- if tlen < width:
- t = " "[0: width - tlen] + t
- return t
- # 다항식을 내림차순의 스트링 표현으로 반환
- def toPolyString(c):
- t = ""
- sc0 = simplify(c[0])
- if len(c) > 2:
- if sc0 == "1":
- t += "x^%d" % (len(c)-1)
- elif sc0 == "-1":
- t += "-x^%d" % (len(c)-1)
- else:
- t += sc0 + " x^%d" % (len(c)-1)
- elif len(c) == 2:
- if sc0 == "1":
- t += "x"
- elif sc0 == "-1":
- t += "-x"
- else:
- t += sc0 + " x"
- elif len(c) == 1:
- t += sc0
- for i in range(1, len(c)):
- k = len(c) - 1 - i
- sc = simplify(c[i])
- if k > 1:
- if c[i] > 0.0:
- if sc == "1":
- t += " + " + "x^%d" % k
- else:
- t += " + " + sc + " x^%d" % k
- elif c[i] < 0.0:
- if sc == "-1":
- t += " - " + "x^%d" % k
- else:
- t += " - " + simplify(abs(c[i])) + " x^%d" % k
- elif k == 1:
- if c[i] > 0.0:
- if sc == "1":
- t += " + " + "x"
- else:
- t += " + " + sc + " x"
- elif c[i] < 0.0:
- if sc == "-1":
- t += " - " + "x"
- else:
- t += " - " + simplify(abs(c[i])) + " x"
- elif k == 0:
- if c[i] > 0.0:
- t += " + " + sc
- elif c[i] < 0.0:
- t += " - " + simplify(abs(c[i]))
- return t
- # 다항식 나눗셈 결과를
- # (피제식) = (제식)(몫) + (나머지)
- # 형태로 출력
- def printDivisionResult(a, c, d, b):
- strLine = " " + toPolyString(c)
- print( strLine )
- strLine = " = ( " + toPolyString( [a[0], -a[1]] ) + " )"
- tmp = [0.0] * (len(b) - 1)
- for i in range(0, len(tmp)):
- tmp[i] = b[i]
- strLine += "( " + toPolyString(tmp) + " )"
- r = d[len(d) - 1]
- if r > 0.0:
- strLine += " + " + simplify(r)
- elif r < 0.0:
- strLine += " - " + simplify(abs(r))
- print( strLine )
- # 조립제법 계산표 출력 함수
- def printSyntheticTable(a, c, s, d, q):
- strLine = " | "
- strLine += simplify(c[0], 8)
- for i in range(1, len(c)):
- strLine += " " + simplify(c[i], 8)
- print( strLine )
- strLine = simplify(a[1], 8) + " |"
- strLine += " "
- strLine += simplify(s[1], 8)
- for i in range(2, len(s)):
- strLine += " " + simplify(s[i], 8)
- print( strLine )
- strLine = " |"
- for i in range(0, len(q)):
- strLine += "----------"
- print( strLine )
- strLine = " | "
- strLine += simplify(d[0], 8)
- for i in range(1, len(d)):
- strLine += " " + simplify(d[i], 8)
- print( strLine )
- strLine = simplifyReciprocal(a[0], 8) + " | "
- strLine += simplify(q[0], 8)
- for i in range(1, len(q) - 1):
- strLine += " " + simplify(q[i], 8)
- print( strLine )
- # 실행 시작 지점
- if len(sys.argv) < 3:
- printUsage()
- sys.exit(1)
- ######################################################
- # 피제식은 c_0 x^n + c_1 x^(n -1) + ... + c_n
- # 제식은 a x - b
- a = [float(sys.argv[1]), - float(sys.argv[2])]
- c = [0.0]*(len(sys.argv) - 3)
- s = [0.0]*(len(sys.argv) - 3)
- d = [0.0]*(len(sys.argv) - 3)
- b = [0.0]*(len(sys.argv) - 3)
- for i in range(0, len(c)):
- c[i] = float(sys.argv[i + 3])
- ######################################################
- # 조립제법의 주요 부분
- s[0] = 0.0
- d[0] = c[0]
- b[0] = c[0] / a[0]
- for i in range(1, len(c)):
- s[i] = b[i-1]*a[1]
- d[i] = c[i] + s[i]
- b[i] = d[i] / a[0]
- ######################################################
- # 몫의 계수와 나머지를 출력한다.
- print("몫의 계수는"),
- for i in range(0, len(b) - 2):
- print(simplify(b[i], None) + ", " ),
- print(simplify(b[len(b) - 2], None)),
- print("이고, 나머지는 " + simplify(d[len(d) - 1], None) + " 이다.")
- ######################################################
- # 조립제법 표를 출력한다.
- printSyntheticTable(a, c, s, d, b)
- ######################################################
- # (피제식) = (제식) x (몫) + (나머지)
- printDivisionResult(a, c, d, b)
실행> python testSyntheticDivision2.py 5 -4 7 8 6 8
몫의 계수는 1.4, 2.72, 3.376 이고, 나머지는 21.504 이다.
| 7 8 6 8
4 | 5.6 10.88 13.504
|----------------------------------------
| 7 13.6 16.88 21.504
/5 | 1.4 2.72 3.376
7 x^3 + 8 x^2 + 6 x + 8
= ( 5 x - 4 )( 1.4 x^2 + 2.72 x + 3.376 ) + 21.504
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
'프로그래밍 > Python' 카테고리의 다른 글
Python 3.2 를 이용한 간단한 수학식 계산하기 (0) | 2011.08.18 |
---|---|
Python 2.7 을 이용한 간단한 수학식 계산하기 (0) | 2011.08.18 |
숫자 맞추기 게임 with Python (0) | 2009.11.05 |
Python 2.x의 input() 함수와 Python 3.x의 input() 함수의 차이 (0) | 2009.10.21 |
스트링 리스트에서 스트링 찾기(find) with Python (0) | 2009.04.22 |