<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Codebreaker &#187; computer science</title>
	<atom:link href="http://blog.sumin.us/archives/category/computer-science/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.sumin.us</link>
	<description>2bc08752a0894eb2c7afb345286e391d</description>
	<lastBuildDate>Wed, 08 Sep 2010 02:15:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Permutation Generation</title>
		<link>http://blog.sumin.us/archives/1119</link>
		<comments>http://blog.sumin.us/archives/1119#comments</comments>
		<pubDate>Wed, 30 Sep 2009 09:15:45 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[computer science]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[recursion]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1119</guid>
		<description><![CDATA[Someone asked me how to generate all possible permutations out of a given set and I thought it was kind of interesting to think about it. I was able to come up with a general solution pretty easily (thanks to all the algorithm and math classes I took!) and I would like to share it [...]]]></description>
			<content:encoded><![CDATA[<p>Someone asked me how to generate all possible permutations out of a given set and I thought it was kind of interesting to think about it. I was able to come up with a general solution pretty easily (thanks to all the algorithm and math classes I took!) and I would like to share it with everyone.</p>

<h3>Recursive solution</h3>

<p>For a given set, <em>S</em>,</p>

<p><img src="http://blog.sumin.us/wp-content/cache/tex_5f3effd07c21e2e9a6d5f592fa0455c3.png" align="absmiddle" class="tex" alt="p(S) = 
\begin{cases} 
  \{\emptyset\},  &#038; \mbox{if } S = \emptyset \\
  \{\{s_1\} + p(S - \{s_1\}), \{s_2\} + p(S - \{s_2\}), ..., \\
    \mbox{  } \{s_n\} + p(S - \{s_n\}) \}, &#038; \mbox{otherwise}
\end{cases}" /></p>

<p>whereas <code>+</code> and <code>-</code> signs denote set addition and set subtraction respectively.</p>

<h3>Python implementation</h3>

<pre><code>def permutation(set):
        if set == []:
                return [[]]
        else:
                r = []
                for i in xrange(0, len(set)):
                        for p in permutation(set[0:i] + set[i+1:]):
                                r.append([set[i]] + p)
                return r
</code></pre>

<h3>Results</h3>

<pre><code>&gt;&gt;&gt; print permutation([1, 2, 3])
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
</code></pre>

<p>I wouldn't say this particular implementation is <em>the most efficient</em> one, but at least we know it works with up to a certain size of set. Sadly, we all have machines with a finite size of memory, our machine will produce stack overflow if your set is too big.</p>

<p>I think languages like Haskell would work very efficiently with this kind of recursive solution due to its beautiful features like lazy evaluation, tail recursion, etc. Please feel free to share your solution or implementation.</p>
<!-- AdSense Now! V1.83 -->
<!-- Post[count: 2] -->
<div class="adsense adsense-leadout" style="text-align:center;margin: 12px;"><script type="text/javascript"><!--
google_ad_client = "pub-2353453386862167";
/* 468x60, created 10/26/09 */
google_ad_slot = "1252542387";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1119/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Class Note for CS445 on Jan 27, 2009</title>
		<link>http://blog.sumin.us/archives/925</link>
		<comments>http://blog.sumin.us/archives/925#comments</comments>
		<pubDate>Tue, 27 Jan 2009 23:44:26 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[computer science]]></category>
		<category><![CDATA[classnote]]></category>
		<category><![CDATA[cs445]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=925</guid>
		<description><![CDATA[Announcements Optional discussion section meets on Wednesday, 7-8pm at FCS 101 Largest Empty Rectangle Problem Divide and conquer function DivideAndConquer(A, m, n) begin PrecomputeLeftRuns(...) PrecomputeRightRuns(...) return DivAndConq(A, m, 1, n, L, R) end DevAndConq() PrecomputeLeftRuns() + PrecomputeRightRus() Total number of rectangles [m 2] * [n 2] = m*(m-1)/2 * n*(n-1)/2 (pair of rows) (pair of [...]]]></description>
			<content:encoded><![CDATA[<h3>Announcements</h3>

<p>Optional discussion section meets on Wednesday, 7-8pm at FCS 101</p>

<h3>Largest Empty Rectangle Problem</h3>

<h4>Divide and conquer</h4>

<pre><code>function DivideAndConquer(A, m, n) begin
    PrecomputeLeftRuns(...)
    PrecomputeRightRuns(...)
    return DivAndConq(A, m, 1, n, L, R)
end
</code></pre>

<h5>DevAndConq()</h5>

<p><img src="http://blog.sumin.us/wp-content/cache/tex_165ad1a0998553d376bec223c7fd7a78.png" align="absmiddle" class="tex" alt="T(m, n) = 2T(m, n/2) + \Theta(m^2) = \Theta(m^2n)" /></p>

<h5>PrecomputeLeftRuns() + PrecomputeRightRus()</h5>

<p><img src="http://blog.sumin.us/wp-content/cache/tex_d24bc92f3ade3cab939ab90e47d2a400.png" align="absmiddle" class="tex" alt="\Theta(mn) + \Theta(m^2n)" /></p>

<h5>Total number of rectangles</h5>

<pre><code>[m 2]          * [n 2]           = m*(m-1)/2 * n*(n-1)/2
(pair of rows)   (pair of cols)  theta(m^2)  theta(n^2)
</code></pre>

<p>To sum up, for Largest Empty Rectangle, we've seen following algorithms:</p>

<ul>
<li>Exhaustive search (<img src="http://blog.sumin.us/wp-content/cache/tex_964eae066ba974118fcbb85e0a77e842.png" align="absmiddle" class="tex" alt="\Theta(m^3n^3)" /> time)</li>
<li>[Optimized exhaustive search (<img src="http://blog.sumin.us/wp-content/cache/tex_61f471ff88971ccea8f15d716f194650.png" align="absmiddle" class="tex" alt="\Theta(m^2n^2)" /> time)]</li>
<li>Divide and conquer (<img src="http://blog.sumin.us/wp-content/cache/tex_ea1f2f3f0a626e55c015915fe4fa27f8.png" align="absmiddle" class="tex" alt="\Theta(m^2n)" /> time)</li>
<li>[Dynamic programming (<img src="http://blog.sumin.us/wp-content/cache/tex_ea1f2f3f0a626e55c015915fe4fa27f8.png" align="absmiddle" class="tex" alt="\Theta(m^2n)" /> time)]</li>
<li>[Amortization (<img src="http://blog.sumin.us/wp-content/cache/tex_cbbfa02ec80f805a0df6ef55bd135d2d.png" align="absmiddle" class="tex" alt="\Theta(mn)" /> time)] (optimal)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/925/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Class Note for SC445 on Jan 20, 2009</title>
		<link>http://blog.sumin.us/archives/854</link>
		<comments>http://blog.sumin.us/archives/854#comments</comments>
		<pubDate>Wed, 21 Jan 2009 06:52:34 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[computer science]]></category>
		<category><![CDATA[classnote]]></category>
		<category><![CDATA[cs445]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=854</guid>
		<description><![CDATA[Announcements Office hours posted on the course webpage: M-F Optional discussion section will be on Wednesdays at 7-8pm Problem (Largest Monochromatic Rectangle) Given an m*n boolean array A[1:m, 1:n] of zeroes and ones, find a subarray A[i:k, j:l] that contains only zeros. Exhaustive Search (examine all possibilities; pick the best one) function exhaustive(A, m, n) [...]]]></description>
			<content:encoded><![CDATA[<h3>Announcements</h3>

<ul>
<li>Office hours posted on the course webpage: M-F</li>
<li>Optional discussion section will be on Wednesdays at 7-8pm</li>
</ul>

<h3>Problem (Largest Monochromatic Rectangle)</h3>

<p>Given an m*n boolean array A[1:m, 1:n] of zeroes and ones, find a subarray A[i:k, j:l] that contains only zeros.</p>

<h4>Exhaustive Search (examine all possibilities; pick the best one)</h4>

<pre><code>function exhaustive(A, m, n) begin * returns the area of the largest solution
a := 0
for i := 1 to m do
for j := 1 to n do
for k := i to m do
for l := j to n do begin
scan A[i:k, j:l]
if it contains only zeroes then
a := max{a, (k-i+1)*(l-j+1)}
end (for)

return a
end (function)
</code></pre>

<ul>
<li>(a) scan - a := max{}</li>
<li>(b) for l:= j to n</li>
<li>(c) for k := i to m</li>
<li>(d) for j := 1 to n</li>
<li>(e) for i := 1 to m</li>
</ul>

<h4>Analysis</h4>

<ul>
<li><p>(a) <img src="http://blog.sumin.us/wp-content/cache/tex_3861dfc520bd1d2069aa0df79a0ddf02.png" align="absmiddle" class="tex" alt="\Theta((k-i)(l-j))" /></p></li>
<li><p>(b) <img src="http://blog.sumin.us/wp-content/cache/tex_5e0bd736e43c72947a0033842a8c42db.png" align="absmiddle" class="tex" alt="\displaystyle
\sum_{j=l}^n\Theta((k-i)(l-j))\\
= \Theta(\sum_{j=l}^n (k-i)(l-j))\\
= \Theta((k-i)\sum_{j=l}^n(l-j))\\
= \Theta((k-i)\sum_{x=0}^{n-j}x)\\
= \Theta((k-i)\Theta(n-j)^2)\\
= \Theta((k-i)(n-j)^2)
" /></p></li>
<li><p>(c) <img src="http://blog.sumin.us/wp-content/cache/tex_a0ed8c92ff831ac52742daab6c9206be.png" align="absmiddle" class="tex" alt="\displaystyle
\sum_{i=k}^m\Theta((k-i)(n-j)^2)\\
= \Theta(\sum_{i=k}^m(k-i)(n-j)^2)\\
= \Theta((n-j)^2 \sum_{i=k}^m(k-i))\\
= \Theta((n-j)^2 \sum_{x=0}^{m-1}x)
" /></p></li>
<li><p>(d) <img src="http://blog.sumin.us/wp-content/cache/tex_a10f2f9db3298aef90733623dd871871.png" align="absmiddle" class="tex" alt="\Theta((m-i)^2 n^3)" /></p></li>
<li><p>(e) <img src="http://blog.sumin.us/wp-content/cache/tex_6645adaedaa4639e1218597515e6fa58.png" align="absmiddle" class="tex" alt="\Theta(m^3 n^3)" /> : time for exhaustive search without any optimization</p></li>
</ul>

<h4>Notations and Formulas</h4>

<ul>
<li><img src="http://blog.sumin.us/wp-content/cache/tex_c7a5ed132201a087eedd29f5bb794677.png" align="absmiddle" class="tex" alt="\Theta(f(n))" /> upper- and lower-bounded by constant times f(n)  </li>
<li><img src="http://blog.sumin.us/wp-content/cache/tex_a9a1e1bc4bf0237c1260d1e60d20fb28.png" align="absmiddle" class="tex" alt="O(f(n))" /> upper-bounded by constant times f(n)  </li>
<li><p><img src="http://blog.sumin.us/wp-content/cache/tex_1a6ca9b6f344cf77802afb21cd114fb2.png" align="absmiddle" class="tex" alt="\Omega(f(n))" /> lower-bounded by constant times f(n)</p></li>
<li><p><img src="http://blog.sumin.us/wp-content/cache/tex_872066d1b912d73910dd4b1b1c6e208a.png" align="absmiddle" class="tex" alt="\sum \Theta(f(i)) = \Theta(\sum f(i))" /> (almost always)</p></li>
<li><img src="http://blog.sumin.us/wp-content/cache/tex_3207d4ca2e69ea08e7fbc0ddc9894b73.png" align="absmiddle" class="tex" alt="\displaystyle \sum_{i=1}^n i^k = \Theta(n^{k+1})" /></li>
</ul>

<h4>Divide and Conquer</h4>

<p>Cut the input array vertically at the middle column. Then the optimal rectangle falls into three cases:</p>

<ol>
<li>It lies strictly in left half. (recurse)</li>
<li>It lies strictly in right half. (recurse)</li>
<li>It spans the middle. (some work to do)</li>
</ol>

<p>If we cut it at the middle column, it breaks into a left rectangle that ends at the middle column and is optimal, and a right rectangle that starts at the middle column and is optimal. (where the start and end rows i and k are fixed -&gt; new subproblem!)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/854/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LCS(Longest Common Subsequence) 찾기</title>
		<link>http://blog.sumin.us/archives/614</link>
		<comments>http://blog.sumin.us/archives/614#comments</comments>
		<pubDate>Tue, 01 May 2007 03:34:06 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[computer science]]></category>

		<guid isPermaLink="false">http://blog.superwtk.com/archives/614</guid>
		<description><![CDATA[오... 완전 신기>_ &#60; LCS(X, Y) for(i=1; i&#60;=m; i++) L[i, 0] = 0 for(j=0; j&#60;=n; j++) L[0, j] = 0 for(i=1; i&#60;=m; i++) for(j=1; j&#60;=n; j++) if(x[i] == y[j]) L[i, j] = 1 + L[i-1, j-1] else if(L[i-1, j] &#62;= L[i, j-1]) L[i, j] = L[i-1, j] else L[i, j] = L[i, j-1]]]></description>
			<content:encoded><![CDATA[<p>오... 완전 신기>_ &lt;</p>

<pre><code>LCS(X, Y)
    for(i=1; i&lt;=m; i++) L[i, 0] = 0
    for(j=0; j&lt;=n; j++) L[0, j] = 0
    for(i=1; i&lt;=m; i++)
        for(j=1; j&lt;=n; j++)
            if(x[i] == y[j])
                L[i, j] = 1 + L[i-1, j-1]
            else if(L[i-1, j] &gt;= L[i, j-1])
                L[i, j] = L[i-1, j]
            else
                L[i, j] = L[i, j-1]
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/614/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bubble Sort</title>
		<link>http://blog.sumin.us/archives/598</link>
		<comments>http://blog.sumin.us/archives/598#comments</comments>
		<pubDate>Thu, 12 Apr 2007 23:25:37 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[computer science]]></category>
		<category><![CDATA[bubble sort]]></category>

		<guid isPermaLink="false">http://blog.superwtk.com/archives/598</guid>
		<description><![CDATA[Bubble Sort (Ascending Order) bubblesort(A) N = the number of elements in A for(i=0; i&#60;n; i++) for(j=0; j&#60;n-(i+1); j++) if(A[j] &#62; A[j+1]) swap(A[j], A[j+1]) end end end 기본 원리는 아주 간단하다: 뒤쪽부터 올바른 값으로 채워넣는다. Insertion Sort 와 상반되는 방법이라고도 할 수 있다. 15, 38, 2, 1, -3, -10, 0, 11, -2, 9 이러한 자료를 [...]]]></description>
			<content:encoded><![CDATA[<h3>Bubble Sort (Ascending Order)</h3>

<pre><code>bubblesort(A)
    N = the number of elements in A
    for(i=0; i&lt;n; i++)
        for(j=0; j&lt;n-(i+1); j++)
            if(A[j] &gt; A[j+1]) swap(A[j], A[j+1])
        end
    end
end
</code></pre>

<p>기본 원리는 아주 간단하다: 뒤쪽부터 올바른 값으로 채워넣는다. Insertion Sort 와 상반되는 방법이라고도 할 수 있다.</p>

<pre><code>15, 38, 2, 1, -3, -10, 0, 11, -2, 9
</code></pre>

<p>이러한 자료를 담고 있는 배열을 정렬한다고 할 때</p>

<pre><code>15, 2, 1, -3, -10, 0, 11, -2, 9, 38
2, 1, -3, -10, 0, 11, -2, 9, 15, 38
1, -3, -10, 0, 2, -2, 9, 11, 15, 38
-3, -10, 0, 1, -2, 2, 9, 11, 15, 38
-10, -3, 0, -2, 1, 2, 9, 11, 15, 38
-10, -3, -2, 0, 1, 2, 9, 11, 15, 38
-10, -3, -2, 0, 1, 2, 9, 11, 15, 38
-10, -3, -2, 0, 1, 2, 9, 11, 15, 38
-10, -3, -2, 0, 1, 2, 9, 11, 15, 38
-10, -3, -2, 0, 1, 2, 9, 11, 15, 38
</code></pre>

<p>이런식으로 동작한다. 여기서 이야기를 멈추면 중학생 수준의 포스트가 되어버리므로 계속 진행하겠다.</p>

<h3>문제점</h3>

<pre><code>1, 2, 3, 4, 5, 6, 7, 8, 9, 10
</code></pre>

<p>위와 같이 이미 정렬되어있는 배열을 정렬하려고 할 경우 똑똑하지 못한 모습을 보여준다. 더이상 정렬할 필요가 없는데도 불구하고 <code>sig(i, 1, N-1)</code> 번 실행된다.</p>

<h3>발전된 형태의 알고리즘</h3>

<pre><code>bubblesort(A)
    flag = N
    while(flag &gt; 0)
        k = flag - 1
        flag = 0
        for(j=0; j&lt;k; j++)
            if(A[j] &gt; A[j+1])
                swap(A[j], A[j+1])
                flag = j + 1
            end
        end
    end
end
</code></pre>

<p>이미 정렬 되어있는 배열의 경우 <code>O(N)</code> 의 실행시간을 보여준다 (best case). <code>flag</code> 가 하는 역할에 주목할 필요가 있다. 이미 정렬된 부분을 표시함으로써 불필요한 연산을 하지 않도록 만들어준다.</p>

<p>각자 좋아하는 언어로 직접 구현해서 코멘트나 트랙백 다는것도 재밌을것 같다 ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/598/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>log(N)</title>
		<link>http://blog.sumin.us/archives/597</link>
		<comments>http://blog.sumin.us/archives/597#comments</comments>
		<pubDate>Thu, 12 Apr 2007 22:32:31 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[computer science]]></category>
		<category><![CDATA[hash]]></category>

		<guid isPermaLink="false">http://blog.superwtk.com/archives/597</guid>
		<description><![CDATA[CS345 이번 과제는 여러가지 해시 알고리즘을 직접 구현하는것이었다. In the program spec, Dr. Moon wrote that a family of hash functions would be created by h sub k(s) = MyUtil.ELFhash(s, 2^k) for k > 0. Since M = 2^k, in order to find the value of k (so we can pass it into the argument [...]]]></description>
			<content:encoded><![CDATA[<p>CS345 이번 과제는 여러가지 해시 알고리즘을 직접 구현하는것이었다.</p>

<blockquote>
  <p>In the program spec, Dr. Moon wrote that a family of hash functions would be
  created by h sub k(s) = MyUtil.ELFhash(s, 2^k) for k > 0. Since M = 2^k, in
  order to find the value of k (so we can pass it into the argument of ElfHash
  when creating the extended function), we need to find the log2(M), am I
  correct? If so, how do I find this in Java? I cannot find any fuctions in
  Java's math utility that returns the log base 2 of a number.</p>
</blockquote>

<p>메일링 리스트에 대략 이런 내용의 글을 올린 사람이 있어서 잠시 <code>log(N)</code> 의 값을 구하는 방법에 대해서 생각해보게 되었다. 사실 구할 필요도 없긴 하지만.</p>

<pre><code>log(N)
    c = 0
    while(N &gt; 1)
        N = N &gt;&gt; 1
        c = c + 1
    end
    return c
end
</code></pre>

<p>대략 의사 코드(pseudo code)로 작성해보았다. 길이가 짧기도 하고 복잡한 조건도 없어서 아주 예뻐보인다 :D</p>

<pre><code>public int log(int n) {
    int c = 0;
    while(n &gt; 1) {
        n = n &gt;&gt; 1;
        c++;
    }
    return c;
}
</code></pre>

<p>자바로는 이렇게 구현하면 될까나... 어떤 언어든지 1분 내로 구현할 수 있다고 본다. 어셈블리어는 제외.</p>

<p>이미 눈치 챈 사람도 있겠지만, N 의 값이 2의 k제곱이 아닐때에는 결과값이 <code>floor of log(N)</code> 이 된다. 아~ 이거 의외로 쓸만할지도 모르겠다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/597/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>증명 문제</title>
		<link>http://blog.sumin.us/archives/576</link>
		<comments>http://blog.sumin.us/archives/576#comments</comments>
		<pubDate>Thu, 22 Feb 2007 06:26:32 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[computer science]]></category>

		<guid isPermaLink="false">http://blog.superwtk.com/archives/576</guid>
		<description><![CDATA[수식은 MS Word 에서 Microsoft Equations 3.0 객체를 이용해서 입력했다. 실제 시험에서도 제발 이렇게만 나왔으면 좋겠다. 내가 한게 맞는건지는 잘 모르겠지만-_-a]]></description>
			<content:encoded><![CDATA[<p><img id="image574" src="/wp-content/uploads/2007/02/exam1-q1.png" alt="exam1-q1.png" /></p>

<p><img id="image575" src="/wp-content/uploads/2007/02/exam1-s1.png" alt="exam1-s1.png" /></p>

<p>수식은 MS Word 에서 Microsoft Equations 3.0 객체를 이용해서 입력했다. 실제 시험에서도 제발 이렇게만 나왔으면 좋겠다. 내가 한게 맞는건지는 잘 모르겠지만-_-a</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/576/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Binary Tree 탐색을 이용한 연산자 표기 순서 변경</title>
		<link>http://blog.sumin.us/archives/552</link>
		<comments>http://blog.sumin.us/archives/552#comments</comments>
		<pubDate>Thu, 08 Feb 2007 07:11:46 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[computer science]]></category>

		<guid isPermaLink="false">http://blog.superwtk.com/archives/552</guid>
		<description><![CDATA[오랜만에 블로그 제목에 어울리는 포스트를 하나 올리겠다. Tree 여기 잘 만들어진 나무가 있다. Visio 를 이용해서 그렸다-_-v 중위 표기법으로 표현된 수식을 이러한 형식으로 변환하는 과정은 생략하겠다 :P 왜냐고 물으면 딱히 할 말이 없다. 그냥 귀찮아서? 이게 정답인것 같다. 괄호로 완벽하게 묶인(fully-parenthesized) 식이라면 몰라도 실세계에서 흔히 접하는 수식은 경우에 따라서 해석하기 난해할 수도 있다. 예를 들면 [...]]]></description>
			<content:encoded><![CDATA[<p>오랜만에 블로그 제목에 어울리는 포스트를 하나 올리겠다.</p>

<h2>Tree</h2>

<p><img id="image551" src="/wp-content/uploads/2007/02/tree.png" alt="tree.png" /></p>

<p>여기 잘 만들어진 나무가 있다. Visio 를 이용해서 그렸다-_-v 중위 표기법으로 표현된 수식을 이러한 형식으로 변환하는 과정은 생략하겠다 :P</p>

<p>왜냐고 물으면 딱히 할 말이 없다. 그냥 귀찮아서? 이게 정답인것 같다. 괄호로 완벽하게 묶인(fully-parenthesized) 식이라면 몰라도 실세계에서 흔히 접하는 수식은 경우에 따라서 해석하기 난해할 수도 있다. 예를 들면 <code>-8 / -1/2(2 + 4)(-3 + 1)</code> 이런거...</p>

<h2>연산자 후위 표기 (Postfix)</h2>

<pre><code>postfix(tree)
    if(tree is null) return

    postfix(tree.left)
    postfix(tree.right)
    print(tree.value)
</code></pre>

<p>의사 코드(pseudo code)이다. 이걸 보고 어떤 프로그래밍 언어냐고 묻는 사람은 없을거라고 믿는다.</p>

<pre><code>1 2 + 3 4 - * 5 6 + *
</code></pre>

<p>연산자 후위 표기와 전위 표기의 주된 장점중 하나는 괄호 없이 연산자 우선순위를 명시할 수 있다는 것이다. 예를 들어서, <code>a + b * c</code> 와 같은 식의 연산자 우선순위를 바꾸려면 <code>(a + b) * c</code> 와 같이 괄호를 써줘야 한다. 하지만 후위 표기법으로 나타내면 전자는 <code>a b c * +</code>, 후자는 <code>a b + c *</code> 와 같이 나타낼 수 있다.</p>

<p>고등학생때 간단한 사칙연산 해석기(parser)를 만들었었는데, 그때도 후위 표기법을 사용했던걸로 기억한다. 중위 표기법으로 표현된 수식을 해석해서 후위 표기법으로 바꿔 스택에 넣으면 아주 간단하게 수식의 결과를 얻을 수 있다.</p>

<h2>연산자 전위 표기 (Prefix)</h2>

<pre><code>prefix(tree)
    if(tree is null) return

    print(tree.value)
    postfix(tree.left)
    postfix(tree.right)
</code></pre>

<p><strike>전위 표기법은 실제로 사용해본적이 없는것 같다.</strike></p>

<pre><code>* * + 1 2 - 3 4 + 5 6
</code></pre>

<h2>연산자 중위 표기 (Infix)</h2>

<p>대부분의 사람들한테 친숙한 표기법이다. 정규 교과 과정에 수학 과목이 포함되어있고, 정규 교과 과정에서 다루는 수학에서는 중위 표기법을 쓰니까.</p>

<pre><code>infix(tree)
    if(tree is null) return

    infix(tree.left)
    print(tree.value)
    infix(tree.right)
</code></pre>

<p>이렇게 하면 될까?</p>

<pre><code>1 + 2 * 3 - 4 * 5 + 6
</code></pre>

<p>대충 모양이 나오는것 같지만, 연산자 우선순위가 엉망이 되어버렸다. 연산자 중위 표기를 위해서는 약간의 추가적인 작업을 해줘야 한다.</p>

<pre><code>infix(tree)
    if(tree is null) return
    if(tree.value is an operator) print("(")

    infix(tree.left)
    print(tree.value)
    infix(tree.right)

    if(tree.value is an operator) print(")")
</code></pre>

<p>결과는?</p>

<pre><code>(((1 + 2) * (3 - 4)) * (5 + 6))
</code></pre>

<p>괄호 덕분에 연산자 우선순위가 바로잡혔다.</p>

<h2>마무리</h2>

<p>고등학생때(아마 2학년때였을 거다) 이러한 내용들을 알게 되었을때 뭔가 커다란 깨달음을 얻은것 같은 느낌이었다. 중3때 C언어 처음 만져봤을때처럼. 그때부터 이쪽으로 계속 연구했었다면 지금쯤 컴파일러 하나쯤 개발했을지도 모르겠다. 아하하...</p>

<ol>
<li>괄호 없이 연산자 우선순위 평가</li>
<li>생략된 연산자 인식 (<code>5(b + c) = 5 * (b + c)</code>)</li>
<li>단일 연산자 구분 (<code>a + -b</code>)</li>
<li>할당 연산자 (<code>=</code>)</li>
</ol>

<p>이정도만 구현해도 꽤 괜찮은 수식 해석기를 만들 수 있을거라고 생각한다. 관심 있는 사람은 한번 도전해보길 바란다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/552/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>도서관에서 책 빌리고 좌절..</title>
		<link>http://blog.sumin.us/archives/202</link>
		<comments>http://blog.sumin.us/archives/202#comments</comments>
		<pubDate>Thu, 09 Mar 2006 18:21:40 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[computer science]]></category>

		<guid isPermaLink="false">http://blog.superwtk.com/archives/202</guid>
		<description><![CDATA[도서관에 책 반납하러 갔는데 A Theory of Destributed Objects 라는 책이 있길래 왠지 재미있어보이는 주제 같아서 목차도 자세히 안보고 바로 빌려왔다. 기숙사 와서 좀 읽다보니까.. 이게 뭐꼬 ㅠ_ㅠ; 지금 학교에서 듣고있는 Calculus 1도 그렇게 만만한 과목은 아닌데.. 이 책을 보고, 또 앞으로 배워야 할 수학(대학 졸업 하려면-_-)을 생각해보니까 지금까지 내가 공부해왔던 수학이 보잘것 없이 느껴진다. [...]]]></description>
			<content:encoded><![CDATA[<p>도서관에 책 반납하러 갔는데 A Theory of Destributed Objects 라는 책이 있길래 왠지 재미있어보이는 주제 같아서 목차도 자세히 안보고 바로 빌려왔다. 기숙사 와서 좀 읽다보니까..</p>

<p><img width="512" height="434" alt="special-reduction.png" id="image201" src="/wp-content/uploads/2006/03/special-reduction.png" /></p>

<p>이게 뭐꼬 ㅠ_ㅠ;</p>

<p>지금 학교에서 듣고있는 Calculus 1도 그렇게 만만한 과목은 아닌데.. 이 책을 보고, 또 앞으로 배워야 할 수학(대학 졸업 하려면-_-)을 생각해보니까 지금까지 내가 공부해왔던 수학이 보잘것 없이 느껴진다. Calculus II, Calculus III, Linear Algebra...
앞으로 수학을 아주아주 열심히 공부해야겠다는 생각이 든다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/202/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
