다항식 p(x) 를 1차 다항식 x - a 로 나눌 때의 몫과 나머지를 구하는 조립제법을
Java 언어로 구현해 보았다. 조립제법은 일명 Horner의 방법이라고도 불리우는데, 이는
x = a 에서 다항식 p(x)의 값 p(a)을 계산하는 가장 빠른 알고리즘이기도 하다.

         p(x) = (x - a)q(x) + r

여기서 r은 나머지이며 r = p(a) 이다. 또 q(x)는 몫이다.

[참고]
    * 온라인으로 조립제법 표 만들기 손으로 계산하는 조립제법 표 
    * 온라인으로 구하는 다항식의 도함수: 조립제법을 이용한 다항식의 도함수


아래의 소스파일은 Ruby용 소스파일 testSyntheticDivision.rb 를 Lua용으로 수정한 것이다.


  1. --[[
  2.   Filename: testSyntheticDivision.lua
  3.   Purpose:  Find the quotient and remainder when some polynomial is
  4.             divided by a monic polynomial of the first degree.
  5.   Execute:  lua testSyntheticDivision.lua -2 1 3 3 1
  6. --]]
  7. -- 사용법 표시
  8. function printUsage()
  9.     print("사용법: lua testSyntheticDivision.lua [수] [피제식의 계수들]")
  10.     print("조립제법(synthetic method)에 의한 다항식 나눗셈 결과를 보여준다.")
  11. end   
  12. -- 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  13. -- 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
  14. function simplify(v, width)
  15.     t = "" .. v
  16.     tlen = string.len(t)
  17.     if string.sub(t, tlen-2) == ".0" then
  18.         t = string.sub(t, 0, tlen-2)
  19.     end
  20.     if width ~= nil then
  21.         if tlen < width then
  22.             t = string.sub("              ", 0, width - tlen) .. t
  23.         end
  24.     end
  25.     return t
  26. end
  27. -- 다항식을 내림차순의 스트링 표현으로 반환
  28. function toPolyString(c)
  29.     local t = ""
  30.     sc0 = simplify(c[1], null)
  31.     if #c > 2 then
  32.         if sc0 == "1" then
  33.             t = t .. "x^" .. (#c-1)
  34.         elseif sc0 == "-1" then
  35.             t = t .. "-x^" .. (#c-1)
  36.         else
  37.             t = t .. sc0 .. " x^" .. (#c-1)
  38.         end
  39.     elseif #c == 2 then
  40.         if sc0 == "1" then
  41.             t = t .. "x"
  42.         elseif sc0 == "-1" then
  43.             t = t .. "-x"
  44.         else
  45.             t = t .. sc0 .. " x"
  46.         end
  47.     elseif #c == 1 then
  48.         t = t .. sc0
  49.     end
  50.     for i = 2, #c do
  51.         k = #c - i
  52.         sc = simplify(c[i], nil)
  53.         if k > 1 then
  54.             if c[i] > 0.0 then
  55.                 if sc == "1" then
  56.                     t = t .. " + " .. "x^" .. k
  57.                 else
  58.                     t = t .. " + " .. sc .. " x^" .. k
  59.                 end
  60.             elseif c[i] < 0.0 then
  61.                 if sc == "-1" then
  62.                     t = t .. " - " .. "x^" .. k
  63.                 else
  64.                     t = t .. " - " .. simplify(math.abs(c[i]), nil) .. " x^" .. k
  65.                 end
  66.             end
  67.         elseif k == 1 then
  68.             if c[i] > 0.0 then
  69.                 if sc == "1" then
  70.                     t = t .. " + " .. "x"
  71.                 else
  72.                     t = t .. " + " .. sc .. " x"
  73.                 end
  74.             elseif c[i] < 0.0 then
  75.                 if sc == "-1" then
  76.                     t = t .. " - " .. "x"
  77.                 else
  78.                     t = t .. " - " .. simplify(math.abs(c[i]), null) .. " x"
  79.                 end
  80.             end
  81.         elseif k == 0 then
  82.             if c[i] > 0.0 then
  83.                 t = t .. " + " .. sc
  84.             elseif c[i] < 0.0 then
  85.                 t = t .. " - " .. simplify(math.abs(c[i]), null)
  86.             end
  87.         end
  88.     end
  89.     return t
  90. end
  91. -- 다향식 나눗셈 결과를
  92. --     (피제식) = (제식)(몫) + (나마지)
  93. -- 형태로 출력
  94. function printDivisionResult(a, c, b)
  95.     local strLine = "  " .. toPolyString(c)
  96.     io.write( strLine .. "\n")
  97.     strLine = "    = ( " .. toPolyString( { 1.0, -a } ) .. " )"
  98.     tmp = { }
  99.     for i = 1, #b - 1 do
  100.         tmp[i] = b[i]
  101.     end
  102.     strLine = strLine .. "( " .. toPolyString(tmp) .. " )"
  103.     r = b[#b]
  104.     if r > 0.0 then
  105.         strLine = strLine .. " + " .. simplify(r, nil)
  106.     elseif r < 0.0 then
  107.         strLine = strLine .. " - " .. simplify(math.abs(r), nil)
  108.     end
  109.     io.write( strLine .. "\n" )
  110. end
  111. -- 조립제법 계산표 출력 함수
  112. function printSyntheticTable(a, c, s, q)
  113.     strLine = "       | "
  114.     strLine = strLine .. simplify(c[1], 6)
  115.     for i = 2, #c do
  116.         strLine = strLine .. "  " .. simplify(c[i], 6)
  117.     end
  118.     io.write( strLine .. "\n" )
  119.     strLine = simplify(a, 6) ..  " |"
  120.     strLine = strLine .. "         "
  121.     strLine = strLine .. simplify(s[2], 6)
  122.     for i = 3, #s do
  123.         strLine = strLine .. "  " .. simplify(s[i], 6)
  124.     end
  125.     io.write( strLine .. "\n" )
  126.     strLine = "       |"
  127.     for i = 1, #q do
  128.         strLine = strLine .. "--------"
  129.     end
  130.     io.write( strLine .. "\n" )
  131.     strLine = "         "
  132.     strLine = strLine .. simplify(q[1], 6)
  133.     for i = 2, #q do
  134.         strLine = strLine .. "  " .. simplify(q[i], 6)
  135.     end
  136.     io.write( strLine .. "\n" )
  137. end
  138. -- 실행 시작 지점
  139. if #arg < 3 then
  140.     printUsage()
  141.     os.exit(1)
  142. end
  143. -- 피제식은 c_0 x^n +  c_1 x^(n -1) + ... + c_n
  144. -- 제식은 x -  a
  145. a = arg[1]
  146. c = { }
  147. s = { }
  148. b = { }
  149. for i = 1, #arg-1 do
  150.     c[i] = tonumber(arg[i + 1])
  151. end
  152. -- 조립제법의 주요 부분
  153. s[1] = 0.0
  154. b[1] = c[1]
  155. for i = 2, #c do
  156.     s[i] = b[i-1]*a
  157.     b[i] = c[i] + s[i]
  158. end
  159. -- 몫의 계수와 나머지를 출력한다.
  160. io.write("몫의 계수는 ")
  161. for i = 1, #b-1 do
  162.     io.write(simplify(b[i], nil) .. ", ");
  163. end
  164. io.write(simplify(b[#b], nil) .. " ")
  165. io.write("이고, 나머지는 " .. simplify(b[#b], nil) .. " 이다." .. "\n")
  166. io.write("\n")
  167. -- 조립제법 표를 출력한다.
  168. printSyntheticTable(a, c, s, b)
  169. io.write("\n")
  170. -- (피제식) = (제식) x (몫) + (나머지)
  171. printDivisionResult(a, c, b)




실행> lua testSyntheticDivision.lua 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



Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Posted by Scripter
,