<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[LIANXU.me]]></title>
  <link href="http://lianxu.me/atom.xml" rel="self"/>
  <link href="http://lianxu.me/"/>
  <updated>2012-05-14T04:25:45-07:00</updated>
  <id>http://lianxu.me/</id>
  <author>
    <name><![CDATA[Xu Lian]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Cocoa中NSString到NSDate的处理]]></title>
    <link href="http://lianxu.me/blog/2012/03/14/speed-up-nsdateformatter/"/>
    <updated>2012-03-14T02:44:00-07:00</updated>
    <id>http://lianxu.me/blog/2012/03/14/speed-up-nsdateformatter</id>
    <content type="html"><![CDATA[<p>NSDate是NS类库中基础类型之一。随着数字化发展，程序对数据处理量越来越大，我们经常从服务器取得的日期是字符串序列，格式化为正确的date类型是一个不可避免的工作。在Cocoa程序里提供了非常方便的函数和类，但是仍然需要我们了解一些技巧。尤其是当我们的程序面对大量的日期字符串转换的时候，要格外的注意。苹果文档中使用NSDateFormatter类格式化日期字符串，但是以防读者不知道，我这里提一下：它的速度非常慢！！这篇文章介绍如何处理这种情况。</p>

<!--more-->




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">NSDate</span> <span class="o">*</span><span class="p">)</span><span class="nf">dateFromString:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">string</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">//Wed Mar 14 16:40:08 +0800 2012</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">string</span><span class="p">)</span> <span class="k">return</span> <span class="nb">nil</span><span class="p">;</span>
</span><span class='line'>    <span class="n">NSDateFormatter</span> <span class="o">*</span><span class="n">dateformatter</span><span class="o">=</span><span class="n">dateformatter</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSDateFormatter</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'>    <span class="n">NSTimeZone</span> <span class="o">*</span><span class="n">tz</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSTimeZone</span> <span class="nl">timeZoneWithAbbreviation:</span><span class="s">@&quot;GMT&quot;</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">dateformatter</span> <span class="nl">setTimeZone:</span><span class="n">tz</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">dateformatter</span> <span class="nl">setDateFormat:</span><span class="s">@&quot;EEE MMM dd HH:mm:ss Z yyyy&quot;</span><span class="p">];;</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">[</span><span class="n">dateformatter</span> <span class="nl">dateFromString:</span><span class="n">string</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>由于NSDateFormatter内部代码原因，所以格式化字符串代价很大。对于个别地方使用它做日期转换是非常方便的，但是如果是放在一个大的循环内部，直接使用NSDateFormatter绝对不是明智的选择。它很有可能成为拖慢你程序速度的元凶。</p>

<p>其实如果你知道你的程序将会取得什么格式的日期字符串，那么直接分解字符串后利用NSCalendar和NSDateComponents可以提高速度很多。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">NSDate</span><span class="o">*</span><span class="p">)</span><span class="nf">mydateFromString:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">string</span><span class="p">;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="c1">//Wed Mar 14 16:40:08 +0800 2012</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">string</span><span class="p">)</span> <span class="k">return</span> <span class="nb">nil</span><span class="p">;</span>
</span><span class='line'>    <span class="k">static</span> <span class="n">NSCalendar</span> <span class="o">*</span><span class="n">gregorian</span><span class="o">=</span><span class="nb">nil</span><span class="p">;</span>
</span><span class='line'>    <span class="k">static</span> <span class="n">NSDateComponents</span> <span class="o">*</span><span class="n">comps</span><span class="o">=</span><span class="nb">nil</span><span class="p">;</span>
</span><span class='line'>    <span class="k">static</span> <span class="n">NSDictionary</span> <span class="o">*</span><span class="n">month</span><span class="o">=</span><span class="nb">nil</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">gregorian</span><span class="o">==</span><span class="nb">nil</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">gregorian</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSCalendar</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithCalendarIdentifier:</span><span class="n">NSGregorianCalendar</span><span class="p">];</span>
</span><span class='line'>        <span class="n">comps</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSDateComponents</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'>        <span class="n">month</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSDictionary</span> <span class="nl">dictionaryWithObjectsAndKeys:</span>
</span><span class='line'>                 <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">1</span><span class="p">],</span> <span class="s">@&quot;Jan&quot;</span><span class="p">,</span>
</span><span class='line'>                 <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">2</span><span class="p">],</span> <span class="s">@&quot;Feb&quot;</span><span class="p">,</span>
</span><span class='line'>                 <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">3</span><span class="p">],</span> <span class="s">@&quot;Mar&quot;</span><span class="p">,</span>
</span><span class='line'>                 <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">4</span><span class="p">],</span> <span class="s">@&quot;Apr&quot;</span><span class="p">,</span>
</span><span class='line'>                 <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">5</span><span class="p">],</span> <span class="s">@&quot;May&quot;</span><span class="p">,</span>
</span><span class='line'>                 <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">6</span><span class="p">],</span> <span class="s">@&quot;Jun&quot;</span><span class="p">,</span>
</span><span class='line'>                 <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">7</span><span class="p">],</span> <span class="s">@&quot;Jul&quot;</span><span class="p">,</span>
</span><span class='line'>                 <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">8</span><span class="p">],</span> <span class="s">@&quot;Aug&quot;</span><span class="p">,</span>
</span><span class='line'>                 <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">9</span><span class="p">],</span> <span class="s">@&quot;Sep&quot;</span><span class="p">,</span>
</span><span class='line'>                 <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">10</span><span class="p">],</span> <span class="s">@&quot;Oct&quot;</span><span class="p">,</span>
</span><span class='line'>                 <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">11</span><span class="p">],</span> <span class="s">@&quot;Nov&quot;</span><span class="p">,</span>
</span><span class='line'>                 <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">12</span><span class="p">],</span> <span class="s">@&quot;Dec&quot;</span><span class="p">,</span>
</span><span class='line'>                 <span class="nb">nil</span><span class="p">];</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">@try</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">NSString</span> <span class="o">*</span><span class="n">t</span><span class="o">=</span><span class="p">[</span><span class="n">string</span> <span class="nl">substringWithRange:</span><span class="n">NSMakeRange</span><span class="p">(</span><span class="mi">26</span><span class="p">,</span> <span class="mi">4</span><span class="p">)];</span>
</span><span class='line'>        <span class="p">[</span><span class="n">comps</span> <span class="nl">setYear:</span><span class="p">[</span><span class="n">t</span> <span class="n">intValue</span><span class="p">]];</span>
</span><span class='line'>        <span class="n">t</span><span class="o">=</span><span class="p">[</span><span class="n">string</span> <span class="nl">substringWithRange:</span><span class="n">NSMakeRange</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">)];</span>
</span><span class='line'>        <span class="p">[</span><span class="n">comps</span> <span class="nl">setMonth:</span><span class="p">[[</span><span class="n">month</span> <span class="nl">objectForKey:</span><span class="n">t</span><span class="p">]</span> <span class="n">intValue</span><span class="p">]];</span>
</span><span class='line'>        <span class="n">t</span><span class="o">=</span><span class="p">[</span><span class="n">string</span> <span class="nl">substringWithRange:</span><span class="n">NSMakeRange</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">2</span><span class="p">)];</span>
</span><span class='line'>        <span class="p">[</span><span class="n">comps</span> <span class="nl">setDay:</span><span class="p">[</span><span class="n">t</span> <span class="n">intValue</span><span class="p">]];</span>
</span><span class='line'>        <span class="n">t</span><span class="o">=</span><span class="p">[</span><span class="n">string</span> <span class="nl">substringWithRange:</span><span class="n">NSMakeRange</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span> <span class="mi">2</span><span class="p">)];</span>
</span><span class='line'>        <span class="p">[</span><span class="n">comps</span> <span class="nl">setHour:</span><span class="p">[</span><span class="n">t</span> <span class="n">intValue</span><span class="p">]];</span>
</span><span class='line'>        <span class="n">t</span><span class="o">=</span><span class="p">[</span><span class="n">string</span> <span class="nl">substringWithRange:</span><span class="n">NSMakeRange</span><span class="p">(</span><span class="mi">14</span><span class="p">,</span> <span class="mi">2</span><span class="p">)];</span>
</span><span class='line'>        <span class="p">[</span><span class="n">comps</span> <span class="nl">setMinute:</span><span class="p">[</span><span class="n">t</span> <span class="n">intValue</span><span class="p">]];</span>
</span><span class='line'>        <span class="n">t</span><span class="o">=</span><span class="p">[</span><span class="n">string</span> <span class="nl">substringWithRange:</span><span class="n">NSMakeRange</span><span class="p">(</span><span class="mi">17</span><span class="p">,</span> <span class="mi">2</span><span class="p">)];</span>
</span><span class='line'>        <span class="p">[</span><span class="n">comps</span> <span class="nl">setSecond:</span><span class="p">[</span><span class="n">t</span> <span class="n">intValue</span><span class="p">]];</span>
</span><span class='line'>        <span class="n">t</span><span class="o">=</span><span class="p">[</span><span class="n">string</span> <span class="nl">substringWithRange:</span><span class="n">NSMakeRange</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="mi">5</span><span class="p">)];</span>
</span><span class='line'>        <span class="c1">//全球共24个标准时区，每个时区为1个小时，下面计算该时区offset秒数</span>
</span><span class='line'>        <span class="p">[</span><span class="n">comps</span> <span class="nl">setTimeZone:</span><span class="p">[</span><span class="n">NSTimeZone</span> <span class="nl">timeZoneForSecondsFromGMT:</span><span class="p">[</span><span class="n">t</span> <span class="n">intValue</span><span class="p">]</span><span class="o">/</span><span class="mi">100</span><span class="o">*</span><span class="mi">3600</span><span class="p">]];</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">@catch</span> <span class="p">(</span><span class="n">NSException</span> <span class="o">*</span><span class="n">exception</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">@finally</span> <span class="p">{</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">return</span> <span class="p">[</span><span class="n">gregorian</span> <span class="nl">dateFromComponents:</span><span class="n">comps</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>如果要更快，就需要抛弃ObjC,编写c代码格式化时间字符串。如下代码经过测试是最快的。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">NSDate</span> <span class="o">*</span><span class="p">)</span><span class="nf">dateFromString:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">string</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">//Wed Mar 14 16:40:08 +0800 2012</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">string</span><span class="p">)</span> <span class="k">return</span> <span class="nb">nil</span><span class="p">;</span>
</span><span class='line'>    <span class="k">struct</span> <span class="n">tm</span> <span class="n">tm</span><span class="p">;</span>
</span><span class='line'>    <span class="n">time_t</span> <span class="n">t</span><span class="p">;</span>
</span><span class='line'>    <span class="n">string</span><span class="o">=</span><span class="p">[</span><span class="n">string</span> <span class="nl">substringFromIndex:</span><span class="mi">4</span><span class="p">];</span>
</span><span class='line'>    <span class="n">strptime</span><span class="p">([</span><span class="n">string</span> <span class="nl">cStringUsingEncoding:</span><span class="n">NSUTF8StringEncoding</span><span class="p">],</span> <span class="s">&quot;%b %d %H:%M:%S %z %Y&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">tm</span><span class="p">);</span>
</span><span class='line'>    <span class="n">tm</span><span class="p">.</span><span class="n">tm_isdst</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">t</span> <span class="o">=</span> <span class="n">mktime</span><span class="p">(</span><span class="o">&amp;</span><span class="n">tm</span><span class="p">);</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">[</span><span class="n">NSDate</span> <span class="nl">dateWithTimeIntervalSince1970:</span><span class="n">t</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>下面是我简单测试循环10000次解析日期字符串的时间比较。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="mi">2012</span><span class="o">-</span><span class="mo">05</span><span class="o">-</span><span class="mo">05</span> <span class="mi">15</span><span class="o">:</span><span class="mi">57</span><span class="o">:</span><span class="mf">51.942</span> <span class="n">timetest</span><span class="p">[</span><span class="mi">18488</span><span class="o">:</span><span class="mi">707</span><span class="p">]</span> <span class="mf">1.991521</span> <span class="c1">//第一种</span>
</span><span class='line'><span class="mi">2012</span><span class="o">-</span><span class="mo">05</span><span class="o">-</span><span class="mo">05</span> <span class="mi">15</span><span class="o">:</span><span class="mi">57</span><span class="o">:</span><span class="mf">52.096</span> <span class="n">timetest</span><span class="p">[</span><span class="mi">18488</span><span class="o">:</span><span class="mi">707</span><span class="p">]</span> <span class="mf">0.921144</span><span class="err">　</span><span class="c1">//第二种</span>
</span><span class='line'><span class="mi">2012</span><span class="o">-</span><span class="mo">05</span><span class="o">-</span><span class="mo">05</span> <span class="mi">15</span><span class="o">:</span><span class="mi">57</span><span class="o">:</span><span class="mf">54.088</span> <span class="n">timetest</span><span class="p">[</span><span class="mi">18488</span><span class="o">:</span><span class="mi">707</span><span class="p">]</span> <span class="mf">0.153897</span><span class="err">　</span><span class="c1">//第三种</span>
</span></code></pre></td></tr></table></div></figure>


<p>最后作为参考资料，说明一下 OSX 10.6 下 NSDateFormatter 使用 Unicode Locale Data Markup Language (LDML) <a href="http://unicode.org/reports/tr35/tr35-10.html#Number_Format_Patterns">version tr35-10</a>　标准。作为标准文档，Apple是不会全部写到开发文档里的，不明白的同学可以到这查看。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Web应用中一种用户友好Email验证模式]]></title>
    <link href="http://lianxu.me/blog/2012/02/18/javascript-user-friendly-email-checker/"/>
    <updated>2012-02-18T03:49:00-08:00</updated>
    <id>http://lianxu.me/blog/2012/02/18/javascript-user-friendly-email-checker</id>
    <content type="html"><![CDATA[<p>每过一段时间，我的网站和论坛就会出现注册邮件错误问题。而且往往是缺少某个字符这样的错误。例如：hotmail.com写成了hotmai.com 对于这种意图明确但又不容易发现的错误，普通邮件格式验证函数是无法处理的。因为这种拼写错误依然属于合法邮件地址。但是一个友好的Web页面应该给与用户适当的提示。这里我提出一个容易想到的简单方法处理这个问题。</p>

<!--more-->


<p>我们计算用户输入的邮件域和一些常见邮件域的 <a href="http://en.wikipedia.org/wiki/Levenshtein_distance">Levenshtein Distance</a>,也称作字符串编辑距离，是指从一个字符串转换到另一个字符串最小的编辑操作次数。对于LD足够小但又不为0的情况，给于用户提示。</p>

<p>下面给出Levenshtein Distance的js实现代码：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">levenshtein</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">i</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">j</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">cost</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">d</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Array</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">a</span><span class="p">.</span><span class="nx">length</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="nx">b</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">b</span><span class="p">.</span><span class="nx">length</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="nx">a</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">for</span> <span class="p">(</span><span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;=</span> <span class="nx">a</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">d</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Array</span><span class="p">();</span>
</span><span class='line'>        <span class="nx">d</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="nx">i</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">for</span> <span class="p">(</span><span class="nx">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">j</span> <span class="o">&lt;=</span> <span class="nx">b</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">d</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="nx">j</span><span class="p">]</span> <span class="o">=</span> <span class="nx">j</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">for</span> <span class="p">(</span><span class="nx">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;=</span> <span class="nx">a</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="nx">j</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">j</span> <span class="o">&lt;=</span> <span class="nx">b</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>          <span class="nx">cost</span> <span class="o">=</span> <span class="p">(</span><span class="nx">a</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="nx">b</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">j</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span> <span class="o">?</span> <span class="mi">0</span> <span class="o">:</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>          
</span><span class='line'>            <span class="nx">d</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span><span class="p">]</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">d</span><span class="p">[</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">][</span><span class="nx">j</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">d</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">d</span><span class="p">[</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">][</span><span class="nx">j</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="nx">cost</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="nx">i</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="nx">j</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span>
</span><span class='line'>              <span class="nx">a</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="nx">b</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">j</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">&amp;&amp;</span>
</span><span class='line'>              <span class="nx">a</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">==</span> <span class="nx">b</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">j</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>                <span class="nx">d</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span><span class="p">]</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">d</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span><span class="p">],</span> <span class="nx">d</span><span class="p">[</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">2</span><span class="p">][</span><span class="nx">j</span> <span class="o">-</span> <span class="mi">2</span><span class="p">]</span> <span class="o">+</span> <span class="nx">cost</span><span class="p">)</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="nx">a</span><span class="p">.</span><span class="nx">length</span><span class="p">][</span><span class="nx">b</span><span class="p">.</span><span class="nx">length</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>接下来我们要准备一些常用的邮件域信息：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">checkCommonMail</span><span class="p">(</span><span class="nx">id</span><span class="p">,</span><span class="nx">errorid</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">email</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="nx">id</span><span class="p">).</span><span class="nx">value</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">useremailDomain</span><span class="o">=</span><span class="nx">email</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="nx">email</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s2">&quot;@&quot;</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span><span class="p">).</span><span class="nx">toLowerCase</span><span class="p">();</span>
</span><span class='line'>      <span class="kd">var</span> <span class="nx">error</span><span class="o">=</span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="nx">errorid</span><span class="p">);</span>
</span><span class='line'>      
</span><span class='line'>      <span class="kd">var</span> <span class="nx">commonDomain</span> <span class="o">=</span> <span class="p">[</span>
</span><span class='line'>          <span class="s2">&quot;hotmail.com&quot;</span><span class="p">,</span>
</span><span class='line'>          <span class="s2">&quot;gmail.com&quot;</span><span class="p">,</span>
</span><span class='line'>          <span class="p">[</span><span class="s2">&quot;yahoo.cn&quot;</span><span class="p">,</span><span class="s2">&quot;yahoo.hk&quot;</span><span class="p">,</span><span class="s2">&quot;yahoo.com.cn&quot;</span><span class="p">,</span><span class="s2">&quot;yahoo.com.hk&quot;</span><span class="p">,</span><span class="s2">&quot;yahoo.com&quot;</span><span class="p">],</span>
</span><span class='line'>          <span class="s2">&quot;163.com&quot;</span><span class="p">,</span>
</span><span class='line'>          <span class="s2">&quot;sina.com&quot;</span><span class="p">,</span>
</span><span class='line'>          <span class="s2">&quot;live.com&quot;</span><span class="p">,</span>
</span><span class='line'>          <span class="s2">&quot;qq.com&quot;</span><span class="p">,</span>
</span><span class='line'>          <span class="s2">&quot;vip.qq.com&quot;</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="nx">i</span><span class="o">&lt;</span><span class="nx">commonDomain</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span><span class="nx">i</span><span class="o">++</span><span class="p">){</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="nx">commonDomain</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nb">Array</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="kd">var</span> <span class="nx">pardomain</span><span class="o">=</span><span class="nx">commonDomain</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
</span><span class='line'>          <span class="kd">var</span> <span class="nx">dis</span><span class="o">=</span><span class="k">new</span> <span class="nb">Array</span><span class="p">();</span>
</span><span class='line'>          <span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="nx">j</span><span class="o">&lt;</span><span class="nx">pardomain</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span><span class="nx">j</span><span class="o">++</span><span class="p">){</span>
</span><span class='line'>              <span class="nx">dis</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span><span class="o">=</span><span class="nx">levenshtein</span><span class="p">(</span><span class="nx">useremailDomain</span><span class="p">,</span><span class="nx">pardomain</span><span class="p">[</span><span class="nx">j</span><span class="p">]);</span>
</span><span class='line'>          <span class="p">}</span>
</span><span class='line'>          <span class="kd">var</span> <span class="nx">mindis</span><span class="o">=</span><span class="mi">100000</span><span class="p">,</span><span class="nx">minj</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'>          <span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="nx">j</span><span class="o">&lt;</span><span class="nx">dis</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span><span class="nx">j</span><span class="o">++</span><span class="p">){</span>
</span><span class='line'>              <span class="k">if</span><span class="p">(</span><span class="nx">dis</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span><span class="o">==</span><span class="mi">0</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
</span><span class='line'>              <span class="k">if</span><span class="p">(</span><span class="nx">dis</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span><span class="o">&lt;</span><span class="nx">mindis</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                  <span class="nx">mindis</span><span class="o">=</span><span class="nx">dis</span><span class="p">[</span><span class="nx">j</span><span class="p">];</span>
</span><span class='line'>                  <span class="nx">minj</span><span class="o">=</span><span class="nx">j</span><span class="p">;</span>
</span><span class='line'>              <span class="p">}</span>
</span><span class='line'>          <span class="p">}</span>
</span><span class='line'>          <span class="k">if</span><span class="p">(</span><span class="nx">mindis</span><span class="o">==</span><span class="mi">0</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
</span><span class='line'>          <span class="k">if</span><span class="p">(</span><span class="nx">mindis</span><span class="o">&lt;</span><span class="mi">3</span><span class="p">){</span>
</span><span class='line'>              <span class="nx">error</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="s1">&#39;您的邮件地址很像&#39;</span><span class="o">+</span><span class="nx">pardomain</span><span class="p">[</span><span class="nx">minj</span><span class="p">]</span><span class="o">+</span><span class="s1">&#39;？&#39;</span><span class="p">;</span>
</span><span class='line'>          <span class="p">}</span>
</span><span class='line'>          <span class="k">delete</span> <span class="nx">dis</span><span class="p">;</span>
</span><span class='line'>          <span class="k">return</span><span class="p">;</span>
</span><span class='line'>      <span class="p">}</span><span class="k">else</span><span class="p">{</span>
</span><span class='line'>          <span class="kd">var</span> <span class="nx">dis</span><span class="o">=</span><span class="nx">levenshtein</span><span class="p">(</span><span class="nx">useremailDomain</span><span class="p">,</span><span class="nx">commonDomain</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
</span><span class='line'>          <span class="k">if</span><span class="p">(</span><span class="nx">dis</span><span class="o">==</span><span class="mi">0</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
</span><span class='line'>          <span class="k">if</span><span class="p">(</span><span class="nx">dis</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">){</span>
</span><span class='line'>              <span class="nx">error</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="s1">&#39;您的邮件地址很像&#39;</span><span class="o">+</span><span class="nx">commonDomain</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span><span class="o">+</span><span class="s1">&#39;？&#39;</span><span class="p">;</span>
</span><span class='line'>              <span class="k">return</span><span class="p">;</span>
</span><span class='line'>          <span class="p">}</span>
</span><span class='line'>          <span class="k">delete</span> <span class="nx">dis</span><span class="p">;</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>上面的函数中yahoo域为并列结算，这样计算更符合用户的意图。</p>

<p>该方式适用处理用户无意间输入的错误。当然你可以同时配合邮箱格式验证函数，来过滤掉一些完全错误的邮箱输入：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">checkMail</span><span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">email</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="nx">id</span><span class="p">).</span><span class="nx">value</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">pattern</span> <span class="o">=</span> <span class="sr">/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">pattern</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">email</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>最后加一句题外话。作为一个普通的程序员，应该能够合理的应用上述功能函数。但是作为一个优秀的程序员，应该能理解上述函数算法。通过阅读上面levenshtein函数，优秀的程序员应该立即识别出这是一个典型的动态规划算法，哪里是动态转移方程，时间复杂度大概是什么等等。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[世界第一个红唇Emoji域名]]></title>
    <link href="http://lianxu.me/blog/2012/02/13/the-world-first-red-lip-emoji-domain/"/>
    <updated>2012-02-13T20:21:00-08:00</updated>
    <id>http://lianxu.me/blog/2012/02/13/the-world-first-red-lip-emoji-domain</id>
    <content type="html"><![CDATA[<p>Mac OS Lion已经发布多时，其中一个伴随系统的重要特性是Emoji表情。现在Emoji已经被接受成为Unicode 6.0 ISO 10646标准。而在此之前，Emoji一直作为移动设备上使用“私有&#8221;Unicode地址的“绘文字”。</p>

<p>大约在2011年6月21日，世界第一个Emoji字符的域名被生成了，它就是：</p>

<div style="text-align:center;font-size:2em;margin:20px auto;"><a href="http://💩.la" style="text-decoration:none;color:#333">http://💩.la</a></div>


<p>而在此刻我荣幸的宣布，成功注册了世界上第一个漂亮的红唇Emoji域名:</p>

<div style="text-align:center;font-size:3em;margin:40px auto;"><a href="http://💋.tk" style="text-decoration:none;color:#333">http://💋.tk</a></div>


<!--more-->


<p>以防，您现在使用的不是Lion下的Safari浏览器，我下面发一张图片，显示这个域名的样子：</p>

<p><img class="center" src="http://lianxu.me/images/post/kissdomain.png"></p>

<p>根据消息，.la的Emoji域名注册已经停止。但是还有其它一些域名，例如.tk的Emoji域名可以<a href="http://iwantmyname.com">注册</a>。</p>

<p>也许你会问：“这些域名有什么用？只能在Lion下的Safari才能看到。” 的确，我也知道Window下不能正确处理Emoji字符。但是，这个问题现在问还为时过早。这里只是希望给大家打开一个不同的大门，从今以后因特网将不再和昨天一样。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Gap Theory of UI Design - John Gruber]]></title>
    <link href="http://lianxu.me/blog/2011/12/26/john-gruber-the-gap-theory-of-ui-design/"/>
    <updated>2011-12-26T05:15:00-08:00</updated>
    <id>http://lianxu.me/blog/2011/12/26/john-gruber-the-gap-theory-of-ui-design</id>
    <content type="html"><![CDATA[<p>一般情况我很少发布视频博客，但是这个演讲非常的好。来自<a href="http://daringfireball.net/">John Gruber</a>，非常优秀的程序员和设计师。同时也是<a href="http://en.wikipedia.org/wiki/Markdown">Markdown</a>的设计者。</p>

<p><video width='640' height='360' preload='none' controls poster=' http://www.beyondcow.com/videos/Webstock11_John_Gruber.jpg'><source src='http://www.beyondcow.com/videos/Webstock11_John_Gruber.mp4' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'/></video></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[介绍Octopress里使用Ender Javascript库]]></title>
    <link href="http://lianxu.me/blog/2011/12/26/octopress-ender-javascript-tutorial/"/>
    <updated>2011-12-26T03:54:00-08:00</updated>
    <id>http://lianxu.me/blog/2011/12/26/octopress-ender-javascript-tutorial</id>
    <content type="html"><![CDATA[<p>很多喜欢便利的web开发人员也许很熟悉jQuery脚本库。但是转移到Octopress下面，它并没有自带jQuery，这一点让我这个非前端开发者但又经常需要做web开发的人为难了好久。因为当我试着自己增加jQuery到Octopress头部的时候，会出现和其它库的冲突问题。既然如此就有必要学习一下Octopress提供的库和它们的优势了。</p>

<!--more-->


<p>打开Octopress的网页头部代码，可以看到自带的js脚本包括：<a href="http://www.modernizr.com/">modernizr</a> <a href="http://ender.no.de/">ender</a> 和一个octopress.js文件。实际上准确来说除了modernizer，其它2个不算是库。</p>

<p>Modernizer是一个提高HTML5,CSS3标准化的库，它的作用很简单，就是检测一个浏览器是不是具有某个特性。与传统的通过navigator.userAgent方法不同，modernizer具有实际测试某项特性的能力，所以使用它会让网页显示标准化更准确。但是对我现在来说，它的作用不大。我是希望可以找到代替jquery做seletor engine再加上ajax请求的库，这样我可以方便的给Octopress增加我自己需求的异步请求特性等等。</p>

<p>再看octopress.js这个文件其实也不是我需要的，它是Octopress自己的一个脚本文件，做一下初始化工作等等。</p>

<p>那么就只能从ender入手了。其实这个名字也是我第一次接触。当第一次进入它的网站<a href="http://ender.no.de/">http://ender.no.de/</a>就发现确实能替代jquery，可以看一下Ender官方网站首页截图如下：</p>

<p><img class="right" src="http://lianxu.me/images/post/ender.png" title="ender" ></p>

<p>是不是一下子又看到了类似jQuery的亲切的语法了呢！而且可以看到有选择器、event binding根据、css属性修改、loop工具和ajax请求工具。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#content a.button&#39;</span><span class="p">)</span>
</span><span class='line'>  <span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="s1">&#39;click.button&#39;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">data</span><span class="p">(</span><span class="s1">&#39;clicked&#39;</span><span class="p">,</span> <span class="kc">true</span><span class="p">).</span><span class="nx">unbind</span><span class="p">()</span>
</span><span class='line'>    <span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">()</span>
</span><span class='line'>  <span class="p">})</span>
</span><span class='line'>  <span class="p">.</span><span class="nx">css</span><span class="p">({</span>
</span><span class='line'>      <span class="nx">opacity</span><span class="o">:</span> <span class="mi">1</span>
</span><span class='line'>    <span class="p">,</span> <span class="nx">color</span><span class="o">:</span> <span class="s1">&#39;red&#39;</span>
</span><span class='line'>  <span class="p">})</span>
</span><span class='line'>  <span class="p">.</span><span class="nx">fadeOut</span><span class="p">(</span><span class="mi">250</span><span class="p">)</span>
</span><span class='line'><span class="nx">$</span><span class="p">.</span><span class="nx">map</span><span class="p">([</span><span class="s1">&#39;a&#39;</span><span class="p">,</span> <span class="s1">&#39;b&#39;</span><span class="p">,</span> <span class="s1">&#39;c&#39;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">letter</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">letter</span><span class="p">.</span><span class="nx">toUpperCase</span><span class="p">()</span>
</span><span class='line'><span class="p">})</span>
</span><span class='line'><span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">(</span><span class="s1">&#39;/data&#39;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#content&#39;</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span>
</span><span class='line'><span class="p">})</span>
</span></code></pre></td></tr></table></div></figure>


<p>但是如果你进一步查看官方说明就会了解，Ender其实并不是jquery的替代产品，它甚至不算一个js库。它是一个前端脚步库的管理工具。可以根据不同的需求编译和重组不同的js库。它的哲学是：</p>

<blockquote><p>small, loosely coupled modules are the future and large, tightly-bound monolithic libraries are the past!</p></blockquote>


<p>这个观点非常吸引人。根据需求提供代码总是web程序员希望达到，却又很少去做的部分。例如你的网站加了一个jquery.js但是实际上，你的网站到底用到了这个库里多少功能呢？20%~40%，我觉得已经很高了。</p>

<p>既然Ender是这个情况，我们就需要看看Octopress给ender里编译了几个库进去。打开Octopress提供的ender.js文件，可以看到头部注释：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="cm">/*!</span>
</span><span class='line'><span class="cm">  * =============================================================</span>
</span><span class='line'><span class="cm">  * Ender: open module JavaScript framework (https://ender.no.de)</span>
</span><span class='line'><span class="cm">  * Build: ender build jeesh reqwest</span>
</span><span class='line'><span class="cm">  * =============================================================</span>
</span><span class='line'><span class="cm">  */</span>
</span></code></pre></td></tr></table></div></figure>


<p>其中jessh是由4个库组成的小巧工具集合大小7.5k。你也可以通过ender工具自己选择去掉其中某些。</p>

<ul>
<li>domReady - a cross-browser domReady</li>
<li>Qwery - a fast light-weight selector engine</li>
<li>Bonzo - a bullet-proof DOM utility</li>
<li>Bean - a multi-platform Event provider</li>
</ul>


<h3>domready</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">.</span><span class="nx">domReady</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{...})</span>
</span></code></pre></td></tr></table></div></figure>


<h3>DOM queries</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#boosh a[rel~=&quot;bookmark&quot;]&#39;</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">el</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">})</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Manipulation</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#boosh p a[rel~=&quot;bookmark&quot;]&#39;</span><span class="p">).</span><span class="nx">hide</span><span class="p">().</span><span class="nx">html</span><span class="p">(</span><span class="s1">&#39;hello&#39;</span><span class="p">).</span><span class="nx">css</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">color</span><span class="o">:</span> <span class="s1">&#39;red&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;text-decoration&#39;</span><span class="o">:</span> <span class="s1">&#39;none&#39;</span>
</span><span class='line'><span class="p">}).</span><span class="nx">addClass</span><span class="p">(</span><span class="s1">&#39;blamo&#39;</span><span class="p">).</span><span class="nx">after</span><span class="p">(</span><span class="s1">&#39;✓&#39;</span><span class="p">).</span><span class="nx">show</span><span class="p">();</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Events</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#content a&#39;</span><span class="p">).</span><span class="nx">bind</span><span class="p">(</span><span class="s1">&#39;keydown input&#39;</span><span class="p">,</span> <span class="nx">handler</span><span class="p">)</span>
</span><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#content a&#39;</span><span class="p">).</span><span class="nx">emit</span><span class="p">(</span><span class="s1">&#39;customEvent&#39;</span><span class="p">)</span>
</span><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#content a&#39;</span><span class="p">).</span><span class="nx">remove</span><span class="p">(</span><span class="s1">&#39;click.myClick&#39;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>而reqwest是一个ajax库<a href="https://github.com/ded/reqwest">https://github.com/ded/reqwest</a>。这里列出几个样例代码：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">reqwest</span><span class="p">({</span>
</span><span class='line'>    <span class="nx">url</span><span class="o">:</span> <span class="s1">&#39;path/to/html&#39;</span>
</span><span class='line'>  <span class="p">,</span> <span class="nx">method</span><span class="o">:</span> <span class="s1">&#39;post&#39;</span>
</span><span class='line'>  <span class="p">,</span> <span class="nx">data</span><span class="o">:</span> <span class="p">{</span> <span class="nx">foo</span><span class="o">:</span> <span class="s1">&#39;bar&#39;</span><span class="p">,</span> <span class="nx">baz</span><span class="o">:</span> <span class="mi">100</span> <span class="p">}</span>
</span><span class='line'>  <span class="p">,</span> <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">qwery</span><span class="p">(</span><span class="s1">&#39;#content&#39;</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">})</span>
</span></code></pre></td></tr></table></div></figure>


<p>不过不能直接按照reqwest官方文档的方法来，根据在Octopress里的实际测试，发现通过ender编译的reqwest需要使用不同的语法。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
</span><span class='line'>    <span class="nx">url</span><span class="o">:</span> <span class="s1">&#39;path/to/html&#39;</span>
</span><span class='line'>  <span class="p">,</span> <span class="nx">method</span><span class="o">:</span> <span class="s1">&#39;post&#39;</span>
</span><span class='line'>  <span class="p">,</span> <span class="nx">data</span><span class="o">:</span> <span class="p">{</span> <span class="nx">foo</span><span class="o">:</span> <span class="s1">&#39;bar&#39;</span><span class="p">,</span> <span class="nx">baz</span><span class="o">:</span> <span class="mi">100</span> <span class="p">}</span>
</span><span class='line'>  <span class="p">,</span> <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">qwery</span><span class="p">(</span><span class="s1">&#39;#content&#39;</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">})</span>
</span></code></pre></td></tr></table></div></figure>


<p>至此我需要的jquery的功能就都在ender里找到代替的库了。所以看了，如果你用了Octopress的话就直接放弃jquery这样的库把，相比较ender做出来的库更小巧，并且可订制化更强。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[整合Instagram到Octopress]]></title>
    <link href="http://lianxu.me/blog/2011/12/21/integrate-instagram-into-octopress/"/>
    <updated>2011-12-21T06:21:00-08:00</updated>
    <id>http://lianxu.me/blog/2011/12/21/integrate-instagram-into-octopress</id>
    <content type="html"><![CDATA[<p><img class="right" src="http://lianxu.me/images/post/instagram128.png" width="128" height="128" title="Instagram" >
<img class="right" src="http://lianxu.me/images/post/octopress128.png" width="128" height="128" title="Octopress" >
今天终于丢掉了Wordpress，拥入Octopress的怀抱。其中最大的原因我想是因为比较geek，自己有能力用Octopress。另一方面的原因是看了Matt Gemmell写的 <a href="http://mattgemmell.com/2011/09/12/blogging-with-octopress/" title="Blogging With Octopress">Blogging With Octopress</a> 说它如何如何好(Matt是我喜爱的Mac程序员之一)。 所以呢，如果你不确定是不是要使用Octopress，那么就看看这篇文章介绍它的优势。 不过说实话，其实我是一个不太喜欢写东西的人，相比较而言我更喜欢拍东西。所以在自己的博客加入Instagram对我来说非常重要。这篇文章算是我开始使用Octopress的第一篇hack文，介绍如何把你的Instagram照片及时更新在博客上。</p>

<!--more-->


<h2>目的</h2>

<p>我要达到的目的很简单：<strong>每次我用手机拍一张照片，都希望在我的博客上立即更新出来。</strong>但是Octopress(Jekyll)生成一个纯静态网站，所以要做到这点有些困难，不过方法肯定是有的。大家可以看我的<a href="http://www.lianxu.me/photos/" title="照片">照片</a>里就是及时更新的Instagram照片流。</p>

<h2>理论</h2>

<p>让固定页面(照片页面)，里面嵌入一段动态语言代码，例如php代码，来抓去Instagram的照片。虽然Jekyll解析成了html页面，但Jekyll允许我们指定文件扩展名。这样就可以增加一个php页面。</p>

<h2>需求</h2>

<ol>
<li>需要你已经运行起来Octopress</li>
<li>要求你的网站可以运行动态语言。例如，我的博客支持php</li>
<li>Instagram账户，并且申请到Application Key。请到 <a href="http://instagram.com/developer/">http://instagram.com/developer/</a> 查看详情</li>
</ol>


<h2>注意</h2>

<p>刚开始做这个工作时候，用google搜到了Luke Karrys的 <a href="http://lukecod.es/blog/2011/11/27/instagram-liquid-tag-plugin-for-jekyll-and-octopress/" title="Instagram Liquid Tag Plugin for Jekyll and Octopress">Instagram Liquid Tag Plugin for Jekyll and Octopress</a> 这篇文章。 文章提到了如何利用 <a href="https://github.com/Instagram/instagram-ruby-gem" title="Instagram ruby gem">Instagram ruby gem</a> 开发的一个Jekyll的插件 <a href="https://github.com/lukekarrys/lukelov.es/blob/master/plugins/instagram.rb" title="instagram.rb">instagram.rb</a>。</p>

<p>但是经过进一步阅读代码，发现这个插件并不满足我的要求。因为它还是属于解析成静态页面的类型。</p>

<p>例如：你在用Markdown写你的文章时候使用这样的脚本可以解析成一张Instagram照片。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="o">{</span>% instagram media_id %<span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>该插件并不能帮你及时同步博客照片和Instagram Photo Stream。如果你是需求这种功能请到Luke博客查看安装方法。</p>

<h2>步骤</h2>

<p>首先增加一个“照片&#8221;页面</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>rake new_page<span class="o">[</span><span class="s1">&#39;photos&#39;</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>接着photos目录下新建一个php页面用来和Instagram同步</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>rake new_page<span class="o">[</span><span class="s1">&#39;photos/instagram.php&#39;</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>这时候你应该在source目录下看到photos目录并且下面有index.markdown和instagram.php这2个文件</p>

<p><img src="http://lianxu.me/images/post/photos_index_instagram.png" title="photos_index_instagram" ></p>

<p>手动修改index.markdown到index.php文件，打开该文件增加php include语句，修改如下：</p>

<figure class='code'><figcaption><span>index.php</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">---</span>
</span><span class='line'><span class="x">layout: page</span>
</span><span class='line'><span class="x">title: &quot;我的照片&quot;</span>
</span><span class='line'><span class="x">date: 2011-12-21 05:22</span>
</span><span class='line'><span class="x">comments: true</span>
</span><span class='line'><span class="x">sharing: true</span>
</span><span class='line'><span class="x">footer: true</span>
</span><span class='line'><span class="x">description: My Photos</span>
</span><span class='line'><span class="x">---</span>
</span><span class='line'>
</span><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">include</span><span class="p">(</span><span class="s2">&quot;./instagram.php&quot;</span><span class="p">);</span>
</span><span class='line'><span class="cp">?&gt;</span><span class="x"></span>
</span></code></pre></td></tr></table></div></figure>


<p>然后我们就可以在instagram.php文件里随意写php代码了。注意必须要这样做，因为直接尝试在index.php写php代码会被Jekyll解析的乱七八糟。</p>

<p>现在我们打开instagram.php增加需要的功能。这里我们要做的工作是从instagram取回json数据然后解析成照片列表，这样就嵌入了index.php里。</p>

<figure class='code'><figcaption><span>instagram.php</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'>
</span><span class='line'>  <span class="nv">$access_token</span><span class="o">=</span><span class="s1">&#39;19120281.12eb222.1614fb6d1334221222d66fcd5f258fb&#39;</span><span class="p">;</span>
</span><span class='line'>  <span class="nv">$count_images</span><span class="o">=</span><span class="mi">90</span><span class="p">;</span>
</span><span class='line'>  <span class="nv">$cache_time</span><span class="o">=</span><span class="mi">60</span><span class="p">;</span>
</span><span class='line'>  <span class="nv">$image_size</span><span class="o">=</span><span class="s1">&#39;thumbnail&#39;</span><span class="p">;</span>
</span><span class='line'>  
</span><span class='line'>  <span class="sd">/**</span>
</span><span class='line'><span class="sd">  Output each image with HTML markup</span>
</span><span class='line'><span class="sd"> */</span>
</span><span class='line'>  <span class="k">function</span> <span class="nf">echoimage</span><span class="p">(</span><span class="nv">$val</span><span class="p">,</span> <span class="nv">$imagesize</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="nv">$image</span> <span class="o">=</span> <span class="nv">$val</span><span class="p">[</span><span class="s2">&quot;images&quot;</span><span class="p">][</span><span class="nv">$imagesize</span><span class="p">][</span><span class="s2">&quot;url&quot;</span><span class="p">];</span>
</span><span class='line'>      <span class="nv">$link</span> <span class="o">=</span> <span class="nv">$val</span><span class="p">[</span><span class="s2">&quot;link&quot;</span><span class="p">];</span>
</span><span class='line'>      <span class="nv">$tag</span><span class="o">=</span><span class="nb">md5</span><span class="p">(</span><span class="nv">$link</span><span class="p">);</span>
</span><span class='line'>      <span class="k">return</span> <span class="s2">&quot;&lt;a href=</span><span class="se">\&quot;</span><span class="si">$link</span><span class="se">\&quot;</span><span class="s2"> target=</span><span class="se">\&quot;</span><span class="s2">_blank</span><span class="se">\&quot;</span><span class="s2">&gt;&lt;img src=</span><span class="se">\&quot;</span><span class="si">$image</span><span class="se">\&quot;</span><span class="s2">/&gt;&lt;/a&gt;&quot;</span><span class="p">;</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>      
</span><span class='line'>  <span class="sd">/**</span>
</span><span class='line'><span class="sd">  Getting the Data from the API</span>
</span><span class='line'><span class="sd"> */</span>
</span><span class='line'>  <span class="k">function</span> <span class="nf">getDataFromApi</span><span class="p">(</span><span class="nv">$token</span><span class="p">,</span> <span class="nv">$number</span><span class="p">){</span>
</span><span class='line'>      <span class="c1">// Instagram API bearbeiten</span>
</span><span class='line'>      <span class="nv">$url</span><span class="o">=</span><span class="s2">&quot;https://api.instagram.com/v1/users/self/media/recent/?access_token=</span><span class="si">$token</span><span class="s2">&amp;count=</span><span class="si">$number</span><span class="s2">&quot;</span><span class="p">;</span>
</span><span class='line'>      <span class="nv">$contents</span> <span class="o">=</span> <span class="nb">file_get_contents</span><span class="p">(</span><span class="nv">$url</span><span class="p">);</span>
</span><span class='line'>      <span class="k">return</span> <span class="nv">$contents</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  
</span><span class='line'>  <span class="sd">/**</span>
</span><span class='line'><span class="sd">  Gets the Data from either the Cache or the API</span>
</span><span class='line'><span class="sd"> */</span>
</span><span class='line'>  <span class="k">function</span> <span class="nf">getData</span><span class="p">(</span><span class="nv">$token</span><span class="p">,</span> <span class="nv">$number</span><span class="p">,</span> <span class="nv">$cache_time</span><span class="p">){</span>
</span><span class='line'>
</span><span class='line'>      <span class="nv">$cache_folder</span> <span class="o">=</span> <span class="s2">&quot;your cache path&quot;</span><span class="p">;</span>
</span><span class='line'>  
</span><span class='line'>      <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nb">is_dir</span><span class="p">(</span><span class="nv">$cache_folder</span><span class="p">)){</span>
</span><span class='line'>        <span class="k">if</span><span class="p">(</span><span class="nb">mkdir</span><span class="p">(</span><span class="nv">$cache_folder</span><span class="p">,</span> <span class="mo">0777</span><span class="p">)</span> <span class="o">==</span> <span class="k">false</span><span class="p">){</span>
</span><span class='line'>          <span class="k">return</span> <span class="nx">getDataFromApi</span><span class="p">(</span><span class="nv">$token</span><span class="p">,</span> <span class="nv">$number</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>  
</span><span class='line'>      <span class="nv">$cachefile</span> <span class="o">=</span> <span class="nv">$cache_folder</span><span class="o">.</span><span class="s2">&quot;user.cache&quot;</span><span class="p">;</span>
</span><span class='line'>  
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="nb">file_exists</span><span class="p">(</span><span class="nv">$cachefile</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="nb">time</span><span class="p">()</span><span class="o">-</span><span class="nb">filemtime</span><span class="p">(</span><span class="nv">$cachefile</span><span class="p">)</span><span class="o">&lt;</span><span class="nv">$cache_time</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">try</span><span class="p">{</span>
</span><span class='line'>          <span class="nv">$contents</span> <span class="o">=</span> <span class="nb">file_get_contents</span><span class="p">(</span><span class="nv">$cachefile</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span><span class="k">catch</span><span class="p">(</span><span class="nx">Exception</span> <span class="nv">$e</span><span class="p">){</span>
</span><span class='line'>          <span class="nv">$contents</span> <span class="o">=</span> <span class="nx">getDataFromApi</span><span class="p">(</span><span class="nv">$token</span><span class="p">,</span> <span class="nv">$number</span><span class="p">);</span>
</span><span class='line'>          <span class="nb">file_put_contents</span><span class="p">(</span><span class="nv">$cachefile</span><span class="p">,</span> <span class="nv">$contents</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>  
</span><span class='line'>      <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$contents</span> <span class="o">=</span> <span class="nx">getDataFromApi</span><span class="p">(</span><span class="nv">$token</span><span class="p">,</span> <span class="nv">$number</span><span class="p">);</span>
</span><span class='line'>        <span class="nb">file_put_contents</span><span class="p">(</span><span class="nv">$cachefile</span><span class="p">,</span> <span class="nv">$contents</span><span class="p">);</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>  
</span><span class='line'>      <span class="k">return</span> <span class="nv">$contents</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  
</span><span class='line'>  <span class="nv">$json</span> <span class="o">=</span> <span class="nb">json_decode</span><span class="p">(</span><span class="nx">getData</span><span class="p">(</span><span class="nv">$access_token</span><span class="p">,</span> <span class="nv">$count_images</span><span class="p">,</span> <span class="nv">$cache_time</span><span class="p">),</span> <span class="k">true</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">echo</span> <span class="s1">&#39;&lt;div class=&quot;photosdiv&quot;&gt;&#39;</span><span class="p">;</span>
</span><span class='line'>  <span class="k">foreach</span> <span class="p">(</span><span class="nv">$json</span><span class="p">[</span><span class="s2">&quot;data&quot;</span><span class="p">]</span> <span class="k">as</span> <span class="nv">$value</span><span class="p">)</span>
</span><span class='line'>      <span class="k">echo</span> <span class="nx">echoimage</span><span class="p">(</span><span class="nv">$value</span><span class="p">,</span> <span class="nv">$image_size</span><span class="p">);</span>
</span><span class='line'>  <span class="k">echo</span> <span class="s1">&#39;&lt;/div&gt;&#39;</span><span class="p">;</span>
</span><span class='line'>  
</span><span class='line'><span class="cp">?&gt;</span><span class="x"></span>
</span></code></pre></td></tr></table></div></figure>


<p>在该文件里你需要自己修改2个变量, $access_token和$cache_folder。从instagram注册application api后你可以的到Client ID和Client Secret字符串。然后通过oauth就可以取得access_token。这个过程比较规范我就不详细说了。cache_folder就是一个临时缓存目录随便设置吧，有写权限就可以了，主要保存从instagram取回的json文件。</p>

<h2>最后</h2>

<p>如果你需要在你的导航栏内添加照片页面的链接，记得修改sorce/_includes/custom/navigation.html文件。这样更新Octopress后就和我的博客一样有一个实时更新的照片页面了。</p>

<p>现在拿起你的手机拍照吧，你的家人和朋友会在你的博客上第一时间看到你的照片。</p>

<h2>额外帮助</h2>

<p>很多朋友向我询问，不知如何取得access token。我这里提一下，access token是oauth认证标准的结果，当在instagram　develper哪里注册了账户后会取得Client ID和Client Secret这２个比较重要的值，用来oauth认证中的请求标示。这个过程从编程来看还是比较复杂的，懂得朋友自然明白。但是如果你不清楚，也没关系，instagram提供了方便的管理工具。在<a href="http://instagram.com/developer/manage/">manage</a>页面点左侧菜单<a href="http://instagram.com/developer/api-console/">API Console</a> 然后点地址栏左侧的锁头图标，选择OAuth，管理工具会自动帮你Oauth登陆并返回access token，您可以发送一个users/self/feed请求，查看Request头信息取得access_token数据。由于instagram返回的token没有过期限制，所以您取一次后就可以一直使用了。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[10个迷惑新手的Cocoa&amp;Objective-c开发问题]]></title>
    <link href="http://lianxu.me/blog/2011/11/14/10-cocoa-objc-newbie-problems/"/>
    <updated>2011-11-14T22:16:20-08:00</updated>
    <id>http://lianxu.me/blog/2011/11/14/10-cocoa-objc-newbie-problems</id>
    <content type="html"><![CDATA[<ol>
<li><a href="#1">language background</a></li>
<li><a href="#2">run­time</a></li>
<li><a href="#3">thread</a></li>
<li><a href="#4">run­loop</a></li>
<li><a href="#5">del­e­gate, protocol</a></li>
<li><a href="#6">event respon­der</a></li>
<li><a href="#7">mem­ory management</a></li>
<li><a href="#8">class heritage and category</a></li>
<li><a href="#9">design pattern</a></li>
<li><a href="#10">thinking before asking</a></li>
</ol>


<p>首先请谅解我可能使用很多英文，毕竟英文资料将来会是你的主要资料来源。</p>

<p>这篇博客将描述一些我见到的众多Cocoa开发新手遇到的问题和障碍。在你继续深入学习MacOS编程之前，请停下脚步弄清这些问题。如果你是新手，这个教程不要希望一次能看的非常透彻，学一定阶段反回来再看看又会有新的体会的。</p>

<!--more-->


<p><a id="1"></a></p>

<h2>1. language background</h2>

<p>首先c, c++语言背景，必须。
很多人问：”没有任何语言基础，我不想学c直接学objective-c。“ 这里我简单说几句，objc是c的超集，也就是说大部分objc代码其实是c、而且众多开源代码是c,c++写成的。你不学好c在unix世界里只能是个二流开发者！也许说得过于严厉，不过自己斟酌把。</p>

<p>接着English,必须。
苹果不会把它们文档都写成中文的。“什么，有人翻译？” 等有人闲着翻译出来了的时候，大家都已经卖了很多软件了。你也是跟着人家屁股后面做开发。</p>

<p><a id="2"></a></p>

<h2>2. runtime（运行时）</h2>

<p>Objective-c是动态语言, 很多新手或者开发人员常常被runtime这个东西所迷惑。而恰恰这是一个非常重要的概念。我可以这么问：“如果让你（设计、）实现一个计算机语言，你要如何下手？” 很少程序员这么思考过。但是这么一问，就会强迫你从更高层次思考<a href="#ref1">1</a>以前的问题了。 注意我这句话‘设计’括起来了，稍微次要点，关键是实现。</p>

<p>我把实现分成3种不同的层次:</p>

<p>第一种是传统的面向过程的语言开发，例如c语言。实现c语言编译器很简单，只要按照语法规则实现一个LALR语法分析器就可以了，编译器优化是非常难的topic，不在这里讨论范围内，忽略。 这里我们实现了编译器其中最最基础和原始的目标之一就是把一份代码里的函数名称，转化成一个相对内存地址，把调用这个函数的语句转换成一个jmp跳转指令。在程序开始运行时候，调用语句可以正确跳转到对应的函数地址。 这样很好，也很直白，但是太死板了。Everything is predetermined.</p>

<p>我们希望语言更加灵活，于是有了第二种改进，开发面向对象的语言，例如c++。 c++在c的基础上增加了类的部分。但这到底意味着什么呢？我们再写它的编译器要如何考虑呢？其实，就是让编译器多绕个弯，在严格的c编译器上增加一层类处理的机制，把一个函数限制在它处在的class环境里，每次请求一个函数调用，先找到它的对象, 其类型,返回值，参数等等，确定了这些后再jmp跳转到需要的函数。这样很多程序增加了灵活性同样一个函数调用会根据请求参数和类的环境返回完全不同的结果。增加类机制后，就模拟了现实世界的抽象模式，不同的对象有不同的属性和方法。同样的方法，不同的类有不同的行为！ 这里大家就可以看到作为一个编译器开发者都做了哪些进一步的思考。虽然面相对象语言有所改进，但还是死板, 我们仍然叫c++是static language.</p>

<p>希望更加灵活！于是我们完全把上面哪个类的实现部分抽象出来，做成一套完整运行阶段的检测环境，形成第三种，动态语言。这次再写编译器甚至保留部分代码里的sytax名称，名称错误检测，runtime环境注册所以全局的类，函数，变量等等信息等等，我们可以无限的为这个层增加必要的功能。调用函数时候，会先从这个运行时环境里检测所以可能的参数再做jmp跳转。这，就是runtime。编译器开发起来比上面更加弯弯绕。但是这个层极大增加了程序的灵活性。 例如当调用一个函数时候，前2种语言，很有可能一个jmp到了一个非法地址导致程序crash, 但是在这个层次里面，runtime就过滤掉了这些可能性。 这就是为什么dynamic langauge更加强壮。 因为编译器和runtime环境开发人员已经帮你处理了这些问题。</p>

<p>好了上面说着这么多，我们再返回来看objective-c的这些语句：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="kt">id</span> <span class="n">obj</span><span class="o">=</span><span class="n">self</span><span class="p">;</span>
</span><span class='line'><span class="k">if</span> <span class="p">([</span><span class="n">obj</span> <span class="nl">respondsToSelector:</span><span class="k">@selector</span><span class="p">(</span><span class="nl">function1:</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">if</span> <span class="p">([</span><span class="n">obj</span> <span class="nl">isKindOfClass:</span><span class="p">[</span><span class="n">NSArray</span> <span class="n">class</span><span class="p">]]</span> <span class="p">)</span> <span class="p">{</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">if</span> <span class="p">([</span><span class="n">obj</span> <span class="nl">conformsToProtocol:</span><span class="err">@</span><span class="n">protocol</span><span class="p">(</span><span class="n">myProtocol</span><span class="p">)])</span> <span class="p">{</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">if</span> <span class="p">([[</span><span class="n">obj</span> <span class="n">class</span><span class="p">]</span> <span class="nl">isSubclassOfClass:</span><span class="p">[</span><span class="n">NSArray</span> <span class="n">class</span><span class="p">]])</span> <span class="p">{</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="p">[</span><span class="n">obj</span> <span class="n">someNonExistFunction</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>看似很简单的语句，但是为了让语言实现这个能力，语言开发者要付出很多努力实现runtime环境。这里运行时环境处理了弱类型、函数存在检查工作。runtime会检测注册列表里是否存在对应的函数，类型是否正确，最后确定下来正确的函数地址，再进行保存寄存器状态，压栈，函数调用等等实际的操作。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="kt">id</span> <span class="n">knife</span><span class="o">=</span><span class="p">[</span><span class="n">Knife</span> <span class="n">grateKnife</span><span class="p">];</span>
</span><span class='line'><span class="n">NSArray</span> <span class="o">*</span><span class="n">monsterList</span><span class="o">=</span><span class="p">[</span><span class="n">NSArray</span> <span class="n">array</span><span class="p">];</span>
</span><span class='line'><span class="p">[</span><span class="n">monsterList</span> <span class="nl">makeObjectsPerformSelector:</span><span class="k">@selector</span><span class="p">(</span><span class="nl">killMonster:</span><span class="p">)</span> <span class="nl">withObject:</span><span class="n">knife</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>用c,c++完成这个功能还是比较非常麻烦的，但是动态语言处理却非常简单并且这些语句让objc语言更加intuitive。</p>

<p>在Objc中针对对象的函数调用将不再是普通的函数调用，<code>[obj function1With:var1];</code> 这样的函数调用将被运行时环境转换成<code>objc_msgSend(target,@selector(function1With:),var1);</code>。Objc的runtime环境是开源的，所以我们可以拿出一下实现做简单介绍，可以看到objc_msgSend由汇编语言实现，我们甚至不必阅读代码，只需查看注释就可以了解，运行时环境在函数调用前做了比较全面的安全检查，已确保动态语言函数调用不会导致程序crash。对于希望深入学习的朋友可以自行<a href="http://opensource.apple.com/">下载</a>Objc-runtime源代码来阅读，这里就不再深入讲解。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="cm">/********************************************************************</span>
</span><span class='line'><span class="cm"> * id        objc_msgSend(id self,</span>
</span><span class='line'><span class="cm"> *           SEL op,</span>
</span><span class='line'><span class="cm"> *           ...)</span>
</span><span class='line'><span class="cm"> *</span>
</span><span class='line'><span class="cm"> * On entry: a1 is the message receiver,</span>
</span><span class='line'><span class="cm"> *           a2 is the selector</span>
</span><span class='line'><span class="cm"> ********************************************************************/</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">ENTRY</span> <span class="n">objc_msgSend</span>
</span><span class='line'><span class="cp"># check whether receiver is nil</span>
</span><span class='line'>  <span class="n">teq</span>     <span class="n">a1</span><span class="p">,</span> <span class="err">#</span><span class="mi">0</span>
</span><span class='line'>  <span class="n">moveq</span>   <span class="n">a2</span><span class="p">,</span> <span class="err">#</span><span class="mi">0</span>
</span><span class='line'>  <span class="n">bxeq</span>    <span class="n">lr</span>
</span><span class='line'><span class="cp"> </span>
</span><span class='line'><span class="cp"># save registers and load receiver&#39;s class for CacheLookup</span>
</span><span class='line'>  <span class="n">stmfd</span>   <span class="n">sp</span><span class="o">!</span><span class="p">,</span> <span class="p">{</span><span class="n">a4</span><span class="p">,</span><span class="n">v1</span><span class="o">-</span><span class="n">v3</span><span class="p">}</span>
</span><span class='line'>  <span class="n">ldr</span>     <span class="n">v1</span><span class="p">,</span> <span class="p">[</span><span class="n">a1</span><span class="p">,</span> <span class="err">#</span><span class="n">ISA</span><span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="cp"># receiver is non-nil: search the cache</span>
</span><span class='line'>  <span class="n">CacheLookup</span> <span class="n">a2</span><span class="p">,</span> <span class="n">LMsgSendCacheMiss</span>
</span><span class='line'>
</span><span class='line'><span class="cp"># cache hit (imp in ip) - prep for forwarding, restore registers and call</span>
</span><span class='line'>  <span class="n">teq</span>  <span class="n">v1</span><span class="p">,</span> <span class="n">v1</span>     <span class="cm">/* set nonstret (eq) */</span>
</span><span class='line'>  <span class="n">ldmfd</span>   <span class="n">sp</span><span class="o">!</span><span class="p">,</span> <span class="p">{</span><span class="n">a4</span><span class="p">,</span><span class="n">v1</span><span class="o">-</span><span class="n">v3</span><span class="p">}</span>
</span><span class='line'>  <span class="n">bx</span>      <span class="n">ip</span>
</span><span class='line'>
</span><span class='line'><span class="cp"># cache miss: go search the method lists</span>
</span><span class='line'><span class="nl">LMsgSendCacheMiss:</span>
</span><span class='line'>  <span class="n">ldmfd</span>    <span class="n">sp</span><span class="o">!</span><span class="p">,</span> <span class="p">{</span><span class="n">a4</span><span class="p">,</span><span class="n">v1</span><span class="o">-</span><span class="n">v3</span><span class="p">}</span>
</span><span class='line'>  <span class="n">b</span>    <span class="n">_objc_msgSend_uncached</span>
</span><span class='line'>
</span><span class='line'><span class="nl">LMsgSendExit:</span>
</span><span class='line'>  <span class="n">END_ENTRY</span> <span class="n">objc_msgSend</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>  <span class="p">.</span><span class="n">text</span>
</span><span class='line'>  <span class="p">.</span><span class="n">align</span> <span class="mi">2</span>
</span><span class='line'><span class="nl">_objc_msgSend_uncached:</span>
</span><span class='line'>
</span><span class='line'><span class="cp"># Push stack frame</span>
</span><span class='line'>  <span class="n">stmfd</span>    <span class="n">sp</span><span class="o">!</span><span class="p">,</span> <span class="p">{</span><span class="n">a1</span><span class="o">-</span><span class="n">a4</span><span class="p">,</span><span class="n">r7</span><span class="p">,</span><span class="n">lr</span><span class="p">}</span>
</span><span class='line'>  <span class="n">add</span>     <span class="n">r7</span><span class="p">,</span> <span class="n">sp</span><span class="p">,</span> <span class="err">#</span><span class="mi">16</span>
</span><span class='line'>  <span class="n">SAVE_VFP</span>
</span><span class='line'>
</span><span class='line'><span class="cp"># Load class and selector</span>
</span><span class='line'>  <span class="n">ldr</span>  <span class="n">a1</span><span class="p">,</span> <span class="p">[</span><span class="n">a1</span><span class="p">,</span> <span class="err">#</span><span class="n">ISA</span><span class="p">]</span>        <span class="cm">/* class = receiver-&gt;isa  */</span>
</span><span class='line'><span class="cp"> # MOVE  a2, a2          </span><span class="cm">/* selector already in a2 */</span><span class="cp"></span>
</span><span class='line'>
</span><span class='line'><span class="cp"># Do the lookup</span>
</span><span class='line'>  <span class="n">MI_CALL_EXTERNAL</span><span class="p">(</span><span class="n">__class_lookupMethodAndLoadCache</span><span class="p">)</span>
</span><span class='line'>  <span class="n">MOVE</span>    <span class="n">ip</span><span class="p">,</span> <span class="n">a1</span>
</span><span class='line'>
</span><span class='line'><span class="cp"># Prep for forwarding, Pop stack frame and call imp</span>
</span><span class='line'>  <span class="n">teq</span>  <span class="n">v1</span><span class="p">,</span> <span class="n">v1</span>     <span class="cm">/* set nonstret (eq) */</span>
</span><span class='line'>  <span class="n">RESTORE_VFP</span>
</span><span class='line'>  <span class="n">ldmfd</span>    <span class="n">sp</span><span class="o">!</span><span class="p">,</span> <span class="p">{</span><span class="n">a1</span><span class="o">-</span><span class="n">a4</span><span class="p">,</span><span class="n">r7</span><span class="p">,</span><span class="n">lr</span><span class="p">}</span>
</span><span class='line'>  <span class="n">bx</span>   <span class="n">ip</span>
</span></code></pre></td></tr></table></div></figure>


<p>现在说一下runtime的负面影响:<br/>
1. 关于执行效率问题。 “静态语言执行效率要比动态语言高”，这句没错。因为一部分cpu计算损耗在了runtime过程中，而从上面的汇编代码也可以看出，大概损耗在哪些地方。而静态语言生成的机器指令更简洁。正因为知道这个原因，所以开发语言的人付出很大一部分努力为了保持runtime小巧上。所以objecitve-c是c的超集+一个小巧的runtime环境。 但是，换句话说，从算法角度考虑，这点复杂度不算差别的，Big O notation结果不会有差别。( It&#8217;s not log(n) vs n<sup>2</sup> )<br/>
2. 另外一个就是安全性。动态语言由于运行时环境的需求，会保留一些源码级别的程序结构。这样就给破解带来的方便之门。一个现成的说明就是，java,大家都知道java运行在jre上面。这就是典型的runtime例子。它的执行文件.class全部可以反编译回近似源代码。所以这里的额外提示就是如果你需要写和安全有关的代码，离objc远点，直接用c去。</p>

<p>简单理解：“Runtime is everything between your each function call.”</p>

<p>但是大家要明白，第二点我提到runtime并不只是因为它带来了这些简便的语言特性。而是这些简单的语言特性,在实际运用中需要你从完全不同的角度考虑和解决问题。只是计算1+1，很多语言都是一样的，但是随着问题的复杂，项目的增长，静态语言和动态语言就会演化出完全不同的风景。</p>

<p><a id="3"></a></p>

<h2>3. thread</h2>

<p>&#8220;thread synchronization another notorious trouble!&#8221;</p>

<p>记得上学时候学操作系统这门课，里面都会有专门一章介绍任务调度和生产者消费者的问题。 这就是为今后使用进程、线程开发打基础。概念很简单，但难点在synchronization(同步)，因为死锁检测算法不是100%有效，否则就根本没有死锁这个说法了。另一个原因是往往这类错误很隐晦，静态分析很难找到。同时多线程开发抽象度较高需要经验去把握。</p>

<p>总体来说，我见到的在这方面的问题可以分为一下几点：</p>

<h3>1. 对系统整体结构认识模糊</h3>

<p>不知道多线程开发的几个基点，看别人代码越看越糊涂的。一会NSThread,一会Grand Central Dispatch、block，一会又看到了pthread等等。Apple封装了很多线程的API, 多线程开发的基本结构入下图:</p>

<p><img class="center" src="http://lianxu.me/images/post/threadlayout.jpg" title="Mac OS Thread Architecture" ></p>

<p>可以看到在多线程开发中你可以选择这上面这4种不同的方式。</p>

<p>Mach是核心的操作系统部分。其实这个我也不是非常熟悉，至少我还没有读到过直接使用mach做多线程的代码。</p>

<p>pthread（POSIX Threads）是传统的多线程标准，灵活、轻巧，但是需要理论基础，开发复杂。需要注意一点，根据<a href="http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html#//apple_ref/doc/uid/20000738-125024">apple文档提示</a>，在Cocoa下使用pthread需要先启动至少一个NSThread，确定进入多线程环境后才可以。</p>

<p><a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsthread_Class/Reference/Reference.html">NSThread</a>是Mac OS 10.0后发布的多线程API较为高层，但是缺乏灵活性，而且和pthread相比效率低下。</p>

<p><a href="http://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html">Grand Central Dispatch</a> 是10.6后引入的开源多线程库，它介于pthread和NSThread之间。比NSThread更灵活、小巧，并且不需要像pthread一样考虑很多lock的问题。同时objective-c 2.0发布的新语法特性之一blocks，也正是根据Grand Central Dispatch需求推出的。</p>

<p>所以在你写多线程代码或者阅读多线程代码时候，心理要先明确使用哪种技术。</p>

<h3>2. thread和Reference Counting内存管理造成的问题。</h3>

<blockquote><p>线程里面的方法都要放到NSAutoreleasePool里面吗?</p></blockquote>

<p>这类问题很常见，迷惑的原因是不明白 NSAutoreleasePool 到底是干什么用的。NSAutoreleasePool跟thread其实关系并不显著，它提供一个临时内存管理空间，好比一个沙箱，确保不会有不当的内存分配泄露出来，在这个空间内新分配的对象要向这个pool做一下注册告诉：“pool，我新分配一块空间了”。当pool drain掉或者release，它里面分配过的内存同样释放掉。可见和thread没有很大关系。但是，我们阅读代码的时候经常会看到，新开线程的函数内总是以NSAutoreleasePool开始结束。这又是为什么呢！？ 因为thread内恰好是最适合需要它的地方！ 线程函数应该计算量大，时间长(supposed to be heavy)。在线程里面可能会有大量对象生成，这时使用autoreleasepool管理更简洁。所以这里的答案是，不一定非要在线程里放NSAutoreleasePool，相对的在cocoa环境下任意地方都可以使用NSAutoreleasePool。如果你在线程内不使用NSAutoreleasePool，要记得在内部alloc和relase配对出现保证没有内存泄露。</p>

<h3>3. 线程安全</h3>

<p>每个程序都有一个主线程(main thread),它负责处理事件响应，和UI更新。</p>

<p>更新UI问题。很多新手会因为这个问题，导致程序崩溃或出现各种问题。而且逛论坛会看到所以人都会这么告诉你：“不要在后台线程更新你的UI”。其实这个说法不严密，在多线程环境里处理这个问题需要谨慎，而且要了解线程安全特性。</p>

<p>首先我们需要把“UI更新”这个词做一个说明，它可以有2个层次理解，首先是绘制，其次是显示。这里绘制是可以在任何线程里进行，但是要向屏幕显示出来就需要在主线程操作了。我举个例子说明一下，例如现在我们有一个NSImageView，里面设置了一个NSImage, 这时我想给NSImage加个变色滤镜，这个过程就可以理解为绘制。那么我完全可以再另外一个线程做这个比较费时的操作，滤镜增加完毕再通知NSImageView显示一下。另一个例子就是，Twitter客户端会把每一条微博显示成一个cell，但是速度很快，这就是因为它先对cell做了offscreen的渲染，然后再拿出来显示。</p>

<p>所以通过这点我们也可以得到进一步的认识，合理设计view的更新是非常重要的部分。很多新手写得代码片段没错，只是因为放错了地方就导致整个程序出现各种问题。</p>

<p>根据苹果线程安全摘要说明，再其它线程更新view需要使用lockFocusIfCanDraw和unlockFocus锁定，确保不会出现安全问题。</p>

<p>另外还要知道常用容器的线程安全情况。immutable的容器是线程安全的，而mutable容器则不是。例如NSArray和NSMutableArray。</p>

<h3>4. Asynchronous（异步） vs. Synchronous（同步）</h3>

<blockquote><p>我在一个view要显示多张web图片，我想问一下，我是应该采用异步一个一个下载的方式，还是应该采用多线程同时下载的方式，还是2个都用，那种方式好呢？</p></blockquote>

<p>实际上单独用这２个方法都不好。并不是简单的用了更多线程就提高速度。这个问题同时涉及客户端和服务器的情况。</p>

<p>处理这种类型的程序，比较好的结构应该是：非主线程建立一个队列(相当于Asynchronous任务)，队列里同时启动n个下载任务(相当于Synchronous任务)。这里的n在2~8左右就够了。这个结构下可以认为队列里面每n个任务之间是异步关系，但是这n个任务之间又是同步关系，每次同时下载2~8张图片。这样处理基本可以满足速度要求和各类服务器限制。</p>

<h3>5. thread和run­loop</h3>

<p>runloop是线程里的一部分，但我觉得有必要单独拿出来写，是因为它涉及的东西比较容易误解，而说明它的文章又不多。</p>

<h2>4. run­loop<a id="4"></a></h2>

<p>thread和runloop在以前，开发者根本不太当成一个问题。因为没有静态语言里runloop就是固定的线程执行loop。而现在Cocoa新手搞不明白的太多了，因为没有从动态角度看它，首先回想一下第2点介绍的runtime概念，接着出一个思考题。</p>

<p>现在有一个程序片段如下：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">myThread:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">sender</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">NSAutoreleasePool</span> <span class="o">*</span><span class="n">pool</span><span class="o">=</span><span class="p">[[</span><span class="n">NSAutoreleasePool</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'>  <span class="k">while</span> <span class="p">(</span><span class="nb">TRUE</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="c1">//do some jobs</span>
</span><span class='line'>      <span class="c1">//break in some condition</span>
</span><span class='line'>      <span class="n">usleep</span><span class="p">(</span><span class="mi">10000</span><span class="p">);</span>
</span><span class='line'>      <span class="p">[</span><span class="n">pool</span> <span class="n">drain</span><span class="p">];</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="p">[</span><span class="n">pool</span> <span class="n">release</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>现在要求，做某些设计，使得当这个线程运行的同时，还可以从其它线程里往它里面随意<em>增加</em>或<em>去掉</em>不同的计算任务。 这，就是NSRunloop的最原始的开发初衷。让一个线程的计算任务更加灵活。 这个功能在c, c++里也许可以做到但是非常难，最主要的是因为语言能力的限制，以前的程序员很少这么去思考。</p>

<p>好，现在我们对上面代码做一个非常简单的进化：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">NSMutableArray</span> <span class="o">*</span><span class="n">targetQueue</span><span class="p">;</span>
</span><span class='line'><span class="n">NSMutableArray</span> <span class="o">*</span><span class="n">actionQueue</span><span class="p">;</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">myThread:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">sender</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">NSAutoreleasePool</span> <span class="o">*</span><span class="n">pool</span><span class="o">=</span><span class="p">[[</span><span class="n">NSAutoreleasePool</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'>    <span class="k">while</span> <span class="p">(</span><span class="nb">TRUE</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">//do some jobs</span>
</span><span class='line'>        <span class="c1">//break in some condition</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">n</span><span class="o">=</span><span class="p">[</span><span class="n">targetQueue</span> <span class="n">count</span><span class="p">];</span>
</span><span class='line'>        <span class="n">assert</span><span class="p">(</span><span class="n">n</span><span class="o">==</span><span class="p">[</span><span class="n">actionQueue</span> <span class="n">count</span><span class="p">]);</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">){</span>
</span><span class='line'>            <span class="kt">id</span> <span class="n">target</span><span class="o">=</span><span class="p">[</span><span class="n">targetQueue</span> <span class="nl">objectAtIndex:</span><span class="n">i</span><span class="p">];</span>
</span><span class='line'>            <span class="kt">SEL</span> <span class="n">action</span><span class="o">=</span><span class="n">NSSelectorFromString</span><span class="p">([</span><span class="n">actionQueue</span> <span class="nl">objectAtIndex:</span><span class="n">i</span><span class="p">]);</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">([</span><span class="n">target</span> <span class="nl">respondsToSelector:</span><span class="n">action</span><span class="p">])</span> <span class="p">{</span>
</span><span class='line'>                <span class="p">[</span><span class="n">target</span> <span class="nl">performSelector:</span><span class="n">action</span> <span class="nl">withObject:</span><span class="nb">nil</span><span class="p">];</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">usleep</span><span class="p">(</span><span class="mi">10000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="p">[</span><span class="n">pool</span> <span class="n">drain</span><span class="p">];</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="p">[</span><span class="n">pool</span> <span class="n">release</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>注意，这里没有做线程安全处理，记住Mutable container is not thread safe.
这个简单的扩展，让我们看到了如何利用runtime能力让线程灵活起来。当我们从另外线程向targetQueue和actionQueue同时加入对象和方法时候，这个线程函数就有了执行一个额外代码的能力。</p>

<p>有人会问,哪里有runloop? 那个是nsrunloop? 看不出来啊。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">while</span> <span class="p">(</span><span class="nb">TRUE</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="c1">//break in some condition</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>这个结构就叫线程的runloop, 它和NSRunloop这个类虽然名字很像，但完全不是一个东西。以前在使用静态语言开始时候，程序员没有什么迷惑，因为没有NSRunloop这个东西。 我接着来说，这个NSRunloop是如何来得。</p>

<p>第二段扩展代码里面确实没有NSRunloop这个玩意儿，我们接着做第3次改进。 这次我们的目的是把其中动态部分抽象出来。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">@interface</span> <span class="nc">MyNSTimer</span> : <span class="nc">NSObject</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">id</span> <span class="n">target</span><span class="p">;</span>
</span><span class='line'>  <span class="kt">SEL</span> <span class="n">action</span><span class="p">;</span>
</span><span class='line'>  <span class="kt">float</span> <span class="n">interval</span><span class="p">;</span>
</span><span class='line'>  <span class="n">CFAbsoluteTime</span> <span class="n">lasttime</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">invoke</span><span class="p">;</span>
</span><span class='line'><span class="k">@end</span>
</span><span class='line'>
</span><span class='line'><span class="k">@implementation</span> <span class="nc">MyNSTimer</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">invoke</span><span class="p">;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">([</span><span class="n">target</span> <span class="nl">respondsToSelector:</span><span class="n">action</span><span class="p">])</span> <span class="p">{</span>
</span><span class='line'>        <span class="p">[</span><span class="n">target</span> <span class="nl">performSelector:</span><span class="n">action</span> <span class="nl">withObject:</span><span class="nb">nil</span><span class="p">];</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">@interface</span> <span class="nc">MyNSRunloop</span> : <span class="nc">NSObject</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">NSMutableArray</span> <span class="o">*</span><span class="n">timerQueue</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">addTimer:</span><span class="p">(</span><span class="n">MyNSTimer</span><span class="o">*</span><span class="p">)</span><span class="n">t</span><span class="p">;</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">executeOnce</span><span class="p">;</span>
</span><span class='line'><span class="k">@end</span>
</span><span class='line'>
</span><span class='line'><span class="k">@implementation</span> <span class="nc">MyNSRunloop</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">addTimer:</span><span class="p">(</span><span class="n">MyNSTimer</span><span class="o">*</span><span class="p">)</span><span class="nv">t</span><span class="p">;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">@synchronized</span><span class="p">(</span><span class="n">timerQueue</span><span class="p">){</span>
</span><span class='line'>      <span class="p">[</span><span class="n">timerQueue</span> <span class="nl">addObject:</span><span class="n">t</span><span class="p">];</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">executeOnce</span><span class="p">;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">CFAbsoluteTime</span> <span class="n">currentTime</span><span class="o">=</span><span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="k">@synchronized</span><span class="p">(</span><span class="n">timerQueue</span><span class="p">){</span>
</span><span class='line'>      <span class="k">for</span><span class="p">(</span><span class="n">MyNSTimer</span> <span class="o">*</span><span class="n">t</span> <span class="k">in</span> <span class="n">timerQueue</span><span class="p">){</span>
</span><span class='line'>          <span class="k">if</span><span class="p">(</span><span class="n">currentTime</span><span class="o">-</span><span class="n">t</span><span class="p">.</span><span class="n">lasttime</span><span class="o">&gt;</span><span class="n">t</span><span class="p">.</span><span class="n">interval</span><span class="p">){</span>
</span><span class='line'>              <span class="n">t</span><span class="p">.</span><span class="n">lasttime</span><span class="o">=</span><span class="n">currentTime</span><span class="p">;</span>
</span><span class='line'>                  <span class="p">[</span><span class="n">t</span> <span class="n">invoke</span><span class="p">];</span>
</span><span class='line'>          <span class="p">}</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">@interface</span> <span class="nc">MyNSThread</span> : <span class="nc">NSObject</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">MyNSRunloop</span> <span class="o">*</span><span class="n">runloop</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">main:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="n">sender</span><span class="p">;</span>
</span><span class='line'><span class="k">@end</span>
</span><span class='line'>
</span><span class='line'><span class="k">@implementation</span> <span class="nc">MyNSThread</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">main:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">sender</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">NSAutoreleasePool</span> <span class="o">*</span><span class="n">pool</span><span class="o">=</span><span class="p">[[</span><span class="n">NSAutoreleasePool</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'>    <span class="k">while</span> <span class="p">(</span><span class="nb">TRUE</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="c1">//do some jobs</span>
</span><span class='line'>        <span class="c1">//break in some condition</span>
</span><span class='line'>        <span class="p">[</span><span class="n">runloop</span> <span class="n">executeOnce</span><span class="p">];</span>
</span><span class='line'>        <span class="n">usleep</span><span class="p">(</span><span class="mi">10000</span><span class="p">);</span>
</span><span class='line'>        <span class="p">[</span><span class="n">pool</span> <span class="n">drain</span><span class="p">];</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="p">[</span><span class="n">pool</span> <span class="n">release</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>


<p>走到这里，我们就算是基本把Runloop结构抽象出来了。例如我有一个MyNSThread实例，myThread1。我可以给这个实例的线程添加需要的任务，而myThread1内部的MyNSRunloop对象会管理好这些任务。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">MyNSTimer</span> <span class="o">*</span><span class="n">timer1</span><span class="o">=</span><span class="p">[</span><span class="n">MyNSTimer</span> <span class="nl">scheduledTimerWithTimeInterval:</span><span class="mi">1</span>
</span><span class='line'>                                                   <span class="nl">target:</span><span class="n">obj1</span>
</span><span class='line'>                                                 <span class="nl">selector:</span><span class="k">@selector</span><span class="p">(</span><span class="nl">download1:</span><span class="p">)];</span>
</span><span class='line'><span class="p">[</span><span class="n">myThread1</span><span class="p">.</span><span class="n">runloop</span> <span class="nl">addTimer:</span><span class="n">timer1</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'><span class="n">MyNSTimer</span> <span class="o">*</span><span class="n">timer2</span><span class="o">=</span><span class="p">[</span><span class="n">MyNSTimer</span> <span class="nl">scheduledTimerWithTimeInterval:</span><span class="mi">2</span>
</span><span class='line'>                                                   <span class="nl">target:</span><span class="n">obj2</span>
</span><span class='line'>                                                 <span class="nl">selector:</span><span class="k">@selector</span><span class="p">(</span><span class="nl">download2:</span><span class="p">)];</span>
</span><span class='line'><span class="p">[</span><span class="n">myThread1</span><span class="p">.</span><span class="n">runloop</span> <span class="nl">addTimer:</span><span class="n">timer2</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>当你看懂了上面的代码也许会感叹，‘原来是这么回事啊！为什么把这么简单的功能搞这么复杂呢？’ 其实就是这么回事，把Runloop抽象出来可以使得线程任务管理更加loose coupling，给设计模式提供更大的空间。这样第三方开发者不需要过深入的涉及线程内部代码而轻松管理线程任务。另外请注意，这里MyNSRunloop, MyNSTimer等类是我写得一个模拟情况，真实的NSRunloop实现肯定不是这么简单。这里为了说明一个思想。这种思想贯穿整个cocoa framework，从界面更新到event管理。</p>

<p><a id="5"></a></p>

<h2>5. delegate, protocol</h2>

<p>这个会列出来因为，我感觉问它的数量仅此于内存管理部分，它们用得很频繁，并且这些是设计模式的重要组成部分。</p>

<p><em>待写&#8230;</em></p>

<p><a id="6"></a></p>

<h2>6. event respon­der</h2>

<p><img class="right" src="http://lianxu.me/images/post/responder.jpg" title="'Interface Builder First Responder'" >
使用过Xcode的开发者都知道Interface Builder这个开发组件，在Xcode4版本以后该组件已经和xcode整合到一起。它是苹果软件开发中非常重要的部分。ib为开发者减轻了很大一部分界面设计工作。但是其中有一个东西让新接触ib的开发者一头雾水，那就是First Responder, 它是什么东西，为何它会有那么多Actions。这节我会详细介绍如何理解Responder和Cocoa下的事件响应链。</p>

<p>First Responder在IB属性为Placeholders，这意味着它属于一个虚拟实例。就好比TextField里面的string placeholder一样，只是临时显示一下。真正的first responder会被其它对象代替。实际上，任何派生自NSResponder类的对象都可以替代First Responder。而First Responder里面的所有Actions就是NSResponder提供的接口函数，当然你也可以定义自己的响应函数。</p>

<p>MacOS在系统内部会维护一个称为“The Responder Chain”的链表。该列表内容为responder对象实例，它们会对各种系统事件做出响应。最上面的哪个对象就叫做first responder，它是最先接收到系统事件的对象。如果该对象不处理该事件，系统会将这个事件向下传递，直到找到响应事件的对象，我们可以理解为该事件被该这个对象截取了。</p>

<p>The Responder Chain基本结构如下图所示：</p>

<p><img class="center" src="http://lianxu.me/images/post/responderchain.jpg" title="'The Responder Chain'" ></p>

<p>在理解了上面的概念之后，我希望使用一个例子让大家对responder有更加具体的认识。大家都知道NSTextField这个控件，它是最常见的控件之一。它最基本功能是显示一个字符串，如果启用可选，那么用户可以选中文本，拷贝文本，如果开启编辑选项，还可以运行用户编辑文本，等等基本操作。</p>

<p>下面展示给大家的例子是创建一个我们自己创建的简单textfield叫LXTextField。它不属于NSTextField而是派生自NSView，具有功能显示字符串，全选字符串，响应用户cmd+c的拷贝操作，三个基本功能。注意NSView派生自NSResponder。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="cp">//</span>
</span><span class='line'><span class="cp">//  LXTextField.h</span>
</span><span class='line'><span class="cp">//  lxtextfield</span>
</span><span class='line'><span class="cp">//</span>
</span><span class='line'><span class="cp">//  Created by xu lian on 12-03-09.</span>
</span><span class='line'><span class="cp">//  Copyright (c) 2012 Beyondcow. All rights reserved.</span>
</span><span class='line'><span class="cp">//</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#import &lt;AppKit/AppKit.h&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="k">@interface</span> <span class="nc">LXTextField</span> : <span class="nc">NSView</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">NSString</span> <span class="o">*</span><span class="n">stringValue</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">BOOL</span> <span class="n">selectAll</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">@property</span><span class="p">(</span><span class="n">retain</span><span class="p">,</span><span class="n">nonatomic</span><span class="p">)</span> <span class="n">NSString</span> <span class="o">*</span><span class="n">stringValue</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="cp">//</span>
</span><span class='line'><span class="cp">//  LXTextField.m</span>
</span><span class='line'><span class="cp">//  lxtextfield</span>
</span><span class='line'><span class="cp">//</span>
</span><span class='line'><span class="cp">//  Created by xu lian on 12-03-09.</span>
</span><span class='line'><span class="cp">//  Copyright (c) 2012 Beyondcow. All rights reserved.</span>
</span><span class='line'><span class="cp">//</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#import &quot;LXTextField.h&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="k">@implementation</span> <span class="nc">LXTextField</span>
</span><span class='line'><span class="k">@synthesize</span> <span class="n">stringValue</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">awakeFromNib</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">selectAll</span> <span class="o">=</span> <span class="n">NO</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nf">initWithFrame:</span><span class="p">(</span><span class="n">NSRect</span><span class="p">)</span><span class="nv">frameRect</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span> <span class="n">self</span> <span class="o">=</span> <span class="p">[</span><span class="n">super</span> <span class="nl">initWithFrame:</span><span class="n">frameRect</span><span class="p">]</span> <span class="p">){</span>
</span><span class='line'>        <span class="n">selectAll</span> <span class="o">=</span> <span class="n">NO</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">self</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">BOOL</span><span class="p">)</span><span class="nf">acceptsFirstResponder</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">YES</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">BOOL</span><span class="p">)</span><span class="nf">becomeFirstResponder</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">YES</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">BOOL</span><span class="p">)</span><span class="nf">resignFirstResponder</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">selectAll</span><span class="o">=</span><span class="n">NO</span><span class="p">;</span>
</span><span class='line'>    <span class="p">[</span><span class="n">self</span> <span class="nl">setNeedsDisplay:</span><span class="n">YES</span><span class="p">];</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">YES</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">setStringValue:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">string</span><span class="p">{</span>
</span><span class='line'>    <span class="n">stringValue</span> <span class="o">=</span> <span class="n">string</span><span class="p">;</span>
</span><span class='line'>    <span class="p">[</span><span class="n">self</span> <span class="nl">setNeedsDisplay:</span><span class="n">YES</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">drawRect:</span><span class="p">(</span><span class="n">NSRect</span><span class="p">)</span><span class="nv">dirtyRect</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">selectAll</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">NSRect</span> <span class="n">r</span> <span class="o">=</span> <span class="n">NSZeroRect</span><span class="p">;</span>
</span><span class='line'>        <span class="n">r</span><span class="p">.</span><span class="n">size</span> <span class="o">=</span> <span class="p">[</span><span class="n">stringValue</span> <span class="nl">sizeWithAttributes:</span><span class="nb">nil</span><span class="p">];</span>
</span><span class='line'>        <span class="p">[[</span><span class="n">NSColor</span> <span class="n">selectedControlColor</span><span class="p">]</span> <span class="n">set</span><span class="p">];</span>
</span><span class='line'>        <span class="n">NSRectFill</span><span class="p">(</span><span class="n">r</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="p">[</span><span class="n">stringValue</span> <span class="nl">drawAtPoint:</span><span class="n">NSZeroPoint</span> <span class="nl">withAttributes:</span><span class="nb">nil</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">IBAction</span><span class="p">)</span><span class="nf">selectAll:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">sender</span><span class="p">;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">selectAll</span><span class="o">=</span><span class="n">YES</span><span class="p">;</span>
</span><span class='line'>    <span class="p">[</span><span class="n">self</span> <span class="nl">setNeedsDisplay:</span><span class="n">YES</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">IBAction</span><span class="p">)</span><span class="nl">copy:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="n">sender</span><span class="p">;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">NSPasteboard</span> <span class="o">*</span><span class="n">pasteBoard</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSPasteboard</span> <span class="n">generalPasteboard</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">pasteBoard</span> <span class="nl">declareTypes:</span><span class="p">[</span><span class="n">NSArray</span> <span class="nl">arrayWithObjects:</span><span class="n">NSStringPboardType</span><span class="p">,</span> <span class="nb">nil</span><span class="p">]</span> <span class="nl">owner:</span><span class="nb">nil</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">pasteBoard</span> <span class="nl">setString:</span><span class="n">stringValue</span> <span class="nl">forType:</span><span class="n">NSStringPboardType</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">mouseDown:</span><span class="p">(</span><span class="n">NSEvent</span> <span class="o">*</span><span class="p">)</span><span class="n">theEvent</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">([</span><span class="n">theEvent</span> <span class="n">clickCount</span><span class="p">]</span><span class="o">&gt;=</span><span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">selectAll</span><span class="o">=</span><span class="n">YES</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="p">[</span><span class="n">self</span> <span class="nl">setNeedsDisplay:</span><span class="n">YES</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">keyDown:</span><span class="p">(</span><span class="n">NSEvent</span> <span class="o">*</span><span class="p">)</span><span class="n">theEvent</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>


<p>运行实例，可以看到随着LXTextField收到系统发送的becomeFirstResponder消息，LXTextField变成responder chain中的frist responder, 这时候可以理解为IB里的哪个First Responder虚拟实例被该LXTextField取代。这时候mainMenu上哪些菜单项,例如：全选(cmd+a), 拷贝(cmd+a)等事件都会最先发给当前这个LXTextField。一旦你的LXTextField实现了NSResponder的哪些默认函数，那么该对象就会截取系统事件。当然这些事件具体如何实现还是需要你自己写代码实现。例如这里的 - (IBAction)copy:(id)sender; 显然我手动实现了textfield的copy能力。</p>

<p>注意上述代码中我实现了一个空函数- (void)keyDown:(NSEvent *)theEvent 这意味着我们希望LXTextField截取键盘事件而不再传递给responder chain后续对象。当然，如果我们希望LXTextField响应特定键盘事件，而其他事件继续传给其他响应对象，我们可以编写如下代码。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">keyDown:</span><span class="p">(</span><span class="n">NSEvent</span> <span class="o">*</span><span class="p">)</span><span class="nv">theEvent</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">condition</span><span class="p">){</span>
</span><span class='line'>      <span class="k">do</span> <span class="n">something</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span><span class="k">else</span><span class="p">{</span>
</span><span class='line'>      <span class="p">[</span><span class="n">super</span> <span class="nl">keyDown:</span><span class="n">theEvent</span><span class="p">];</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><em>待写&#8230;</em></p>

<p><a id="7"></a></p>

<h2>7. mem­ory management</h2>

<p>内存管理问题，也许是问得最多的问题了吧。</p>

<ol>
<li>内存管理规则
Cocoa下程序开发内存管理使用ref­er­ence counting(RC)机制。从10.7以后apple开始推荐auto­matic ref­er­ence counting(ARC)机制。大家是否知道从旧时代的RC到ARC机制到底意味着什么呢？为什么ARC从开发速度，到执行速度和稳定性都要优于rc？</li>
</ol>


<p>开发速度不言而喻，你少写很多release代码，甚至很少去操心这部分。</p>

<p>执行速度呢？这个还要从runtime说起，还记得我在第２点说得一句话么：“Runtime is everything between your each function call.”</p>

<p>RC有一个古老的内存管理哲学：<strong>谁分配谁释放。</strong> 通过counting来确定一个资源有几个使用者。道理很简单，但是往往简单的东西人却会犯错。从来没有一个程序员可以充满信心的说，我写得代码从来没有过内存泄露。这样来看，我们就更需要让程序可以自己处理这个管理机制，这就需要把这个机制放到runtime里。</p>

<p>所以RC->ARC就是把内存管理部分从普通开发者的函数中移到了函数外的runtime中。因为runtime的开发原型简单，逻辑层次更高，所以做这个开发和管理出错的概率更小。实际上编译器开发人员对这部分经过无数次测试，所以可以说用arc几乎不会出错。另外由于编译的额外优化，使得这个部分比程序员自己写得代码要快速很多。而且对于一些通用的开发模式，例如autorelease对象，arc有更优秀的算法保证autoreleasepool里的对象更少。</p>

<ol>
<li>RC规则
首先说一下rc是什么，r-Reference参照，引用 c-counting计数, rc就是引用计数。俗话说就是记录使用者的数量。　例如现在我有一个房间空着，大家可以进去随意使用，但是你进门前，需要给门口的计数牌子+1, 出门时候-1。　这时候这个门口的牌子就是该房间里的人数。一但这个牌子变为０我就可以把房间关闭。</li>
</ol>


<p>这个规则可以让NSObject决定是不是要释放内存。当一个对象alloc时候，系统分配其一块内存并且object自动计数retainCount=1 这时候每当[object retain]一次retainCount+1（这里虽然简写也是rc不过是巧合或者当时开发人员故意选的retain这个词吧）每次[object release]时候retainCount-1　当retainCount==0时候object就真正把这快内存还给系统。</p>

<ol>
<li>常用container的Reference Counting特性
这个规则很简单把。但是这块确实让新手最头疼的地方。问题出在，新手总想去验证rc规则，又总是发现和自己的期望不符合。 　
无数次看到有人写下如下句子</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;%d&quot;</span><span class="p">,[</span><span class="n">object</span> <span class="n">retainCount</span><span class="p">]);</span>
</span><span class='line'>
</span><span class='line'><span class="k">while</span><span class="p">([</span><span class="n">object</span> <span class="n">retainCount</span><span class="p">]</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">){</span>
</span><span class='line'>      <span class="p">[</span><span class="n">object</span> <span class="n">release</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>当然了，我也做过类似的动作，那种希望一切尽在掌握中的心态。但是你会看到其他人告诉这么做完全没有意义，RC规则并不是这么用的。</p>

<p>首先，这个数字也许并不是你心目中的哪个。因为很难跟踪到底哪些地方引用的该资源。你建立的资源不光只有你的代码才会用到，你调用的各种Framework，Framework调用的Framework，都有可能改变这个资源的retainCount。</p>

<p>其次，这里每个数字意味着有其它对象引用该资源，这样的暴力释放很容易导致程序崩溃。就好比，其它人也许可以翻牌子把门口哪个牌子上的数字改变，但是这会出现问题。还有很多人在里面，把牌子变成0房间锁了结果谁也出不来。又或者，减少牌子上的数字，人进的过多房间变得过于拥挤。</p>

<p>所以去验证rc规则，或者单纯的改变retainCount并不是明智之举。你能做的就是理解规则，使用规则，读文档了解container的引用特性。或者干脆移到arc上面，让runtime环境处理这些问题。</p>

<blockquote><p>我有一个NSMutableArray里面保存了1000个NSString对象，我在release的时候需要循环释放1000个string么？还是只需要release NSMutableArray。</p></blockquote>

<p>就像上面提到的，如果你了解container的引用特性，这个问题自然就解决了。“NSMutableArray在添加、插入objects时会做retain操作。” 通过这一句话就分析出，用户不否需要帮助NSMutableArray释放1000个string。回忆上面提到的管理哲学，“谁分配谁释放” 编写NSMutableArray的程序员非常熟悉这个规则，NSMutableArray内部retain了，NSMutableArray自然要负责release。但是NSMutableArray才不会管你在外面什么地方引用了这1000个string，它只管理好内部的rc就够了。所以如果你在NSMutableArray外面对1000个string retain了，你自然需要release。相应的，你作为创建这个NSMutableArray的程序员，你只管release这个NSMutableArray就可以了。</p>

<p>最后说一下不用arc的情况。目前情况来看，有不少第三方的库并未支持arc，所以如果你的旧项目使用了这些库，请检查是否作者发布了新版本，或者你需要自己修正支持arc。</p>

<p><a id="8"></a></p>

<h2>8. class heritage and category</h2>

<p>在这节里说明2个比较重要的问题，第一是subclass和category的区别。第二是新手最容易忽略的学习步骤。</p>

<p>Objective-C的Object-oriented programming特性提供subclass和category这2个比较非常重要的部分。subclass应该反复被各种编程书籍介绍过。它是oop继承特性的关键语法，它给类添加了延续并且多样化自己的方法。可以说没有继承就没有oop这玩意。而category相对于subclass就不那么出名了。其实category思想出世于smalltalk，所以它不能算是一个新生事物。</p>

<p>先说一下这2个特性最主要的区别。简单可以这么理解，subclass体现了类的上下级关系，而category是类间的平级关系。</p>

<p><img class="center" src="http://lianxu.me/images/post/subclassandcategory.jpg" title="Subclass and Category" ></p>

<p>如上图所示，左侧是subclass，可以看到class, subclass1, subclass2是递进关系。同时下面的子类完全继承父类的方法，并且可以覆盖父类的方法。subclass2拥有function1,function2,function3三个函数方法。function1的执行代码来自subclass1, function2的执行代码来自于subclass2。</p>

<p>右侧是category。可以看到，无论如何扩展类的category，最终就只有一个类class。category可以说是类的不同方法的小集合，它把一个类的方法划分成不同的区块。请注意观察，每个category块内的方法名称都没有重复的。这正是category的重要要求。</p>

<p>经过上面简单解释了解了这2点的基本区别，现在深入说一下category。</p>

<p>在Objective-c语言设计之初一个主要的哲学观点就是尽量让一个程序员维护庞大的代码集。(对于庞大的项目‘原则’和‘协议’是非常重要的东西。甚至编写良好的文件名都是非常重要的开发技巧)根据结构化程序设计的经验出发，把一个大块代码划分成一些小块的代码更便于程序员管理。于是objc借用了smalltalk的categories概念。允许程序员把一系列功能相近的方法组织到一个单独的文件内，使得这些代码更容易识别。</p>

<p>更进一步的，和c,c++这种静态语言相比。objc把class categories功能集成到了run-time里面。因此，objc的categories允许程序员为已经存在的类添加新的方法而不需要重新编译旧的类。一旦一个category加入，它可以访问该类所有方法和实例变量，包括私有变量。</p>

<p>category不仅可以为原有class添加方法，而且如果category方法与类内某个方法具有同样的method signature，那么category里的方法将会替换类的原有方法。这是category的替换特性。利用这个特性，category还可以用来修复一些bugs。例如已经发布的Framework出现漏洞，如果不便于重新发布新版本，可以使用category替换特性修复漏洞。另外，由于category有run-time级别的集成度，所以使得cocoa程序安全性有所下降。许多黑客就是利用这个特性（和posting技术<a href="#ref2">2</a>）劫持函数、破解软件，或者为软件增加新功能。一个很典型的例子就是，我发布的<a href="https://www.beyondcow.com/qqfacemanager/">QQ表情管理器</a>。</p>

<p>值得注意的一点是，由于一个类的categories之间是平级关系。所以如果不同categories拥有相同的方法，这个调用结果是未知的。所以：</p>

<blockquote><p>Category methods should not override existing methods (class or instance).
Two different categories implementing the same method results in undefined behavior</p></blockquote>

<p>Objc中Categories有其局限的部分，就是你不能为原有的class添加变量，只能添加方法。当然方法里可以添加局部变量。在这个局限基础上就有其它语言做了进一步改进，例如TOM语言就为Categories增加了添加类变量的能力。</p>

<p>总上所属，如果你开发时候遇到无论如何都需要为类添加变量的情况，最好的选择就是subclass。相反如果你只希望增加一些函数簇。Categories是最好的选择。</p>

<p>Categories关注的重心是代码设计，把不同功能的方法分离开。在Objc里因为Categories是runtimes级别的特性，所以这种分离不仅体现在源码结构上，同时体现在运行时过程中。这意味着一个category里的方法在程序运行中如果没有被调用，那么它就不会被加载到内存中。所以合理的使用categories会减少你的程序内存消耗。</p>

<p>所以我个人给大家的建议是，每个Cocoa程序员都应该收集整理自己的一套NS类函数的Categories扩展库。这对你今后程序开发效率和掌控情况都有很大提高。</p>

<p><em>待写&#8230;</em></p>

<p><a id="9"></a></p>

<h2>9. design pattern</h2>

<p><em>待写&#8230;</em></p>

<p><a id="10"></a></p>

<h2>10. thinking before asking</h2>

<p>其实剩下这个有好几点要说，但综合一下把。思路有些相似, 例如刚看到这个问题：</p>

<blockquote><p>现在有A ＊a；A＊b<br/>
[NSMutableArray addObject : a];<br/>
[NSMutableArray replaceObjectAtIndex:0 withObject:b]<br/>
执行完这两个之后，拿可变数组里面的0的位置 就是b元素了，那这个时候a到哪里去了？？是否还占用着内存，如果占用内存的话，又如何去释放？？</p></blockquote>

<p>It&#8217;s kind of silly. 我并不是想讽刺问问题的朋友。其实如果你真的了解了上面这些知识点，就不会再问这种问题的。 为什么不多思考一层呢，在问这个问题之前想想，到底为什么会问出这个问题？ ”如果让你给NSMutableArray实现一个replaceObjectAtIndex函数你会怎么写？“ 难道连个[obj release]都考虑不到么？然后根据内存管理规则，它到底释放了没，不言自明了吧。</p>

<p>其实这种问题论坛里很多的。不妨在迷惑的时候，先问问自己为什么会迷惑。</p>

<p><em><a name="ref1">1</a>:这里其实很有意思，为何我用“更高层次思考”，而不是“更底层次”。作为一个编译器和语言开发人员，面对的问题确实更底层没错，但是他们思考的维度更高，更抽象，这样子。一个不算恰当的比方就好像一个三维世界的人处理二维世界的一条线的问题。</em></p>

<p><em><a name="ref2">2</a>:Posting技术在10.5以后deprecated，并且64bit run-time也不再支持</em></p>

<h4>最近事情比较忙。 我只能忙里偷闲过来接着写这篇教程。大家莫怪。</h4>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[基于非负矩阵分解的文本聚类]]></title>
    <link href="http://lianxu.me/blog/2008/05/30/document-clustering-based-on-non-negative-matrix-factorization/"/>
    <updated>2008-05-30T10:23:00-07:00</updated>
    <id>http://lianxu.me/blog/2008/05/30/document-clustering-based-on-non-negative-matrix-factorization</id>
    <content type="html"><![CDATA[<p>文本分类、聚类算法中，最常见的障碍就是高维矩阵。对于具有一定规模的文本聚类很轻易会遇到维度成千上万的矩阵，如果按照常规计算方法，耗时将不可估量。而非负矩阵分解则是非常好的降维理论，利用非负矩阵分解我们可以将高维矩阵分解为可接受的小维矩阵，并保持其原矩阵的特征。这篇文章将介绍如何利用非负矩阵分解做文本聚类。非负矩阵分解英文全称是 Non-negative matrix factorization(NMF)。请您记住本文只做文本聚类，并不介绍如何中文分词。</p>

<!--more-->


<p>下面的引用是Wikipedia对NMF的历史介绍：</p>

<blockquote><p>Early work on non-negative matrix factorizations was performed by a Finnish group of researchers in the middle of the 1990s under the name positive matrix factorization. It became more widely known as non-negative matrix factorization after Lee and Seung investigated the properties of the algorithm and published some simple and useful algorithms for two types of factorizations.  <a href="http://en.wikipedia.org/wiki/Non-negative_matrix_factorization">Read &rarr;</a></p></blockquote>

<p>好了废话我不多说，相信对这篇文章感兴趣的人对NMF也应该有所了解。</p>

<p>我根据实际的情况来写这个工作过程。从我手头有的资料说起：</p>

<ol>
<li>用于训练的样本数据，也就是已经做好分词的中文文本，类别已经标注 file1.txt~file50.txt 每10篇代表一大类（环境、教育、经济、体育、政治）</li>
<li>停用词表（如果您还没有，请在google里搜索）</li>
<li>待测试文本，属于上述5大类的文本，也是已经做好分词处理的</li>
<li>开发环境（可编译c代码即可)</li>
</ol>


<p>整个文本分类可以分为3大部分：</p>

<ol>
<li>文本的处理</li>
<li>利用NMF做矩阵分解</li>
<li>利用NMF得到的降维特征矩阵和相关数据分类待分类文本</li>
</ol>


<p><em>注：请从宏观角度记住着3大部分</em></p>

<h1>第一：建立VSM</h1>

<p>实际上第一步文本的处理无非就是找到VSM (Vector space model) 向量空间模型。利用TF-IDF（term frequency–inverse document frequency）求出每个词的权重。这步的目的就是生成一个所有文章，所有词的一个矩阵。这个矩阵带有这些文本的特点。（tf-idf也就是 词频-逆文频率指数）
公式如下:</p>

<ul>
<li>TF=某词在一文本中出现次数/这篇文本总词数</li>
<li>IDF=log(文本集合总数/这个词出现的文本个数）</li>
<li>TF*IDF就是这个词在特征矩阵的权重。</li>
</ul>


<p>关于这个google数学之美系列中有很生动的介绍请自行研读, 我这里简单介绍，tf就是一个词在文本中出现的频率，idf则可以反映出这个词在整个文本集里的广泛程度。如果一个词出现的越广泛那么它的主题相关性就越低。就像google数学之美系列中介绍的一样“原子能 的 应用”这句话里“原子能”的广泛度应该比“应用”低，这个是个常识，至于“的”，由于它太广泛所以沦落到停用此表里了。</p>

<p>这个生成的矩阵大概是个什么样子呢？我随便写一个样子把。数据我瞎写的看看样子而已。</p>

<pre><code>    文本1   文本2   文本3
词1 0.3     0.3     0.0
词2 0.7     0.1     0.8
词3 0.0     0.6     0.2
</code></pre>

<p>这里面的每个数据都是TF*IDF得到的。好下面我吧第一部分求VSM的代码贴一下：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
<span class='line-number'>102</span>
<span class='line-number'>103</span>
<span class='line-number'>104</span>
<span class='line-number'>105</span>
<span class='line-number'>106</span>
<span class='line-number'>107</span>
<span class='line-number'>108</span>
<span class='line-number'>109</span>
<span class='line-number'>110</span>
<span class='line-number'>111</span>
<span class='line-number'>112</span>
<span class='line-number'>113</span>
<span class='line-number'>114</span>
<span class='line-number'>115</span>
<span class='line-number'>116</span>
<span class='line-number'>117</span>
<span class='line-number'>118</span>
<span class='line-number'>119</span>
<span class='line-number'>120</span>
<span class='line-number'>121</span>
<span class='line-number'>122</span>
<span class='line-number'>123</span>
<span class='line-number'>124</span>
<span class='line-number'>125</span>
<span class='line-number'>126</span>
<span class='line-number'>127</span>
<span class='line-number'>128</span>
<span class='line-number'>129</span>
<span class='line-number'>130</span>
<span class='line-number'>131</span>
<span class='line-number'>132</span>
<span class='line-number'>133</span>
<span class='line-number'>134</span>
<span class='line-number'>135</span>
<span class='line-number'>136</span>
<span class='line-number'>137</span>
<span class='line-number'>138</span>
<span class='line-number'>139</span>
<span class='line-number'>140</span>
<span class='line-number'>141</span>
<span class='line-number'>142</span>
<span class='line-number'>143</span>
<span class='line-number'>144</span>
<span class='line-number'>145</span>
<span class='line-number'>146</span>
<span class='line-number'>147</span>
<span class='line-number'>148</span>
<span class='line-number'>149</span>
<span class='line-number'>150</span>
<span class='line-number'>151</span>
<span class='line-number'>152</span>
<span class='line-number'>153</span>
<span class='line-number'>154</span>
<span class='line-number'>155</span>
<span class='line-number'>156</span>
<span class='line-number'>157</span>
<span class='line-number'>158</span>
<span class='line-number'>159</span>
<span class='line-number'>160</span>
<span class='line-number'>161</span>
<span class='line-number'>162</span>
<span class='line-number'>163</span>
<span class='line-number'>164</span>
<span class='line-number'>165</span>
<span class='line-number'>166</span>
<span class='line-number'>167</span>
<span class='line-number'>168</span>
<span class='line-number'>169</span>
<span class='line-number'>170</span>
<span class='line-number'>171</span>
<span class='line-number'>172</span>
<span class='line-number'>173</span>
<span class='line-number'>174</span>
<span class='line-number'>175</span>
<span class='line-number'>176</span>
<span class='line-number'>177</span>
<span class='line-number'>178</span>
<span class='line-number'>179</span>
<span class='line-number'>180</span>
<span class='line-number'>181</span>
<span class='line-number'>182</span>
<span class='line-number'>183</span>
<span class='line-number'>184</span>
<span class='line-number'>185</span>
<span class='line-number'>186</span>
<span class='line-number'>187</span>
<span class='line-number'>188</span>
<span class='line-number'>189</span>
<span class='line-number'>190</span>
<span class='line-number'>191</span>
<span class='line-number'>192</span>
<span class='line-number'>193</span>
<span class='line-number'>194</span>
<span class='line-number'>195</span>
<span class='line-number'>196</span>
<span class='line-number'>197</span>
<span class='line-number'>198</span>
<span class='line-number'>199</span>
<span class='line-number'>200</span>
<span class='line-number'>201</span>
<span class='line-number'>202</span>
<span class='line-number'>203</span>
<span class='line-number'>204</span>
<span class='line-number'>205</span>
<span class='line-number'>206</span>
<span class='line-number'>207</span>
<span class='line-number'>208</span>
<span class='line-number'>209</span>
<span class='line-number'>210</span>
<span class='line-number'>211</span>
<span class='line-number'>212</span>
<span class='line-number'>213</span>
<span class='line-number'>214</span>
<span class='line-number'>215</span>
<span class='line-number'>216</span>
<span class='line-number'>217</span>
<span class='line-number'>218</span>
<span class='line-number'>219</span>
<span class='line-number'>220</span>
<span class='line-number'>221</span>
<span class='line-number'>222</span>
<span class='line-number'>223</span>
<span class='line-number'>224</span>
<span class='line-number'>225</span>
<span class='line-number'>226</span>
<span class='line-number'>227</span>
<span class='line-number'>228</span>
<span class='line-number'>229</span>
<span class='line-number'>230</span>
<span class='line-number'>231</span>
<span class='line-number'>232</span>
<span class='line-number'>233</span>
<span class='line-number'>234</span>
<span class='line-number'>235</span>
<span class='line-number'>236</span>
<span class='line-number'>237</span>
<span class='line-number'>238</span>
<span class='line-number'>239</span>
<span class='line-number'>240</span>
<span class='line-number'>241</span>
<span class='line-number'>242</span>
<span class='line-number'>243</span>
<span class='line-number'>244</span>
<span class='line-number'>245</span>
<span class='line-number'>246</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="cm">/**************************************************</span>
</span><span class='line'><span class="cm">*   VSM by keefo 2008.05.26</span>
</span><span class='line'><span class="cm">**************************************************/</span>
</span><span class='line'><span class="cp">     </span>
</span><span class='line'><span class="cp">#include &lt;stdio.h&gt;</span>
</span><span class='line'><span class="cp">#include &lt;math.h&gt;</span>
</span><span class='line'><span class="cp">#include &lt;map&gt;</span>
</span><span class='line'><span class="cp">#include &lt;string&gt;</span>
</span><span class='line'><span class="cp">#include &lt;vector&gt;</span>
</span><span class='line'><span class="n">using</span> <span class="n">namespace</span> <span class="n">std</span><span class="p">;</span>
</span><span class='line'><span class="cp">#define FILENUM                50 </span>
</span><span class='line'><span class="cp">#define isDigit(ch) ((ch)&gt;=&#39;0&#39; &amp;&amp; (ch)&lt;=&#39;9&#39;)</span>
</span><span class='line'><span class="cp">#define isAlpha(ch) (((ch)&gt;=&#39;a&#39; &amp;&amp; (ch)&lt;=&#39;z&#39;) || ((ch)&gt;=&#39;A&#39; &amp;&amp; (ch)&lt;=&#39;Z&#39;))</span>
</span><span class='line'><span class="cp">#define isSign(ch) (((ch)&lt;127 &amp;&amp; (ch)&gt;=0)?signindex[ch]:0)</span>
</span><span class='line'><span class="n">map</span><span class="o">&lt;</span><span class="n">string</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="n">dic</span><span class="p">;</span> <span class="c1">//全局词典。文本集里出现过的词全部保存在这里</span>
</span><span class='line'><span class="n">map</span><span class="o">&lt;</span><span class="n">string</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="n">filedic</span><span class="p">[</span><span class="n">FILENUM</span><span class="p">];</span>
</span><span class='line'><span class="n">map</span><span class="o">&lt;</span><span class="n">string</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="n">stopword</span><span class="p">;</span><span class="c1">//停用词表</span>
</span><span class='line'><span class="n">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">diclist</span><span class="p">;</span><span class="c1">//单篇文档词典</span>
</span><span class='line'><span class="kt">int</span> <span class="n">signindex</span><span class="p">[</span><span class="mi">200</span><span class="p">]</span><span class="o">=</span><span class="p">{</span><span class="mi">0</span><span class="p">};</span><span class="c1">//符号hash表用来去除文章里的符号</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="kt">int</span> <span class="nf">loadstopword</span><span class="p">()</span> <span class="c1">//加载停用词到stopword中</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">FILE</span> <span class="o">*</span><span class="n">fp</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">char</span> <span class="n">str</span><span class="p">[</span><span class="mi">32</span><span class="p">];</span>
</span><span class='line'>    <span class="n">stopword</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
</span><span class='line'>    <span class="n">fp</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="s">&quot;stopwords.txt&quot;</span><span class="p">,</span><span class="s">&quot;r&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">fp</span><span class="o">==</span><span class="nb">NULL</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Can&#39;t open stopword file.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Loading stopword...&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">while</span><span class="p">(</span><span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%s&quot;</span><span class="p">,</span><span class="n">str</span><span class="p">)</span><span class="o">!=</span><span class="n">EOF</span><span class="p">)</span>
</span><span class='line'>        <span class="n">stopword</span><span class="p">[</span><span class="n">str</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;OK!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">int</span> <span class="nf">trimfile</span><span class="p">()</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">char</span> <span class="n">ch</span><span class="p">,</span><span class="n">name</span><span class="p">[</span><span class="mi">128</span><span class="p">],</span><span class="n">word</span><span class="p">[</span><span class="mi">128</span><span class="p">];</span>
</span><span class='line'>    <span class="kt">FILE</span> <span class="o">*</span><span class="n">fp1</span><span class="p">,</span><span class="o">*</span><span class="n">fp2</span><span class="p">;</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Create trim file waiting...</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="c1">//去除符号</span>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">FILENUM</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">sprintf</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;file/file%d.txt&quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span><span class="c1">//训练数据保存在file目录下</span>
</span><span class='line'>        <span class="n">fp1</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;r&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span><span class="p">(</span><span class="n">fp1</span><span class="o">==</span><span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>            <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Open file %s error!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">name</span><span class="p">);</span>
</span><span class='line'>            <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">sprintf</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;trim%d.txt&quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fp2</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;w+&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span><span class="p">(</span><span class="n">fp2</span><span class="o">==</span><span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>            <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Create file %s error!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">name</span><span class="p">);</span>
</span><span class='line'>            <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">ch</span><span class="o">=</span><span class="n">fgetc</span><span class="p">(</span><span class="n">fp1</span><span class="p">);</span>
</span><span class='line'>        <span class="k">while</span><span class="p">(</span><span class="n">ch</span><span class="o">!=</span><span class="n">EOF</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">isDigit</span><span class="p">(</span><span class="n">ch</span><span class="p">)</span> <span class="o">||</span> <span class="n">isAlpha</span><span class="p">(</span><span class="n">ch</span><span class="p">)</span> <span class="o">||</span> <span class="n">isSign</span><span class="p">(</span><span class="n">ch</span><span class="p">)))</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="n">fputc</span><span class="p">(</span><span class="n">ch</span><span class="p">,</span><span class="n">fp2</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="n">ch</span><span class="o">=</span><span class="n">fgetc</span><span class="p">(</span><span class="n">fp1</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">fclose</span><span class="p">(</span><span class="n">fp1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fclose</span><span class="p">(</span><span class="n">fp2</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="c1">//去除停用词</span>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">FILENUM</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">sprintf</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;trim%d.txt&quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fp1</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;r+&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span><span class="p">(</span><span class="n">fp1</span><span class="o">==</span><span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>            <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Can&#39;t open file %s!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">name</span><span class="p">);</span>
</span><span class='line'>            <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">sprintf</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;file%d.txt&quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;%d &quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fp2</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;w&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span><span class="p">(</span><span class="n">fp2</span><span class="o">==</span><span class="nb">NULL</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Create file %s error!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">name</span><span class="p">);</span>
</span><span class='line'>            <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">while</span><span class="p">(</span><span class="n">fscanf</span><span class="p">(</span><span class="n">fp1</span><span class="p">,</span><span class="s">&quot;%s&quot;</span><span class="p">,</span><span class="n">word</span><span class="p">)</span><span class="o">!=</span><span class="n">EOF</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">stopword</span><span class="p">[</span><span class="n">word</span><span class="p">])</span>
</span><span class='line'>                <span class="n">fprintf</span><span class="p">(</span><span class="n">fp2</span><span class="p">,</span><span class="s">&quot;%s &quot;</span><span class="p">,</span><span class="n">word</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">fclose</span><span class="p">(</span><span class="n">fp1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fclose</span><span class="p">(</span><span class="n">fp2</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">system</span><span class="p">(</span><span class="s">&quot;del trim*.txt&quot;</span><span class="p">);</span><span class="c1">//删除临时文件</span>
</span><span class='line'>    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">initsign</span><span class="p">()</span><span class="c1">//初始化符号表</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">memset</span><span class="p">(</span><span class="n">signindex</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="k">sizeof</span><span class="p">(</span><span class="n">signindex</span><span class="p">));</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">33</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">34</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">37</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">38</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">40</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">41</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">42</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">43</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">44</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">45</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">46</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">47</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">58</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">59</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">60</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">61</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">62</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">63</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">91</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">93</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">95</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">123</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">125</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">126</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">int</span> <span class="n">allwordnum</span><span class="p">,</span><span class="n">process</span><span class="p">[</span><span class="mi">11</span><span class="p">]</span><span class="o">=</span><span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span><span class='line'><span class="kt">void</span> <span class="nf">processing</span><span class="p">(</span><span class="kt">int</span> <span class="n">k</span><span class="p">)</span><span class="c1">//显示计算进度</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">float</span> <span class="n">s</span><span class="o">=</span><span class="p">(</span><span class="kt">float</span><span class="p">)</span><span class="n">k</span><span class="o">/</span><span class="n">allwordnum</span><span class="o">*</span><span class="mi">100</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">ca</span><span class="o">=</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">s</span><span class="o">/</span><span class="mi">10</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">process</span><span class="p">[</span><span class="n">ca</span><span class="p">])</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span><span class="p">(</span><span class="n">ca</span><span class="o">==</span><span class="mi">10</span><span class="p">)</span>
</span><span class='line'>            <span class="n">printf</span><span class="p">(</span><span class="s">&quot;%d%% OK!&quot;</span><span class="p">,</span><span class="n">ca</span><span class="o">*</span><span class="mi">10</span><span class="p">);</span>
</span><span class='line'>        <span class="k">else</span>
</span><span class='line'>            <span class="n">printf</span><span class="p">(</span><span class="s">&quot;%d%% &quot;</span><span class="p">,</span><span class="n">ca</span><span class="o">*</span><span class="mi">10</span><span class="p">);</span>
</span><span class='line'>        <span class="n">process</span><span class="p">[</span><span class="n">ca</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span><span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">FILE</span> <span class="o">*</span><span class="n">fp</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">char</span> <span class="n">name</span><span class="p">[</span><span class="mi">128</span><span class="p">],</span><span class="n">word</span><span class="p">[</span><span class="mi">128</span><span class="p">];</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">filewordnum</span><span class="p">[</span><span class="n">FILENUM</span><span class="p">];</span>
</span><span class='line'>    <span class="n">initsign</span><span class="p">();</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">loadstopword</span><span class="p">())</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">trimfile</span><span class="p">())</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="c1">//计算tf-idf建立向量空间模型</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Create VSM waiting ...</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">diclist</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
</span><span class='line'>    <span class="n">dic</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">FILENUM</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="c1">//按顺序打开处理好的文本，统计词</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">filedic</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">clear</span><span class="p">();</span>
</span><span class='line'>        <span class="n">sprintf</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;file%d.txt&quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;%d &quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fp</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;r&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span><span class="p">(</span><span class="n">fp</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>            <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Processing file %d error!&quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>            <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">filewordnum</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'>        <span class="k">while</span><span class="p">(</span><span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%s&quot;</span><span class="p">,</span><span class="n">word</span><span class="p">)</span> <span class="o">!=</span> <span class="n">EOF</span><span class="p">)</span> <span class="c1">//循环查找该文件内所有单词</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span><span class="p">(</span><span class="n">filedic</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">word</span><span class="p">])</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="c1">//如果在filedic[i]里发现这个单词,出现个数增加，总字典内个数增加</span>
</span><span class='line'>                <span class="n">filedic</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">word</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>                <span class="n">dic</span><span class="p">[</span><span class="n">word</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="k">else</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="n">filedic</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">word</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span><span class="c1">//没出现过的新单词加入filedic[i]</span>
</span><span class='line'>                <span class="k">if</span><span class="p">(</span><span class="n">dic</span><span class="p">[</span><span class="n">word</span><span class="p">]</span><span class="o">==</span><span class="mi">0</span><span class="p">)</span>
</span><span class='line'>                <span class="p">{</span>
</span><span class='line'>                    <span class="c1">//如果也不在dic里，同样加入dic和diclist内。</span>
</span><span class='line'>                    <span class="n">diclist</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">word</span><span class="p">);</span>
</span><span class='line'>                    <span class="n">dic</span><span class="p">[</span><span class="n">word</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>                <span class="p">}</span>
</span><span class='line'>                <span class="k">else</span>
</span><span class='line'>                <span class="p">{</span>
</span><span class='line'>                    <span class="c1">//在总字典里出现过，出现个数增加</span>
</span><span class='line'>                    <span class="n">dic</span><span class="p">[</span><span class="n">word</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>                <span class="p">}</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="n">filewordnum</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">system</span><span class="p">(</span><span class="s">&quot;del file*.txt&quot;</span><span class="p">);</span><span class="c1">//删除临时文件</span>
</span><span class='line'>    <span class="n">fp</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="s">&quot;T_v.txt&quot;</span><span class="p">,</span><span class="s">&quot;w&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">fp</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Create v file error.&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">allwordnum</span><span class="o">=</span><span class="n">diclist</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">计算&amp;打印VSM T_v.txt</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;一共有 %d 个词需要计算 waiting ... </span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">allwordnum</span><span class="p">);</span>
</span><span class='line'>    <span class="n">fprintf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%d %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">FILENUM</span><span class="p">,</span><span class="n">allwordnum</span><span class="p">);</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">knum</span><span class="p">;</span>
</span><span class='line'>    <span class="n">string</span> <span class="n">key</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">double</span> <span class="n">tf</span><span class="p">,</span><span class="n">idf</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">FILE</span> <span class="o">*</span><span class="n">fpword</span><span class="p">;</span>
</span><span class='line'>    <span class="n">fpword</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="s">&quot;T_word.txt&quot;</span><span class="p">,</span><span class="s">&quot;w&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">fprintf</span><span class="p">(</span><span class="n">fpword</span><span class="p">,</span><span class="s">&quot;%d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">allwordnum</span><span class="p">);</span>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">allwordnum</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">key</span><span class="o">=</span><span class="n">diclist</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span><span class='line'>        <span class="n">fprintf</span><span class="p">(</span><span class="n">fpword</span><span class="p">,</span><span class="s">&quot;%s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">key</span><span class="p">.</span><span class="n">c_str</span><span class="p">());</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">knum</span><span class="o">=</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">FILENUM</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>            <span class="k">if</span><span class="p">(</span><span class="n">filedic</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">key</span><span class="p">])</span>
</span><span class='line'>                <span class="n">knum</span><span class="o">++</span><span class="p">;</span><span class="c1">//knum出现该词的文档数</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">idf</span><span class="o">=</span><span class="n">log</span><span class="p">((</span><span class="kt">double</span><span class="p">)</span><span class="n">FILENUM</span><span class="o">/</span><span class="n">knum</span><span class="p">);</span><span class="c1">//逆文频率指数,这里注意要排除全局都出现的关键词。log(1)=0 会导致后期迭代失败</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">FILENUM</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">tf</span><span class="o">=</span><span class="p">(</span><span class="kt">double</span><span class="p">)</span><span class="n">filedic</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">key</span><span class="p">]</span><span class="o">/</span><span class="n">filewordnum</span><span class="p">[</span><span class="n">j</span><span class="p">];</span><span class="c1">//词频</span>
</span><span class='line'>            <span class="n">fprintf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%.8lf &quot;</span><span class="p">,</span> <span class="n">tf</span><span class="o">*</span><span class="n">idf</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">fprintf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="n">processing</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span><span class="c1">//显示计算进度</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
</span><span class='line'>    <span class="n">fclose</span><span class="p">(</span><span class="n">fpword</span><span class="p">);</span>
</span><span class='line'>    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>截图显示该程序运行结果如下：</p>

<p><img class="center" src="http://lianxu.me/images/post/nmf1.jpg" title="NMF" ></p>

<p>经过这个程序会把50篇训练样本变成一个T_v.txt文件也就是这50篇文章的VSM，还有一个T_word.txt这个全部的词表。这是很好的开始，我们已经把一篇篇文章变成可以计算的数字了。</p>

<h1>第二：VSM做NMF分解</h1>

<p>接下来第2大步骤用NMF分解矩阵。这个步骤目的很简单，给VSM降维。因为VSM太庞大了，文本分类速度会很慢。NMF可以把一个非负矩阵X分解成2个非负矩阵B、H，满足X≈BH。矩阵分解的数学研究有很长历史，大家可以自己慢慢学习。至于矩阵分解后为何可以做文本分类，呵呵大家可以后悔自己上学的时候为什么没好好学习线性代数了，不过可以简单的理解为分解后的矩阵带有原矩阵的特点</p>

<p>第二步可以使用不同的矩阵分解方法,例如PCA(主成分分析)、ICA(独立成分分析)、SVD(奇异值分解)、VQ(矢量量化)等，它们各有特点。不过都是对原矩阵没有约束的，NMF则有非负这个约束条件。</p>

<p>NMF算法3个输入参数分别是X，R，IterateNum 。X是哪个大矩阵，R是降维后的B的秩，IterateNum 是NMF的迭代次数。NMF是迭代计算的，需要迭代次数。生成的BH会收敛。迭代次数越多BH越接近X。至于迭代多少次就可以自己可以测试，满足精度就可以了，否则NMF迭代计算比较费时间。</p>

<p>NMF算法2个输出分别是B和H。算法描述如下:</p>

<pre><code>1. 初始化矩阵B，H为非负数，同时对U的每一列数据归一化
2. for i=1 to IterateNum 
    a：H = H .* ( B' * ( X ./ ( B * H ) ) )
    b：B = B .* ( ( X ./ ( B * H ) ) * H' )
    c：B 归一化
3. end
</code></pre>

<p>对上面这个伪代码做个解释。先说B，H的大小原矩阵X(w,h)的话 B(R,Xh) H(Xw,R) (<em>注：w表示矩阵宽度,h表示高度</em>)</p>

<p>初始化B,H是将2个矩阵的数据随机赋值，正浮点数范围(1.0~10.0)就可以了。接着第一步里B需要归一化，归一化的意思就是把B变成一个特殊的矩阵，特殊之处在于，B的每一列相加正好等于1。</p>

<p>第二步迭代IterateNum次，其中U&#8217;表示矩阵转置，.<em>表示点乘就是矩阵对应位置数据相乘 ./就是点除对应位置相除。</em>就是矩阵乘法。</p>

<p>下面贴一下NMF 的代码：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
<span class='line-number'>102</span>
<span class='line-number'>103</span>
<span class='line-number'>104</span>
<span class='line-number'>105</span>
<span class='line-number'>106</span>
<span class='line-number'>107</span>
<span class='line-number'>108</span>
<span class='line-number'>109</span>
<span class='line-number'>110</span>
<span class='line-number'>111</span>
<span class='line-number'>112</span>
<span class='line-number'>113</span>
<span class='line-number'>114</span>
<span class='line-number'>115</span>
<span class='line-number'>116</span>
<span class='line-number'>117</span>
<span class='line-number'>118</span>
<span class='line-number'>119</span>
<span class='line-number'>120</span>
<span class='line-number'>121</span>
<span class='line-number'>122</span>
<span class='line-number'>123</span>
<span class='line-number'>124</span>
<span class='line-number'>125</span>
<span class='line-number'>126</span>
<span class='line-number'>127</span>
<span class='line-number'>128</span>
<span class='line-number'>129</span>
<span class='line-number'>130</span>
<span class='line-number'>131</span>
<span class='line-number'>132</span>
<span class='line-number'>133</span>
<span class='line-number'>134</span>
<span class='line-number'>135</span>
<span class='line-number'>136</span>
<span class='line-number'>137</span>
<span class='line-number'>138</span>
<span class='line-number'>139</span>
<span class='line-number'>140</span>
<span class='line-number'>141</span>
<span class='line-number'>142</span>
<span class='line-number'>143</span>
<span class='line-number'>144</span>
<span class='line-number'>145</span>
<span class='line-number'>146</span>
<span class='line-number'>147</span>
<span class='line-number'>148</span>
<span class='line-number'>149</span>
<span class='line-number'>150</span>
<span class='line-number'>151</span>
<span class='line-number'>152</span>
<span class='line-number'>153</span>
<span class='line-number'>154</span>
<span class='line-number'>155</span>
<span class='line-number'>156</span>
<span class='line-number'>157</span>
<span class='line-number'>158</span>
<span class='line-number'>159</span>
<span class='line-number'>160</span>
<span class='line-number'>161</span>
<span class='line-number'>162</span>
<span class='line-number'>163</span>
<span class='line-number'>164</span>
<span class='line-number'>165</span>
<span class='line-number'>166</span>
<span class='line-number'>167</span>
<span class='line-number'>168</span>
<span class='line-number'>169</span>
<span class='line-number'>170</span>
<span class='line-number'>171</span>
<span class='line-number'>172</span>
<span class='line-number'>173</span>
<span class='line-number'>174</span>
<span class='line-number'>175</span>
<span class='line-number'>176</span>
<span class='line-number'>177</span>
<span class='line-number'>178</span>
<span class='line-number'>179</span>
<span class='line-number'>180</span>
<span class='line-number'>181</span>
<span class='line-number'>182</span>
<span class='line-number'>183</span>
<span class='line-number'>184</span>
<span class='line-number'>185</span>
<span class='line-number'>186</span>
<span class='line-number'>187</span>
<span class='line-number'>188</span>
<span class='line-number'>189</span>
<span class='line-number'>190</span>
<span class='line-number'>191</span>
<span class='line-number'>192</span>
<span class='line-number'>193</span>
<span class='line-number'>194</span>
<span class='line-number'>195</span>
<span class='line-number'>196</span>
<span class='line-number'>197</span>
<span class='line-number'>198</span>
<span class='line-number'>199</span>
<span class='line-number'>200</span>
<span class='line-number'>201</span>
<span class='line-number'>202</span>
<span class='line-number'>203</span>
<span class='line-number'>204</span>
<span class='line-number'>205</span>
<span class='line-number'>206</span>
<span class='line-number'>207</span>
<span class='line-number'>208</span>
<span class='line-number'>209</span>
<span class='line-number'>210</span>
<span class='line-number'>211</span>
<span class='line-number'>212</span>
<span class='line-number'>213</span>
<span class='line-number'>214</span>
<span class='line-number'>215</span>
<span class='line-number'>216</span>
<span class='line-number'>217</span>
<span class='line-number'>218</span>
<span class='line-number'>219</span>
<span class='line-number'>220</span>
<span class='line-number'>221</span>
<span class='line-number'>222</span>
<span class='line-number'>223</span>
<span class='line-number'>224</span>
<span class='line-number'>225</span>
<span class='line-number'>226</span>
<span class='line-number'>227</span>
<span class='line-number'>228</span>
<span class='line-number'>229</span>
<span class='line-number'>230</span>
<span class='line-number'>231</span>
<span class='line-number'>232</span>
<span class='line-number'>233</span>
<span class='line-number'>234</span>
<span class='line-number'>235</span>
<span class='line-number'>236</span>
<span class='line-number'>237</span>
<span class='line-number'>238</span>
<span class='line-number'>239</span>
<span class='line-number'>240</span>
<span class='line-number'>241</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="cm">/**************************************************</span>
</span><span class='line'><span class="cm">*   NMF by keefo 2008.05.26</span>
</span><span class='line'><span class="cm">**************************************************/</span>
</span><span class='line'><span class="cp"> </span>
</span><span class='line'><span class="cp">#include &lt;stdio.h&gt;</span>
</span><span class='line'><span class="cp">#include &lt;string.h&gt;</span>
</span><span class='line'><span class="cp">#include &lt;memory.h&gt;</span>
</span><span class='line'><span class="cp">#include &lt;stdlib.h&gt;</span>
</span><span class='line'><span class="cp">#include &lt;time.h&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#define ARRAY2D(VTYPE,X,Y) (VTYPE **) malloc2d(X, Y, sizeof(VTYPE))</span>
</span><span class='line'><span class="cp">#define MATRIX(NAME,X,Y) matrix NAME;NAME.p=ARRAY2D(double,X,Y);NAME.x=X;NAME.y=Y;</span>
</span><span class='line'><span class="cp">#define FREE(X) free2d(&amp;X)</span>
</span><span class='line'>
</span><span class='line'><span class="k">typedef</span> <span class="k">struct</span><span class="p">{</span>
</span><span class='line'>  <span class="kt">double</span> <span class="o">**</span><span class="n">p</span><span class="p">;</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span> <span class="n">matrix</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span><span class="o">**</span> <span class="nf">malloc2d</span><span class="p">(</span><span class="kt">int</span> <span class="n">W</span><span class="p">,</span> <span class="kt">int</span> <span class="n">H</span><span class="p">,</span> <span class="kt">int</span> <span class="n">size</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">j</span><span class="p">,</span><span class="n">rowSize</span><span class="o">=</span><span class="n">W</span><span class="o">*</span><span class="n">size</span><span class="p">,</span><span class="n">colSize</span><span class="o">=</span><span class="n">H</span><span class="o">*</span><span class="k">sizeof</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">);</span>
</span><span class='line'>  <span class="kt">void</span> <span class="o">**</span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="kt">void</span> <span class="o">**</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="n">colSize</span><span class="o">+</span><span class="n">H</span><span class="o">*</span><span class="n">rowSize</span><span class="p">);</span>
</span><span class='line'>  <span class="kt">char</span> <span class="o">*</span><span class="n">begin</span><span class="o">=</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">a</span><span class="o">+</span><span class="n">colSize</span><span class="p">;</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">H</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="n">a</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">=</span><span class="n">begin</span><span class="o">+</span><span class="n">j</span><span class="o">*</span><span class="n">rowSize</span><span class="p">;</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">a</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">free2d</span><span class="p">(</span><span class="n">matrix</span> <span class="o">*</span><span class="n">M</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">free</span><span class="p">(</span><span class="n">M</span><span class="o">-&gt;</span><span class="n">p</span><span class="p">);</span>
</span><span class='line'>  <span class="n">M</span><span class="o">-&gt;</span><span class="n">p</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'>  <span class="n">M</span><span class="o">-&gt;</span><span class="n">x</span><span class="o">=</span><span class="n">M</span><span class="o">-&gt;</span><span class="n">y</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="n">matrix</span> <span class="nf">RandomMatrix</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span><span class="kt">int</span> <span class="n">y</span><span class="p">)</span> <span class="c1">//生成随机矩阵</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">;</span>
</span><span class='line'>  <span class="n">MATRIX</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>  <span class="n">srand</span><span class="p">((</span><span class="kt">int</span><span class="p">)</span><span class="n">time</span><span class="p">(</span><span class="nb">NULL</span><span class="p">));</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">y</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">x</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">A</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">=</span><span class="p">((</span><span class="kt">double</span><span class="p">)</span><span class="n">rand</span><span class="p">()</span><span class="o">/</span><span class="p">((</span><span class="kt">double</span><span class="p">)</span><span class="n">RAND_MAX</span><span class="o">+</span><span class="mi">1</span><span class="p">))</span><span class="o">*</span><span class="mi">10</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">A</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="n">matrix</span> <span class="nf">ONES</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span><span class="kt">int</span> <span class="n">y</span><span class="p">)</span> <span class="c1">//生成全为1的矩阵</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">;</span>
</span><span class='line'>  <span class="n">MATRIX</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">y</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">x</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>            <span class="n">A</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">=</span><span class="mf">1.0</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">A</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">SUM</span><span class="p">(</span><span class="n">matrix</span> <span class="n">A</span><span class="p">,</span><span class="n">matrix</span> <span class="o">*</span><span class="n">B</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">;</span>
</span><span class='line'>  <span class="kt">double</span> <span class="n">sum</span><span class="p">;</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">x</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>        <span class="n">sum</span><span class="o">=</span><span class="mf">0.0</span><span class="p">;</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">y</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>            <span class="n">sum</span><span class="o">+=</span><span class="n">A</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">i</span><span class="p">];</span>
</span><span class='line'>        <span class="n">B</span><span class="o">-&gt;</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">sum</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">DOTMUL</span><span class="p">(</span><span class="n">matrix</span> <span class="n">A</span><span class="p">,</span><span class="n">matrix</span> <span class="n">B</span><span class="p">,</span><span class="n">matrix</span> <span class="o">*</span><span class="n">C</span><span class="p">)</span> <span class="c1">//矩阵点乘</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">;</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">x</span><span class="o">!=</span><span class="n">B</span><span class="p">.</span><span class="n">x</span> <span class="o">||</span> <span class="n">A</span><span class="p">.</span><span class="n">y</span><span class="o">!=</span><span class="n">B</span><span class="p">.</span><span class="n">y</span><span class="p">)</span>
</span><span class='line'>        <span class="k">return</span><span class="p">;</span>
</span><span class='line'>  
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">y</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">x</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>            <span class="n">C</span><span class="o">-&gt;</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">=</span><span class="n">A</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">*</span><span class="n">B</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">MUL</span><span class="p">(</span><span class="n">matrix</span> <span class="n">A</span><span class="p">,</span><span class="n">matrix</span> <span class="n">B</span><span class="p">,</span><span class="n">matrix</span> <span class="o">*</span><span class="n">C</span><span class="p">)</span> <span class="c1">//矩阵相乘</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">k</span><span class="p">;</span>
</span><span class='line'>  <span class="kt">double</span> <span class="n">sum</span><span class="p">;</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">x</span><span class="o">!=</span><span class="n">B</span><span class="p">.</span><span class="n">y</span><span class="p">)</span>
</span><span class='line'>        <span class="k">return</span><span class="p">;</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">y</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">B</span><span class="p">.</span><span class="n">x</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">sum</span><span class="o">=</span><span class="mf">0.0</span><span class="p">;</span>
</span><span class='line'>            <span class="k">for</span><span class="p">(</span><span class="n">k</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">k</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">x</span><span class="p">;</span><span class="n">k</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>                <span class="n">sum</span><span class="o">+=</span><span class="n">A</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">]</span><span class="o">*</span><span class="n">B</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">k</span><span class="p">][</span><span class="n">j</span><span class="p">];</span>
</span><span class='line'>            <span class="n">C</span><span class="o">-&gt;</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">=</span><span class="n">sum</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">DOTDIV</span><span class="p">(</span><span class="n">matrix</span> <span class="n">A</span><span class="p">,</span><span class="n">matrix</span> <span class="n">B</span><span class="p">,</span><span class="n">matrix</span> <span class="o">*</span><span class="n">C</span><span class="p">)</span> <span class="c1">//矩阵点除</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">;</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">x</span><span class="o">!=</span><span class="n">B</span><span class="p">.</span><span class="n">x</span> <span class="o">||</span> <span class="n">A</span><span class="p">.</span><span class="n">y</span><span class="o">!=</span><span class="n">B</span><span class="p">.</span><span class="n">y</span><span class="p">)</span>
</span><span class='line'>        <span class="k">return</span><span class="p">;</span>
</span><span class='line'>  
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">y</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">x</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>            <span class="n">C</span><span class="o">-&gt;</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">=</span><span class="n">A</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">/</span><span class="n">B</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">T</span><span class="p">(</span><span class="n">matrix</span> <span class="n">S</span><span class="p">,</span><span class="n">matrix</span> <span class="o">*</span><span class="n">D</span><span class="p">)</span> <span class="c1">//矩阵转置</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">;</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">S</span><span class="p">.</span><span class="n">y</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">S</span><span class="p">.</span><span class="n">x</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">D</span><span class="o">-&gt;</span><span class="n">p</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">S</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">fprint</span><span class="p">(</span><span class="kt">char</span> <span class="n">name</span><span class="p">[</span><span class="mi">128</span><span class="p">],</span><span class="n">matrix</span> <span class="n">m</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">;</span>
</span><span class='line'>  <span class="kt">FILE</span> <span class="o">*</span><span class="n">fp</span><span class="p">;</span>
</span><span class='line'>  <span class="n">fp</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;w&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="n">fprintf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%d %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">m</span><span class="p">.</span><span class="n">x</span><span class="p">,</span><span class="n">m</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">m</span><span class="p">.</span><span class="n">p</span><span class="p">){</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">m</span><span class="p">.</span><span class="n">y</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">){</span>
</span><span class='line'>            <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">m</span><span class="p">.</span><span class="n">x</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>                <span class="n">fprintf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%.8f &quot;</span><span class="p">,</span><span class="n">m</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]);</span>
</span><span class='line'>            <span class="n">fprintf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">argv</span><span class="p">[])</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="n">r</span><span class="p">,</span><span class="n">iteratenum</span><span class="p">;</span>
</span><span class='line'>  <span class="kt">char</span> <span class="n">word</span><span class="p">[</span><span class="mi">128</span><span class="p">];</span>
</span><span class='line'>  <span class="kt">FILE</span> <span class="o">*</span><span class="n">fp</span><span class="p">;</span>
</span><span class='line'>  
</span><span class='line'>  <span class="n">fp</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="s">&quot;config.ini&quot;</span><span class="p">,</span><span class="s">&quot;r&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">fp</span><span class="o">==</span><span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>      <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Can&#39;t open file config.ini!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>      <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>      <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%s %d&quot;</span><span class="p">,</span><span class="n">word</span><span class="p">,</span><span class="o">&amp;</span><span class="n">r</span><span class="p">);</span>
</span><span class='line'>  <span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%s %d&quot;</span><span class="p">,</span><span class="n">word</span><span class="p">,</span><span class="o">&amp;</span><span class="n">iteratenum</span><span class="p">);</span>
</span><span class='line'>  <span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
</span><span class='line'>  
</span><span class='line'>  <span class="n">fp</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="s">&quot;T_v.txt&quot;</span><span class="p">,</span><span class="s">&quot;r&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">fp</span><span class="o">==</span><span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Can&#39;t open file T_v.txt!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  
</span><span class='line'>  <span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%d %d&quot;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">x</span><span class="p">,</span><span class="o">&amp;</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>  
</span><span class='line'>  <span class="n">MATRIX</span><span class="p">(</span><span class="n">X</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>  
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">y</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">x</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>            <span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%lf&quot;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">X</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]);</span>
</span><span class='line'>  <span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
</span><span class='line'>  
</span><span class='line'>  <span class="n">printf</span><span class="p">(</span><span class="s">&quot;r=%d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">r</span><span class="p">);</span>
</span><span class='line'>  
</span><span class='line'>  <span class="n">matrix</span> <span class="n">B</span><span class="o">=</span><span class="n">RandomMatrix</span><span class="p">(</span><span class="n">r</span><span class="p">,</span><span class="n">X</span><span class="p">.</span><span class="n">y</span><span class="p">);</span> <span class="c1">//初始化B，为随机非负数</span>
</span><span class='line'>  <span class="n">matrix</span> <span class="n">H</span><span class="o">=</span><span class="n">RandomMatrix</span><span class="p">(</span><span class="n">X</span><span class="p">.</span><span class="n">x</span><span class="p">,</span><span class="n">r</span><span class="p">);</span> <span class="c1">//初始化H，为随机非负数</span>
</span><span class='line'>  <span class="cm">/*************定义中间变量*************/</span>
</span><span class='line'>  <span class="n">matrix</span> <span class="n">one</span><span class="o">=</span><span class="n">ONES</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">X</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>  <span class="n">MATRIX</span><span class="p">(</span><span class="n">XX</span><span class="p">,</span><span class="n">X</span><span class="p">.</span><span class="n">x</span><span class="p">,</span><span class="n">X</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>  <span class="n">MATRIX</span><span class="p">(</span><span class="n">TB</span><span class="p">,</span><span class="n">B</span><span class="p">.</span><span class="n">y</span><span class="p">,</span><span class="n">B</span><span class="p">.</span><span class="n">x</span><span class="p">);</span>
</span><span class='line'>  <span class="n">MATRIX</span><span class="p">(</span><span class="n">BB</span><span class="p">,</span><span class="n">B</span><span class="p">.</span><span class="n">x</span><span class="p">,</span><span class="n">B</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>  <span class="n">MATRIX</span><span class="p">(</span><span class="n">TH</span><span class="p">,</span><span class="n">H</span><span class="p">.</span><span class="n">y</span><span class="p">,</span><span class="n">H</span><span class="p">.</span><span class="n">x</span><span class="p">);</span>
</span><span class='line'>  <span class="n">MATRIX</span><span class="p">(</span><span class="n">HH</span><span class="p">,</span><span class="n">H</span><span class="p">.</span><span class="n">x</span><span class="p">,</span><span class="n">H</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>  <span class="n">MATRIX</span><span class="p">(</span><span class="n">BH</span><span class="p">,</span><span class="n">H</span><span class="p">.</span><span class="n">x</span><span class="p">,</span><span class="n">B</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>  <span class="n">MATRIX</span><span class="p">(</span><span class="n">SB</span><span class="p">,</span><span class="n">B</span><span class="p">.</span><span class="n">x</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>  
</span><span class='line'>  <span class="cm">/*************归一化B的每一列*************/</span>
</span><span class='line'>  <span class="n">SUM</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="o">&amp;</span><span class="n">SB</span><span class="p">);</span>
</span><span class='line'>  <span class="n">MUL</span><span class="p">(</span><span class="n">one</span><span class="p">,</span><span class="n">SB</span><span class="p">,</span><span class="o">&amp;</span><span class="n">BB</span><span class="p">);</span>
</span><span class='line'>  <span class="n">DOTDIV</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="n">BB</span><span class="p">,</span><span class="o">&amp;</span><span class="n">B</span><span class="p">);</span>
</span><span class='line'>  
</span><span class='line'>  <span class="cm">/*************开始迭代计算*************/</span>
</span><span class='line'>  <span class="n">printf</span><span class="p">(</span><span class="s">&quot;共%d次迭代计算</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">iteratenum</span><span class="p">);</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">iteratenum</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">printf</span><span class="p">(</span><span class="s">&quot;%d &quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>      <span class="c1">// a：H = H .* ( B&#39; * ( X ./ ( B * H ) ) )</span>
</span><span class='line'>      <span class="n">MUL</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="n">H</span><span class="p">,</span><span class="o">&amp;</span><span class="n">BH</span><span class="p">);</span>
</span><span class='line'>      <span class="n">DOTDIV</span><span class="p">(</span><span class="n">X</span><span class="p">,</span><span class="n">BH</span><span class="p">,</span><span class="o">&amp;</span><span class="n">XX</span><span class="p">);</span>
</span><span class='line'>      <span class="n">T</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="o">&amp;</span><span class="n">TB</span><span class="p">);</span>
</span><span class='line'>      <span class="n">MUL</span><span class="p">(</span><span class="n">TB</span><span class="p">,</span><span class="n">XX</span><span class="p">,</span><span class="o">&amp;</span><span class="n">HH</span><span class="p">);</span>
</span><span class='line'>      <span class="n">DOTMUL</span><span class="p">(</span><span class="n">H</span><span class="p">,</span><span class="n">HH</span><span class="p">,</span><span class="o">&amp;</span><span class="n">H</span><span class="p">);</span>
</span><span class='line'>      <span class="c1">// b：B = B .* ( ( X ./ ( B * H ) ) * H&#39; )</span>
</span><span class='line'>      <span class="n">T</span><span class="p">(</span><span class="n">H</span><span class="p">,</span><span class="o">&amp;</span><span class="n">TH</span><span class="p">);</span>
</span><span class='line'>      <span class="n">MUL</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="n">H</span><span class="p">,</span><span class="o">&amp;</span><span class="n">BH</span><span class="p">);</span>
</span><span class='line'>      <span class="n">DOTDIV</span><span class="p">(</span><span class="n">X</span><span class="p">,</span><span class="n">BH</span><span class="p">,</span><span class="o">&amp;</span><span class="n">XX</span><span class="p">);</span>
</span><span class='line'>      <span class="n">MUL</span><span class="p">(</span><span class="n">XX</span><span class="p">,</span><span class="n">TH</span><span class="p">,</span><span class="o">&amp;</span><span class="n">BB</span><span class="p">);</span>
</span><span class='line'>      <span class="n">DOTMUL</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="n">BB</span><span class="p">,</span><span class="o">&amp;</span><span class="n">B</span><span class="p">);</span>
</span><span class='line'>      <span class="c1">// c：B 归一化</span>
</span><span class='line'>      <span class="n">SUM</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="o">&amp;</span><span class="n">SB</span><span class="p">);</span>
</span><span class='line'>      <span class="n">MUL</span><span class="p">(</span><span class="n">one</span><span class="p">,</span><span class="n">SB</span><span class="p">,</span><span class="o">&amp;</span><span class="n">BB</span><span class="p">);</span>
</span><span class='line'>      <span class="n">DOTDIV</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="n">BB</span><span class="p">,</span><span class="o">&amp;</span><span class="n">B</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  
</span><span class='line'>  <span class="c1">//MUL(B,H,&amp;XX);//测试计算出来的BH相乘是否接近X</span>
</span><span class='line'>  <span class="c1">//fprint(&quot;BxH.txt&quot;,XX);</span>
</span><span class='line'>  
</span><span class='line'>  <span class="n">T</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="o">&amp;</span><span class="n">TB</span><span class="p">);</span>
</span><span class='line'>  <span class="n">MUL</span><span class="p">(</span><span class="n">TB</span><span class="p">,</span><span class="n">X</span><span class="p">,</span><span class="o">&amp;</span><span class="n">HH</span><span class="p">);</span>
</span><span class='line'>  
</span><span class='line'>  <span class="n">printf</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">计算完成!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="n">printf</span><span class="p">(</span><span class="s">&quot;写入数据 T_eigenvector.txt...</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="n">fprint</span><span class="p">(</span><span class="s">&quot;T_eigenvector.txt&quot;</span><span class="p">,</span><span class="n">HH</span><span class="p">);</span>
</span><span class='line'>  <span class="n">fprint</span><span class="p">(</span><span class="s">&quot;T_B.txt&quot;</span><span class="p">,</span><span class="n">TB</span><span class="p">);</span>
</span><span class='line'>  
</span><span class='line'>  <span class="n">FREE</span><span class="p">(</span><span class="n">B</span><span class="p">);</span>
</span><span class='line'>  <span class="n">FREE</span><span class="p">(</span><span class="n">H</span><span class="p">);</span>
</span><span class='line'>  <span class="n">FREE</span><span class="p">(</span><span class="n">X</span><span class="p">);</span>
</span><span class='line'>  <span class="n">FREE</span><span class="p">(</span><span class="n">one</span><span class="p">);</span>
</span><span class='line'>  <span class="n">FREE</span><span class="p">(</span><span class="n">BB</span><span class="p">);</span>
</span><span class='line'>  <span class="n">FREE</span><span class="p">(</span><span class="n">HH</span><span class="p">);</span>
</span><span class='line'>  <span class="n">FREE</span><span class="p">(</span><span class="n">TB</span><span class="p">);</span>
</span><span class='line'>  <span class="n">FREE</span><span class="p">(</span><span class="n">TH</span><span class="p">);</span>
</span><span class='line'>  <span class="n">FREE</span><span class="p">(</span><span class="n">SB</span><span class="p">);</span>
</span><span class='line'>  <span class="n">FREE</span><span class="p">(</span><span class="n">XX</span><span class="p">);</span>
</span><span class='line'>  <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>现在虽然代码已经贴出来了，但是有些细节还没介绍。NMF程序计算完，它把VSM生成的T_v.txt这个矩阵分解，生成了B和H。但是第3步的文本分类并不是直接利用生成的B、H，而是需要使用 B&#8217; 和 B&#8217; * X 。所以 T_B.txt 和 T_eigenvector.txt 这2个文件，T_B.txt 是分解出的矩阵B的转置，T_eigenvector.txt 则是 B&#8217; * X 。所以保存这2个矩阵。</p>

<h1>第三：文本文类</h1>

<p>从实际角度考虑文本分类传入的参数应该是一个待分类的文本，输出是它属于哪个类别。这样需要计算的就是这个文本和哪个类别的相似度最高。</p>

<p>从程序计算的角度考虑，现在已经拥有的数据是训练样本生成的特征矩阵T_eigenvector.txt和B的转置T_B.txt 。所以待分类文本也需要做处理才能用于计算，当然是生成待分类文本的特征查询向量q，注意是q查询向量，也就是一个1xW的矩阵。这个向量应该在第一步建立的表征词表T_word.txt的基础上。因为这样才能保证待分类向量和训练样本在同一个语义集合。请仔细理解这里。</p>

<p>例如上面的例子中，我建立的表征词共8109个，那么如果要分类一个文件ABC.t×t 那么需要建立的这个向量便是ABC内的词映射到这8109个词上的统计表，使用tf计算权重。这个向量也是1×8109的。</p>

<p>接下来我就说明如何计算这个查询向量q和训练出来的特征矩阵的相似度。使用余弦距离计算2个向量的距离。T_eigenvector.txt的每一列表示一个训练文件的特征向量。余弦距离计算，传入的参数是2个同维的向量，而T_eigenvector.txt的每一列是个R维的向量，当然我们的这个查询向量q则有8109维。这时候大家应该想的了，需要第2步生成的哪个B&#8217; ，也就是T_B.txt 。公式如下：</p>

<pre><code>q = q * B'
</code></pre>

<p>这个公式把查询向量q转化成R维。这样就可以计算这个查询向量和哪个训练文本相似度高了。</p>

<p>把q分别和T_eigenvector.txt的50列计算余弦距离。然后每10列求平均值，得到5列，这5列就是查询向量和5大类文本的相似度，越大的相似度越高。</p>

<p>下面写出代码:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
<span class='line-number'>102</span>
<span class='line-number'>103</span>
<span class='line-number'>104</span>
<span class='line-number'>105</span>
<span class='line-number'>106</span>
<span class='line-number'>107</span>
<span class='line-number'>108</span>
<span class='line-number'>109</span>
<span class='line-number'>110</span>
<span class='line-number'>111</span>
<span class='line-number'>112</span>
<span class='line-number'>113</span>
<span class='line-number'>114</span>
<span class='line-number'>115</span>
<span class='line-number'>116</span>
<span class='line-number'>117</span>
<span class='line-number'>118</span>
<span class='line-number'>119</span>
<span class='line-number'>120</span>
<span class='line-number'>121</span>
<span class='line-number'>122</span>
<span class='line-number'>123</span>
<span class='line-number'>124</span>
<span class='line-number'>125</span>
<span class='line-number'>126</span>
<span class='line-number'>127</span>
<span class='line-number'>128</span>
<span class='line-number'>129</span>
<span class='line-number'>130</span>
<span class='line-number'>131</span>
<span class='line-number'>132</span>
<span class='line-number'>133</span>
<span class='line-number'>134</span>
<span class='line-number'>135</span>
<span class='line-number'>136</span>
<span class='line-number'>137</span>
<span class='line-number'>138</span>
<span class='line-number'>139</span>
<span class='line-number'>140</span>
<span class='line-number'>141</span>
<span class='line-number'>142</span>
<span class='line-number'>143</span>
<span class='line-number'>144</span>
<span class='line-number'>145</span>
<span class='line-number'>146</span>
<span class='line-number'>147</span>
<span class='line-number'>148</span>
<span class='line-number'>149</span>
<span class='line-number'>150</span>
<span class='line-number'>151</span>
<span class='line-number'>152</span>
<span class='line-number'>153</span>
<span class='line-number'>154</span>
<span class='line-number'>155</span>
<span class='line-number'>156</span>
<span class='line-number'>157</span>
<span class='line-number'>158</span>
<span class='line-number'>159</span>
<span class='line-number'>160</span>
<span class='line-number'>161</span>
<span class='line-number'>162</span>
<span class='line-number'>163</span>
<span class='line-number'>164</span>
<span class='line-number'>165</span>
<span class='line-number'>166</span>
<span class='line-number'>167</span>
<span class='line-number'>168</span>
<span class='line-number'>169</span>
<span class='line-number'>170</span>
<span class='line-number'>171</span>
<span class='line-number'>172</span>
<span class='line-number'>173</span>
<span class='line-number'>174</span>
<span class='line-number'>175</span>
<span class='line-number'>176</span>
<span class='line-number'>177</span>
<span class='line-number'>178</span>
<span class='line-number'>179</span>
<span class='line-number'>180</span>
<span class='line-number'>181</span>
<span class='line-number'>182</span>
<span class='line-number'>183</span>
<span class='line-number'>184</span>
<span class='line-number'>185</span>
<span class='line-number'>186</span>
<span class='line-number'>187</span>
<span class='line-number'>188</span>
<span class='line-number'>189</span>
<span class='line-number'>190</span>
<span class='line-number'>191</span>
<span class='line-number'>192</span>
<span class='line-number'>193</span>
<span class='line-number'>194</span>
<span class='line-number'>195</span>
<span class='line-number'>196</span>
<span class='line-number'>197</span>
<span class='line-number'>198</span>
<span class='line-number'>199</span>
<span class='line-number'>200</span>
<span class='line-number'>201</span>
<span class='line-number'>202</span>
<span class='line-number'>203</span>
<span class='line-number'>204</span>
<span class='line-number'>205</span>
<span class='line-number'>206</span>
<span class='line-number'>207</span>
<span class='line-number'>208</span>
<span class='line-number'>209</span>
<span class='line-number'>210</span>
<span class='line-number'>211</span>
<span class='line-number'>212</span>
<span class='line-number'>213</span>
<span class='line-number'>214</span>
<span class='line-number'>215</span>
<span class='line-number'>216</span>
<span class='line-number'>217</span>
<span class='line-number'>218</span>
<span class='line-number'>219</span>
<span class='line-number'>220</span>
<span class='line-number'>221</span>
<span class='line-number'>222</span>
<span class='line-number'>223</span>
<span class='line-number'>224</span>
<span class='line-number'>225</span>
<span class='line-number'>226</span>
<span class='line-number'>227</span>
<span class='line-number'>228</span>
<span class='line-number'>229</span>
<span class='line-number'>230</span>
<span class='line-number'>231</span>
<span class='line-number'>232</span>
<span class='line-number'>233</span>
<span class='line-number'>234</span>
<span class='line-number'>235</span>
<span class='line-number'>236</span>
<span class='line-number'>237</span>
<span class='line-number'>238</span>
<span class='line-number'>239</span>
<span class='line-number'>240</span>
<span class='line-number'>241</span>
<span class='line-number'>242</span>
<span class='line-number'>243</span>
<span class='line-number'>244</span>
<span class='line-number'>245</span>
<span class='line-number'>246</span>
<span class='line-number'>247</span>
<span class='line-number'>248</span>
<span class='line-number'>249</span>
<span class='line-number'>250</span>
<span class='line-number'>251</span>
<span class='line-number'>252</span>
<span class='line-number'>253</span>
<span class='line-number'>254</span>
<span class='line-number'>255</span>
<span class='line-number'>256</span>
<span class='line-number'>257</span>
<span class='line-number'>258</span>
<span class='line-number'>259</span>
<span class='line-number'>260</span>
<span class='line-number'>261</span>
<span class='line-number'>262</span>
<span class='line-number'>263</span>
<span class='line-number'>264</span>
<span class='line-number'>265</span>
<span class='line-number'>266</span>
<span class='line-number'>267</span>
<span class='line-number'>268</span>
<span class='line-number'>269</span>
<span class='line-number'>270</span>
<span class='line-number'>271</span>
<span class='line-number'>272</span>
<span class='line-number'>273</span>
<span class='line-number'>274</span>
<span class='line-number'>275</span>
<span class='line-number'>276</span>
<span class='line-number'>277</span>
<span class='line-number'>278</span>
<span class='line-number'>279</span>
<span class='line-number'>280</span>
<span class='line-number'>281</span>
<span class='line-number'>282</span>
<span class='line-number'>283</span>
<span class='line-number'>284</span>
<span class='line-number'>285</span>
<span class='line-number'>286</span>
<span class='line-number'>287</span>
<span class='line-number'>288</span>
<span class='line-number'>289</span>
<span class='line-number'>290</span>
<span class='line-number'>291</span>
<span class='line-number'>292</span>
<span class='line-number'>293</span>
<span class='line-number'>294</span>
<span class='line-number'>295</span>
<span class='line-number'>296</span>
<span class='line-number'>297</span>
<span class='line-number'>298</span>
<span class='line-number'>299</span>
<span class='line-number'>300</span>
<span class='line-number'>301</span>
<span class='line-number'>302</span>
<span class='line-number'>303</span>
<span class='line-number'>304</span>
<span class='line-number'>305</span>
<span class='line-number'>306</span>
<span class='line-number'>307</span>
<span class='line-number'>308</span>
<span class='line-number'>309</span>
<span class='line-number'>310</span>
<span class='line-number'>311</span>
<span class='line-number'>312</span>
<span class='line-number'>313</span>
<span class='line-number'>314</span>
<span class='line-number'>315</span>
<span class='line-number'>316</span>
<span class='line-number'>317</span>
<span class='line-number'>318</span>
<span class='line-number'>319</span>
<span class='line-number'>320</span>
<span class='line-number'>321</span>
<span class='line-number'>322</span>
<span class='line-number'>323</span>
<span class='line-number'>324</span>
<span class='line-number'>325</span>
<span class='line-number'>326</span>
<span class='line-number'>327</span>
<span class='line-number'>328</span>
<span class='line-number'>329</span>
<span class='line-number'>330</span>
<span class='line-number'>331</span>
<span class='line-number'>332</span>
<span class='line-number'>333</span>
<span class='line-number'>334</span>
<span class='line-number'>335</span>
<span class='line-number'>336</span>
<span class='line-number'>337</span>
<span class='line-number'>338</span>
<span class='line-number'>339</span>
<span class='line-number'>340</span>
<span class='line-number'>341</span>
<span class='line-number'>342</span>
<span class='line-number'>343</span>
<span class='line-number'>344</span>
<span class='line-number'>345</span>
<span class='line-number'>346</span>
<span class='line-number'>347</span>
<span class='line-number'>348</span>
<span class='line-number'>349</span>
<span class='line-number'>350</span>
<span class='line-number'>351</span>
<span class='line-number'>352</span>
<span class='line-number'>353</span>
<span class='line-number'>354</span>
<span class='line-number'>355</span>
<span class='line-number'>356</span>
<span class='line-number'>357</span>
<span class='line-number'>358</span>
<span class='line-number'>359</span>
<span class='line-number'>360</span>
<span class='line-number'>361</span>
<span class='line-number'>362</span>
<span class='line-number'>363</span>
<span class='line-number'>364</span>
<span class='line-number'>365</span>
<span class='line-number'>366</span>
<span class='line-number'>367</span>
<span class='line-number'>368</span>
<span class='line-number'>369</span>
<span class='line-number'>370</span>
<span class='line-number'>371</span>
<span class='line-number'>372</span>
<span class='line-number'>373</span>
<span class='line-number'>374</span>
<span class='line-number'>375</span>
<span class='line-number'>376</span>
<span class='line-number'>377</span>
<span class='line-number'>378</span>
<span class='line-number'>379</span>
<span class='line-number'>380</span>
<span class='line-number'>381</span>
<span class='line-number'>382</span>
<span class='line-number'>383</span>
<span class='line-number'>384</span>
<span class='line-number'>385</span>
<span class='line-number'>386</span>
<span class='line-number'>387</span>
<span class='line-number'>388</span>
<span class='line-number'>389</span>
<span class='line-number'>390</span>
<span class='line-number'>391</span>
<span class='line-number'>392</span>
<span class='line-number'>393</span>
<span class='line-number'>394</span>
<span class='line-number'>395</span>
<span class='line-number'>396</span>
<span class='line-number'>397</span>
<span class='line-number'>398</span>
<span class='line-number'>399</span>
<span class='line-number'>400</span>
<span class='line-number'>401</span>
<span class='line-number'>402</span>
<span class='line-number'>403</span>
<span class='line-number'>404</span>
<span class='line-number'>405</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="cm">/**************************************************</span>
</span><span class='line'><span class="cm">*   Class by keefo 2008.05.26</span>
</span><span class='line'><span class="cm">**************************************************/</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#include &lt;stdio.h&gt;</span>
</span><span class='line'><span class="cp">#include &lt;string.h&gt;</span>
</span><span class='line'><span class="cp">#include &lt;time.h&gt;</span>
</span><span class='line'><span class="cp">#include &lt;math.h&gt;</span>
</span><span class='line'><span class="cp">#include &lt;map&gt;</span>
</span><span class='line'><span class="cp">#include &lt;string&gt;</span>
</span><span class='line'><span class="cp">#include &lt;vector&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="n">using</span> <span class="n">namespace</span> <span class="n">std</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#define FILENUM  50 </span>
</span><span class='line'><span class="cp">#define isDigit(ch) ((ch)&gt;=&#39;0&#39; &amp;&amp; (ch)&lt;=&#39;9&#39;)</span>
</span><span class='line'><span class="cp">#define isAlpha(ch) (((ch)&gt;=&#39;a&#39; &amp;&amp; (ch)&lt;=&#39;z&#39;) || ((ch)&gt;=&#39;A&#39; &amp;&amp; (ch)&lt;=&#39;Z&#39;))</span>
</span><span class='line'><span class="cp">#define isSign(ch) (((ch)&lt;127 &amp;&amp; (ch)&gt;=0)?signindex[ch]:0)</span>
</span><span class='line'><span class="cp">#define ARRAY2D(VTYPE,X,Y)  (VTYPE **) malloc2d(X, Y, sizeof(VTYPE))</span>
</span><span class='line'><span class="cp">#define MATRIX(NAME,X,Y) matrix NAME;NAME.p=ARRAY2D(double,X,Y);NAME.x=X;NAME.y=Y;</span>
</span><span class='line'><span class="cp">#define FREE(X) free2d(&amp;X)</span>
</span><span class='line'>
</span><span class='line'><span class="n">map</span><span class="o">&lt;</span><span class="n">string</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="n">dic</span><span class="p">;</span>
</span><span class='line'><span class="n">map</span><span class="o">&lt;</span><span class="n">string</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="n">filedic</span><span class="p">[</span><span class="n">FILENUM</span><span class="p">];</span>
</span><span class='line'><span class="n">map</span><span class="o">&lt;</span><span class="n">string</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="n">stopword</span><span class="p">;</span>
</span><span class='line'><span class="n">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">diclist</span><span class="p">;</span>
</span><span class='line'><span class="kt">int</span> <span class="n">filewordnum</span><span class="p">[</span><span class="n">FILENUM</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'><span class="k">typedef</span> <span class="k">struct</span><span class="p">{</span>
</span><span class='line'>    <span class="kt">double</span> <span class="o">**</span><span class="n">p</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span> <span class="n">matrix</span><span class="p">;</span>
</span><span class='line'><span class="kt">int</span> <span class="n">signindex</span><span class="p">[</span><span class="mi">200</span><span class="p">]</span><span class="o">=</span><span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kt">int</span> <span class="nf">loadstopword</span><span class="p">()</span> <span class="c1">//加载停用词到stopword中</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">FILE</span> <span class="o">*</span><span class="n">fp</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">char</span> <span class="n">str</span><span class="p">[</span><span class="mi">32</span><span class="p">];</span>
</span><span class='line'>    <span class="n">stopword</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
</span><span class='line'>    <span class="n">fp</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="s">&quot;stopwords.txt&quot;</span><span class="p">,</span><span class="s">&quot;r&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">fp</span><span class="o">==</span><span class="nb">NULL</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Can&#39;t open stopword file.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Loading stopword...OK!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">while</span><span class="p">(</span><span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%s&quot;</span><span class="p">,</span><span class="n">str</span><span class="p">)</span><span class="o">!=</span><span class="n">EOF</span><span class="p">)</span>
</span><span class='line'>        <span class="n">stopword</span><span class="p">[</span><span class="n">str</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
</span><span class='line'>    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">int</span> <span class="nf">trimfile</span><span class="p">()</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">char</span> <span class="n">ch</span><span class="p">,</span><span class="n">name</span><span class="p">[</span><span class="mi">128</span><span class="p">],</span><span class="n">word</span><span class="p">[</span><span class="mi">128</span><span class="p">];</span>
</span><span class='line'>    <span class="kt">FILE</span> <span class="o">*</span><span class="n">fp1</span><span class="p">,</span><span class="o">*</span><span class="n">fp2</span><span class="p">;</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Create trim file waiting...</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">FILENUM</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">sprintf</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;data/file%d.txt&quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fp1</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;r&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span><span class="p">(</span><span class="n">fp1</span><span class="o">==</span><span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>            <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Open file %s error!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">name</span><span class="p">);</span>
</span><span class='line'>            <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">sprintf</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;trim%d.txt&quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fp2</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;w&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span><span class="p">(</span><span class="n">fp2</span><span class="o">==</span><span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>            <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Create file %s error!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">name</span><span class="p">);</span>
</span><span class='line'>            <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">ch</span><span class="o">=</span><span class="n">fgetc</span><span class="p">(</span><span class="n">fp1</span><span class="p">);</span>
</span><span class='line'>        <span class="k">while</span><span class="p">(</span><span class="n">ch</span><span class="o">!=</span><span class="n">EOF</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">isDigit</span><span class="p">(</span><span class="n">ch</span><span class="p">)</span> <span class="o">||</span> <span class="n">isAlpha</span><span class="p">(</span><span class="n">ch</span><span class="p">)</span> <span class="o">||</span> <span class="n">isSign</span><span class="p">(</span><span class="n">ch</span><span class="p">)))</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="n">fputc</span><span class="p">(</span><span class="n">ch</span><span class="p">,</span><span class="n">fp2</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="n">ch</span><span class="o">=</span><span class="n">fgetc</span><span class="p">(</span><span class="n">fp1</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">fclose</span><span class="p">(</span><span class="n">fp1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fclose</span><span class="p">(</span><span class="n">fp2</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">FILENUM</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">sprintf</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;trim%d.txt&quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fp1</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;r&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span><span class="p">(</span><span class="n">fp1</span><span class="o">==</span><span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>            <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Can&#39;t open file %s!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">name</span><span class="p">);</span>
</span><span class='line'>            <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">sprintf</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;file%d.txt&quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;%d &quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fp2</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;w&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span><span class="p">(</span><span class="n">fp2</span><span class="o">==</span><span class="nb">NULL</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Create file %s error!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">name</span><span class="p">);</span>
</span><span class='line'>            <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">while</span><span class="p">(</span><span class="n">fscanf</span><span class="p">(</span><span class="n">fp1</span><span class="p">,</span><span class="s">&quot;%s&quot;</span><span class="p">,</span><span class="n">word</span><span class="p">)</span><span class="o">!=</span><span class="n">EOF</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">stopword</span><span class="p">[</span><span class="n">word</span><span class="p">])</span>
</span><span class='line'>                <span class="n">fprintf</span><span class="p">(</span><span class="n">fp2</span><span class="p">,</span><span class="s">&quot;%s &quot;</span><span class="p">,</span><span class="n">word</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">fclose</span><span class="p">(</span><span class="n">fp1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fclose</span><span class="p">(</span><span class="n">fp2</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">system</span><span class="p">(</span><span class="s">&quot;del trim*.txt&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">initsign</span><span class="p">()</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">memset</span><span class="p">(</span><span class="n">signindex</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="k">sizeof</span><span class="p">(</span><span class="n">signindex</span><span class="p">));</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">33</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">34</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">37</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">38</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">40</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">41</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">42</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">43</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">44</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">45</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">46</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">47</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">58</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">59</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">60</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">61</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">62</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">63</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">91</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">93</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">95</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">123</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">125</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="n">signindex</span><span class="p">[</span><span class="mi">126</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span><span class="o">**</span> <span class="nf">malloc2d</span><span class="p">(</span><span class="kt">int</span> <span class="n">W</span><span class="p">,</span> <span class="kt">int</span> <span class="n">H</span><span class="p">,</span> <span class="kt">int</span> <span class="n">size</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">j</span><span class="p">,</span><span class="n">rowSize</span><span class="o">=</span><span class="n">W</span><span class="o">*</span><span class="n">size</span><span class="p">,</span><span class="n">colSize</span><span class="o">=</span><span class="n">H</span><span class="o">*</span><span class="k">sizeof</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">);</span>
</span><span class='line'>    <span class="kt">void</span> <span class="o">**</span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="kt">void</span> <span class="o">**</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="n">colSize</span><span class="o">+</span><span class="n">H</span><span class="o">*</span><span class="n">rowSize</span><span class="p">);</span>
</span><span class='line'>    <span class="kt">char</span> <span class="o">*</span><span class="n">begin</span><span class="o">=</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">a</span><span class="o">+</span><span class="n">colSize</span><span class="p">;</span>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">H</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="n">a</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">=</span><span class="n">begin</span><span class="o">+</span><span class="n">j</span><span class="o">*</span><span class="n">rowSize</span><span class="p">;</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">a</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">free2d</span><span class="p">(</span><span class="n">matrix</span> <span class="o">*</span><span class="n">M</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">free</span><span class="p">(</span><span class="n">M</span><span class="o">-&gt;</span><span class="n">p</span><span class="p">);</span>
</span><span class='line'>    <span class="n">M</span><span class="o">-&gt;</span><span class="n">p</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'>    <span class="n">M</span><span class="o">-&gt;</span><span class="n">x</span><span class="o">=</span><span class="n">M</span><span class="o">-&gt;</span><span class="n">y</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">double</span> <span class="nf">SIM</span><span class="p">(</span><span class="n">matrix</span> <span class="n">A</span><span class="p">,</span><span class="n">matrix</span> <span class="n">B</span><span class="p">,</span><span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="kt">int</span> <span class="n">j</span><span class="p">)</span> <span class="c1">//计算余弦距离</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">m</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">double</span> <span class="n">molecule</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span><span class="n">denominatorA</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span><span class="n">denominatorB</span><span class="o">=</span><span class="mf">0.0</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">y</span><span class="o">!=</span><span class="n">B</span><span class="p">.</span><span class="n">y</span> <span class="o">||</span> <span class="n">i</span><span class="o">&gt;=</span><span class="n">A</span><span class="p">.</span><span class="n">x</span> <span class="o">||</span> <span class="n">j</span><span class="o">&gt;=</span><span class="n">B</span><span class="p">.</span><span class="n">x</span><span class="p">)</span>
</span><span class='line'>        <span class="k">return</span> <span class="o">-</span><span class="mf">1.0</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">m</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">m</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">y</span><span class="p">;</span><span class="n">m</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">molecule</span><span class="o">+=</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">m</span><span class="p">][</span><span class="n">i</span><span class="p">]</span><span class="o">*</span><span class="n">B</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">m</span><span class="p">][</span><span class="n">j</span><span class="p">]);</span>
</span><span class='line'>        <span class="n">denominatorA</span><span class="o">+=</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">m</span><span class="p">][</span><span class="n">i</span><span class="p">]</span><span class="o">*</span><span class="n">A</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">m</span><span class="p">][</span><span class="n">i</span><span class="p">]);</span>
</span><span class='line'>        <span class="n">denominatorB</span><span class="o">+=</span><span class="p">(</span><span class="n">B</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">m</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">*</span><span class="n">B</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">m</span><span class="p">][</span><span class="n">j</span><span class="p">]);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">denominatorA</span><span class="o">=</span><span class="n">sqrt</span><span class="p">(</span><span class="n">denominatorA</span><span class="o">*</span><span class="n">denominatorB</span><span class="p">);</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">molecule</span><span class="o">/</span><span class="n">denominatorA</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">MUL</span><span class="p">(</span><span class="n">matrix</span> <span class="n">A</span><span class="p">,</span><span class="n">matrix</span> <span class="n">B</span><span class="p">,</span><span class="n">matrix</span> <span class="o">*</span><span class="n">C</span><span class="p">)</span> <span class="c1">//矩阵相乘</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">k</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">double</span> <span class="n">sum</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">x</span><span class="o">!=</span><span class="n">B</span><span class="p">.</span><span class="n">y</span><span class="p">)</span>
</span><span class='line'>        <span class="k">return</span><span class="p">;</span>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">y</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">B</span><span class="p">.</span><span class="n">x</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">sum</span><span class="o">=</span><span class="mf">0.0</span><span class="p">;</span>
</span><span class='line'>            <span class="k">for</span><span class="p">(</span><span class="n">k</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">k</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">x</span><span class="p">;</span><span class="n">k</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>                <span class="n">sum</span><span class="o">+=</span><span class="n">A</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">]</span><span class="o">*</span><span class="n">B</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">k</span><span class="p">][</span><span class="n">j</span><span class="p">];</span>
</span><span class='line'>            <span class="n">C</span><span class="o">-&gt;</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">=</span><span class="n">sum</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">disprint</span><span class="p">(</span><span class="kt">char</span> <span class="n">name</span><span class="p">[</span><span class="mi">128</span><span class="p">],</span><span class="n">matrix</span> <span class="n">m</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">k</span><span class="p">,</span><span class="n">maxindex</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">double</span> <span class="n">classes</span><span class="p">[</span><span class="mi">5</span><span class="p">],</span><span class="n">max</span><span class="o">=-</span><span class="mf">1.0</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">char</span> <span class="n">CLASS</span><span class="p">[</span><span class="mi">5</span><span class="p">][</span><span class="mi">32</span><span class="p">]</span><span class="o">=</span><span class="p">{</span><span class="s">&quot;环境&quot;</span><span class="p">,</span><span class="s">&quot;教育&quot;</span><span class="p">,</span><span class="s">&quot;经济&quot;</span><span class="p">,</span><span class="s">&quot;政治&quot;</span><span class="p">,</span><span class="s">&quot;体育&quot;</span><span class="p">};</span>
</span><span class='line'>    <span class="kt">FILE</span> <span class="o">*</span><span class="n">fp</span><span class="p">;</span>
</span><span class='line'>    <span class="n">fp</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;w&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">fprintf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%d %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">m</span><span class="p">.</span><span class="n">x</span><span class="p">,</span><span class="n">m</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">打印分类表 waiting...</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">FILENUM</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">max</span><span class="o">=-</span><span class="mf">1.0</span><span class="p">;</span>
</span><span class='line'>        <span class="n">maxindex</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'>        <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'>        <span class="n">k</span><span class="o">=</span><span class="n">j</span><span class="o">+</span><span class="mi">10</span><span class="p">;</span>
</span><span class='line'>        <span class="k">while</span><span class="p">(</span><span class="n">k</span><span class="o">&lt;=</span><span class="n">FILENUM</span><span class="p">){</span>
</span><span class='line'>            <span class="kt">double</span> <span class="n">avg</span><span class="o">=</span><span class="mf">0.0</span><span class="p">;</span>
</span><span class='line'>            <span class="k">while</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="n">avg</span><span class="o">=</span><span class="n">avg</span><span class="o">+</span><span class="n">m</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span>
</span><span class='line'>                <span class="n">j</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>                <span class="k">if</span><span class="p">(</span><span class="n">j</span><span class="o">==</span><span class="n">k</span><span class="p">)</span><span class="k">break</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="k">if</span><span class="p">(</span><span class="n">avg</span><span class="o">/</span><span class="mf">10.0</span><span class="o">&gt;</span><span class="n">max</span><span class="p">){</span>
</span><span class='line'>                <span class="n">maxindex</span><span class="o">=</span><span class="n">j</span><span class="o">/</span><span class="mi">10</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>                <span class="n">max</span><span class="o">=</span><span class="n">avg</span><span class="o">/</span><span class="mf">10.0</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="n">classes</span><span class="p">[</span><span class="n">j</span><span class="o">/</span><span class="mi">10</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="n">avg</span><span class="o">/</span><span class="mf">10.0</span><span class="p">;</span>
</span><span class='line'>            <span class="n">k</span><span class="o">=</span><span class="n">j</span><span class="o">+</span><span class="mi">10</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">fprintf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;File%2d.txt  &quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">k</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">k</span><span class="o">&lt;</span><span class="mi">5</span><span class="p">;</span><span class="n">k</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span><span class="p">(</span><span class="n">k</span><span class="o">==</span><span class="n">maxindex</span><span class="p">){</span>
</span><span class='line'>                <span class="n">fprintf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;</span><span class="se">\t</span><span class="s">|%s|&quot;</span><span class="p">,</span><span class="n">CLASS</span><span class="p">[</span><span class="n">k</span><span class="p">]);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="k">else</span><span class="p">{</span>
</span><span class='line'>                <span class="n">fprintf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;</span><span class="se">\t</span><span class="s"> %s &quot;</span><span class="p">,</span><span class="n">CLASS</span><span class="p">[</span><span class="n">k</span><span class="p">]);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">fprintf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">int</span> <span class="nf">processingdata</span><span class="p">()</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">FILE</span> <span class="o">*</span><span class="n">fp</span><span class="p">,</span><span class="o">*</span><span class="n">fpv</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">char</span> <span class="n">name</span><span class="p">[</span><span class="mi">128</span><span class="p">],</span><span class="n">word</span><span class="p">[</span><span class="mi">128</span><span class="p">];</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">wordnum</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">initsign</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">loadstopword</span><span class="p">())</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">trimfile</span><span class="p">())</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">fp</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="s">&quot;T_word.txt&quot;</span><span class="p">,</span><span class="s">&quot;r&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">fp</span><span class="o">==</span><span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Can&#39;t open file T_word.txt!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%d&quot;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">wordnum</span><span class="p">);</span>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">wordnum</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">){</span>
</span><span class='line'>        <span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%s&quot;</span><span class="p">,</span><span class="n">word</span><span class="p">);</span>
</span><span class='line'>        <span class="n">dic</span><span class="p">[</span><span class="n">word</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>        <span class="n">diclist</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">word</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">fpv</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="s">&quot;dis_v.txt&quot;</span><span class="p">,</span><span class="s">&quot;w&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">fpv</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Create dis_v.txt file error!&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">fprintf</span><span class="p">(</span><span class="n">fpv</span><span class="p">,</span><span class="s">&quot;%d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">FILENUM</span><span class="p">);</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Processing data file ...</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">FILENUM</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="c1">//按顺序打开文件，统计单词 </span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">filedic</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">clear</span><span class="p">();</span>
</span><span class='line'>        <span class="n">sprintf</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;file%d.txt&quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;%d &quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fp</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="s">&quot;r&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span><span class="p">(</span><span class="n">fp</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>            <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Processing data file %d error!&quot;</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>            <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">filewordnum</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'>        <span class="k">while</span><span class="p">(</span><span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%s&quot;</span><span class="p">,</span><span class="n">word</span><span class="p">)</span> <span class="o">!=</span> <span class="n">EOF</span><span class="p">)</span> <span class="c1">//循环查找该文件内所有单词</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span><span class="p">(</span><span class="n">dic</span><span class="p">[</span><span class="n">word</span><span class="p">])</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="k">if</span><span class="p">(</span><span class="n">filedic</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">word</span><span class="p">])</span>
</span><span class='line'>                    <span class="n">filedic</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">word</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>                <span class="k">else</span>
</span><span class='line'>                    <span class="n">filedic</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">word</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="k">else</span><span class="p">{</span>
</span><span class='line'>                <span class="n">filedic</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">word</span><span class="p">]</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="n">filewordnum</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">fprintf</span><span class="p">(</span><span class="n">fpv</span><span class="p">,</span><span class="s">&quot;%d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">wordnum</span><span class="p">);</span>
</span><span class='line'>        <span class="n">string</span> <span class="n">key</span><span class="p">;</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">thisfilewordnum</span><span class="p">;</span>
</span><span class='line'>        <span class="n">thisfilewordnum</span><span class="o">=</span><span class="n">filewordnum</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">wordnum</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">key</span><span class="o">=</span><span class="n">diclist</span><span class="p">[</span><span class="n">j</span><span class="p">];</span>
</span><span class='line'>            <span class="n">fprintf</span><span class="p">(</span><span class="n">fpv</span><span class="p">,</span><span class="s">&quot;%.8lf &quot;</span><span class="p">,(</span><span class="kt">double</span><span class="p">)</span><span class="n">filedic</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">key</span><span class="p">]</span><span class="o">/</span><span class="n">thisfilewordnum</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="n">fprintf</span><span class="p">(</span><span class="n">fpv</span><span class="p">,</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">fclose</span><span class="p">(</span><span class="n">fpv</span><span class="p">);</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">system</span><span class="p">(</span><span class="s">&quot;del file*.txt&quot;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">argv</span><span class="p">[])</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">FILE</span> <span class="o">*</span><span class="n">fp</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">;</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;共%d篇文章需要分类 waiting...</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">FILENUM</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">processingdata</span><span class="p">())</span> <span class="c1">//generate dis_v.txt</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">fp</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="s">&quot;T_eigenvector.txt&quot;</span><span class="p">,</span><span class="s">&quot;r&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">fp</span><span class="o">==</span><span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Can&#39;t open file T_eigenvector.txt!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%d %d&quot;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">x</span><span class="p">,</span><span class="o">&amp;</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>    <span class="n">MATRIX</span><span class="p">(</span><span class="n">EV</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">y</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">x</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>            <span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%lf&quot;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">EV</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]);</span>
</span><span class='line'>    <span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>    <span class="n">fp</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="s">&quot;T_B.txt&quot;</span><span class="p">,</span><span class="s">&quot;r&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">fp</span><span class="o">==</span><span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Can&#39;t open file T_B.txt!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%d %d&quot;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">x</span><span class="p">,</span><span class="o">&amp;</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>    <span class="n">MATRIX</span><span class="p">(</span><span class="n">TB</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">y</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">x</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>            <span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%lf&quot;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">TB</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]);</span>
</span><span class='line'>    <span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">fp</span><span class="o">=</span><span class="n">fopen</span><span class="p">(</span><span class="s">&quot;dis_v.txt&quot;</span><span class="p">,</span><span class="s">&quot;r&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">fp</span><span class="o">==</span><span class="nb">NULL</span><span class="p">){</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Can&#39;t open file dis_v.txt!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="n">system</span><span class="p">(</span><span class="s">&quot;pause&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%d&quot;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">x</span><span class="p">);</span>
</span><span class='line'>    <span class="n">MATRIX</span><span class="p">(</span><span class="n">X</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="n">TB</span><span class="p">.</span><span class="n">x</span><span class="p">);</span>
</span><span class='line'>    <span class="n">MATRIX</span><span class="p">(</span><span class="n">XX</span><span class="p">,</span><span class="n">X</span><span class="p">.</span><span class="n">x</span><span class="p">,</span><span class="n">TB</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>    <span class="n">MATRIX</span><span class="p">(</span><span class="n">DIS</span><span class="p">,</span><span class="n">FILENUM</span><span class="p">,</span><span class="n">FILENUM</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;计算距离 waiting...</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="n">FILENUM</span><span class="p">);</span>
</span><span class='line'>    <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">FILENUM</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">printf</span><span class="p">(</span><span class="s">&quot;%d &quot;</span><span class="p">,</span><span class="n">i</span><span class="p">);</span>
</span><span class='line'>        <span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%d&quot;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">x</span><span class="p">);</span>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">x</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">fscanf</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span><span class="s">&quot;%lf&quot;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">X</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="mi">0</span><span class="p">]);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">MUL</span><span class="p">(</span><span class="n">TB</span><span class="p">,</span><span class="n">X</span><span class="p">,</span><span class="o">&amp;</span><span class="n">XX</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">FILENUM</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">DIS</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">=</span><span class="n">SIM</span><span class="p">(</span><span class="n">XX</span><span class="p">,</span><span class="n">EV</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="n">j</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
</span><span class='line'>    <span class="n">system</span><span class="p">(</span><span class="s">&quot;del dis_v.txt&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">disprint</span><span class="p">(</span><span class="s">&quot;分类表.txt&quot;</span><span class="p">,</span><span class="n">DIS</span><span class="p">);</span>
</span><span class='line'>    <span class="n">FREE</span><span class="p">(</span><span class="n">DIS</span><span class="p">);</span>
</span><span class='line'>    <span class="n">FREE</span><span class="p">(</span><span class="n">EV</span><span class="p">);</span>
</span><span class='line'>    <span class="n">FREE</span><span class="p">(</span><span class="n">TB</span><span class="p">);</span>
</span><span class='line'>    <span class="n">FREE</span><span class="p">(</span><span class="n">X</span><span class="p">);</span>
</span><span class='line'>    <span class="n">FREE</span><span class="p">(</span><span class="n">XX</span><span class="p">);</span>
</span><span class='line'>    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>这样通过上面的程序我们就实现了最后的分类部分。下面是一次试验结果R=80 IterateNum=80。</p>

<pre><code>50 50
file 1.txt |环境| 教育 经济 政治 体育 
file 2.txt |环境| 教育 经济 政治 体育 
file 3.txt |环境| 教育 经济 政治 体育 
file 4.txt |环境| 教育 经济 政治 体育 
file 5.txt |环境| 教育 经济 政治 体育 
file 6.txt |环境| 教育 经济 政治 体育 
file 7.txt |环境| 教育 经济 政治 体育 
file 8.txt |环境| 教育 经济 政治 体育 
file 9.txt |环境| 教育 经济 政治 体育 
file10.txt |环境| 教育 经济 政治 体育 
file11.txt 环境 |教育| 经济 政治 体育 
file12.txt 环境 |教育| 经济 政治 体育 
file13.txt 环境 |教育| 经济 政治 体育 
file14.txt 环境 |教育| 经济 政治 体育 
file15.txt 环境 |教育| 经济 政治 体育 
file16.txt 环境 |教育| 经济 政治 体育 
file17.txt 环境 |教育| 经济 政治 体育 
file18.txt 环境 |教育| 经济 政治 体育 
file19.txt 环境 |教育| 经济 政治 体育 
file20.txt 环境 |教育| 经济 政治 体育 
file21.txt 环境 教育 |经济| 政治 体育 
file22.txt 环境 教育 |经济| 政治 体育 
file23.txt 环境 教育 |经济| 政治 体育 
file24.txt 环境 教育 |经济| 政治 体育 
file25.txt 环境 教育 |经济| 政治 体育 
file26.txt 环境 教育 经济 |政治| 体育 　&lt;-错误 
file27.txt 环境 教育 |经济| 政治 体育 
file28.txt 环境 教育 |经济| 政治 体育 
file29.txt 环境 教育 |经济| 政治 体育 
file30.txt 环境 教育 |经济| 政治 体育 
file31.txt 环境 教育 |经济| 政治 体育 
file32.txt 环境 教育 经济 政治 |体育|
file33.txt 环境 教育 经济 政治 |体育|
file34.txt 环境 教育 经济 政治 |体育|
file35.txt 环境 |教育| 经济 政治 体育 　&lt;-错误
file36.txt 环境 教育 经济 政治 |体育|
file37.txt 环境 教育 经济 政治 |体育|
file38.txt 环境 教育 经济 政治 |体育|
file39.txt 环境 教育 经济 政治 |体育|
file40.txt 环境 教育 经济 政治 |体育|
file41.txt 环境 教育 经济 |政治| 体育 
file42.txt 环境 教育 经济 |政治| 体育 
file43.txt 环境 教育 经济 |政治| 体育 
file44.txt 环境 教育 经济 |政治| 体育 
file45.txt 环境 教育 经济 |政治| 体育 
file46.txt 环境 教育 经济 |政治| 体育 
file47.txt 环境 教育 经济 |政治| 体育 
file48.txt 环境 教育 经济 |政治| 体育 
file49.txt 环境 教育 经济 |政治| 体育 
file50.txt 环境 教育 经济 |政治| 体育
</code></pre>

<p>可以看到有2篇分类错误。而经济类文章被分入政治类，体育类被分入教育类，也是可以理解的。这些话题有很多重合的地方。</p>
]]></content>
  </entry>
  
</feed>

