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

  <title><![CDATA[NOEY]]></title>
  <link href="http://fyou.me/atom.xml" rel="self"/>
  <link href="http://fyou.me/"/>
  <updated>2021-04-06T23:33:53-07:00</updated>
  <id>http://fyou.me/</id>
  <author>
    <name><![CDATA[Fan You]]></name>
    
  </author>

  
  <entry>
    <title type="html"><![CDATA[Dynamic Configuration System]]></title>
    <link href="http://fyou.me/blog/2019/05/04/dynamic-configuration-system/"/>
    <updated>2019-05-04T16:31:01-07:00</updated>
    <id>http://fyou.me/blog/2019/05/04/dynamic-configuration-system</id>
    <content type="html"><![CDATA[<h2>Index</h2>

<p>[TOC]</p>

<h2>Overview</h2>

<p>People all like generic software solutions, but as the scale of modern computer system grows larger, there are business logic cannot be avoided in order to handle real world complexity, Tax Rules, Accounting Treatment, Pricing/Deal calculation…</p>

<p>However, write business logic in code was never recommended because it will result in</p>

<ul>
<li>Hard-to-read code: code are not readable without huge documentation</li>
<li>Hard-to-test code: code will be tested against specific business and not able to test generically</li>
<li>Hard-to-change code: change won&rsquo;t be in effective until code deploy and also hard to revert</li>
<li>Hard-to-analyze data being processed: metrics can not be easily emitted and analyzed</li>
</ul>


<p>Here is where a dynamic configuration system (short for DCS) comes into play and we will see how it solves all these problems.</p>

<h2>Definition</h2>

<p>A DCS abstracts business logics layer from other layer in a readable and testable fashion during runtime, it should generally allow store, edit, update configuration as well as fetch them by certain conditions.</p>

<p>To put it simple, a client of a DCS should be able to</p>

<ul>
<li>PutConfig: upload configurations containing business logics</li>
<li>GetConfig: fetch configuration by filters</li>
<li>ProcessConfig: given inputs, DCS should match against stored config and produce results</li>
</ul>


<p><img src="http://fyou.me/images/flare.png" alt="flare" /></p>

<h2>Modeling</h2>

<p>Model of a configuration is tightly coupled with its functionality. Here we will only cover the essential functionality of the DCS where new result should be produce by given input and configuration.</p>

<p>e.g. input:</p>

<figure class='code'><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=''><span class='line'>input::
</span><span class='line'>{
</span><span class='line'>  attribute_1: value_1
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>and config:</p>

<figure class='code'><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=''><span class='line'>when attribute_1 == value_1, produce attribute_2 = value_2</span></code></pre></td></tr></table></div></figure>


<p>we should get:</p>

<figure class='code'><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=''><span class='line'>{
</span><span class='line'>  attribute_2: value_2
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>as a response. (The above syntax is <a href="http://amzn.github.io/ion-docs/">ion</a>)</p>

<p>Then its not hard to infer the very basic piece of a configuration is a compose of <code>condition</code> and <code>resulting value</code>. (Lets call it a derivation config) A naive model can look like this:</p>

<figure class='code'><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=''><span class='line'>{
</span><span class='line'>  condition: {
</span><span class='line'>    condition: cond,
</span><span class='line'>  },
</span><span class='line'>  value: {
</span><span class='line'>    value: v,
</span><span class='line'>  }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>and of course a group of derivation config can be written as:</p>

<figure class='code'><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>
</pre></td><td class='code'><pre><code class=''><span class='line'>{
</span><span class='line'>  conditions: {
</span><span class='line'>    condition_1: cond_1,
</span><span class='line'>    condition_2: cond_2,
</span><span class='line'>    ...
</span><span class='line'>  },
</span><span class='line'>  values: {
</span><span class='line'>    value_1: v_1,
</span><span class='line'>    value_2: v_2,
</span><span class='line'>    ...
</span><span class='line'>  }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>and multiple conditions are <code>and</code> relationship.</p>

<h2>Storage</h2>

<p>We have the model of derivation configuration now, but how can we store them? A traditional relational database and reference by id? or a document based storage reference by nature key? Let&rsquo;s take a look at both of them.</p>

<h4>Relational</h4>

<table>
<thead>
<tr>
<th> row_id </th>
<th style="text-align:left;"> config_element_id </th>
<th> config_data                          </th>
</tr>
</thead>
<tbody>
<tr>
<td> 1      </td>
<td style="text-align:left;"> 1                 </td>
<td> {conditions:{c_1, c_2}, value:{v_1}} </td>
</tr>
<tr>
<td> 2      </td>
<td style="text-align:left;"> 2                 </td>
<td> {conditions:{c_1,c_2}, value:{v_2}}  </td>
</tr>
<tr>
<td> &hellip;    </td>
<td style="text-align:left;"> &hellip;               </td>
<td> &hellip;                                  </td>
</tr>
</tbody>
</table>


<p>Benefit of this approach is:</p>

<ul>
<li>Strong consistency guarantee, much easier to work with in a multi-thread access environment</li>
</ul>


<p>Downside of this approach is: (All come from the persistence identifier!!)</p>

<ul>
<li>Extra cost to maintain additional id. id is required to be present everywhere in the DCS, big waste of space!!</li>
<li>Requires additional joins when querying, slow down the access speed!</li>
<li>Huge pain when it comes to editing the configuration, id has to be carefully handled and matched. (Simple diff doesn&rsquo;t work!)</li>
<li>Duplicate check can be hard, even though 2 config data is duplicate, we still treat them as different if they have different <code>config_element_id</code></li>
</ul>


<p><strong><em>Despite all those negative thing with relational database and persistence identifier, we will still be using this approach in this article because this has been proven to work in production environment.</em></strong></p>

<h4>NoSql</h4>

<table>
<thead>
<tr>
<th> key                                           </th>
<th> value </th>
</tr>
</thead>
<tbody>
<tr>
<td> condition_1:cond_1/condition_2:cond_2/value_1 </td>
<td> v_1   </td>
</tr>
<tr>
<td> condition_1:cond_1/condition_2:cond_2/value_2 </td>
<td> v_2   </td>
</tr>
<tr>
<td> &hellip;                                           </td>
<td> &hellip;   </td>
</tr>
</tbody>
</table>


<p>Benefit of this approach are:</p>

<ul>
<li>Simpler data model, no separate persistence identifier resulting in faster query speed</li>
</ul>


<p>Downside of this approach are:</p>

<ul>
<li>Hard to guarantee consistency (Especially in a distributed k-v store, manual distributed lock has to be implemented and maintained by DCS)</li>
</ul>


<h3>In-Memory</h3>

<p>It&rsquo;s expensive to always go back to database and retrieve information for every operation DCS needed. An in-memory representation of configuration is also needed.</p>

<p>The most nature way of storing key-value pair chain is <code>Trie</code>, and that&rsquo;s what we are going to use:</p>

<figure class='code'><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=''><span class='line'>           root
</span><span class='line'>            |
</span><span class='line'>       condition_1
</span><span class='line'>    /               \
</span><span class='line'> cond_3 {value_2: v2}   cond_1 {value_1: v_1}
</span><span class='line'>                      \
</span><span class='line'>                      condition_2           
</span><span class='line'>                        \
</span><span class='line'>                        cond_2 {value_1: v_1}</span></code></pre></td></tr></table></div></figure>


<p>Is a representation of</p>

<figure class='code'><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=''><span class='line'>{
</span><span class='line'>  conditions: {
</span><span class='line'>    condition_1: cond_3,
</span><span class='line'>    condition_2: cond_2,
</span><span class='line'>  },
</span><span class='line'>  values: {
</span><span class='line'>    value_1: v_1,
</span><span class='line'>  }
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>{
</span><span class='line'>  conditions: {
</span><span class='line'>    condition_1: cond_1,
</span><span class='line'>  },
</span><span class='line'>  values: {
</span><span class='line'>    value_2: v_2,
</span><span class='line'>  }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>Ordering of conditions in tree are guaranteed by alphabetic order by default and is &ldquo;configurable&rdquo; for different tenant of DCS.</p>

<p>To formalize a little bit, a config tree node can be represent as (in haskell)</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>
</pre></td><td class='code'><pre><code class='haskell'><span class='line'><span class="kr">data</span> <span class="kt">ConfigElement</span> <span class="ow">=</span> <span class="kt">ConfigElement</span>
</span><span class='line'><span class="kr">data</span> <span class="kt">Trie</span> <span class="ow">=</span> <span class="kt">Empty</span> <span class="o">|</span> <span class="kt">TrieNode</span> <span class="kt">String</span> <span class="kt">String</span> <span class="kt">ConfigElement</span> <span class="p">[</span><span class="kt">Trie</span><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>


<h4>S3, Caching and Interning</h4>

<p>In-memory Tree are also not directly built from RDS database because it can take minutes or even ours to load few entire tree, instead, every latest changes are truncated to a snapshot, serialized &amp; compressed to store in S3, 99% of the time, s3 are the storage used to fetch the configuration.</p>

<p>In-memory Tree in DCS are 1 tree per snapshot and that&rsquo;s what DCS keeps in the cache as well. If an entire tree is 4GB, and a typical DCS host has 60GB, only 15 snapshot can be stored at maximum! Request will have a huge latency spike if there is a cache miss. Here comes the idea of interning.</p>

<p>Interning (like String interning) is a technique to share repetitive in-memory object by putting them in a poll. This saves the memory of cache because multiple snapshot shares the same piece of subtree. And DCS calculates repetitive solely based on its hash key.</p>

<h4>Filtering and Indexing</h4>

<p>One interesting thing about fetch configuration in DCS is filter. DCS supports filter that allow access configuration from different dimension. e.g. by config_element_id, by status&hellip;</p>

<p>This means different indexing of the configuration has to be built, there are global index for indexing config_element_id (unique), there are per snapshot index for content key to perform duplicate lookup&hellip;</p>

<p>Keep adding index is also not scalable and interning won&rsquo;t help because different index will likely have very little to share. A DCS might consider using graph based DB to better help with indexing and querying tasks.</p>

<h4>Collapsing Configuration</h4>

<p>TODO</p>

<h4>Tenant Separation</h4>

<p>Muti-tenancy is an important consideration for DCS:</p>

<ul>
<li>Every config element and operation should be directly or indirectly associated with a tenant and they can be traced from the Database</li>
<li>Request for DCS should always pass in tenant, and ownership shall validate &amp; approve the request before any operation</li>
<li>Tenant should be able to easily manage their tenant configuration (e.g. ownership)</li>
</ul>


<h2>Authoring</h2>

<p>Authoring is the process of PutConfig into DCS. Enable parallel editing, bulk editing and consistency model will be the main focus of this section.</p>

<h4>Why not using Git?</h4>

<p>Git treat each line (or even character if you&rsquo;d like) as the lowest granular editing, however our DCS treat a single config element change as the lowest granular editing. They are fundamentally different!! Using git means we cannot use &ldquo;line changes&rdquo; of git directly as &ldquo;config element&rdquo; changes which immediately brings no benefit of using git! Plus, change can be very hard to validate before pushing, traditional pull/rebase/code review/push model won&rsquo;t work because DCS are changing so rapidly and concurrently!!</p>

<p>It then became very obvious that instead of hack Git and trying to put different pieces together, we are better off building our own authoring workflows.</p>

<h4>Change List</h4>

<p>Change list is a list of config elements that represents changes a person is trying to make in DCS.</p>

<table>
<thead>
<tr>
<th> change_list_id </th>
<th> change_list_revision </th>
<th> config_element_ids </th>
</tr>
</thead>
<tbody>
<tr>
<td> 1              </td>
<td> 1                    </td>
<td> [1,2,3]            </td>
</tr>
<tr>
<td> 1              </td>
<td> 2                    </td>
<td> [4]                </td>
</tr>
<tr>
<td> 2              </td>
<td> 1                    </td>
<td> [5,6]              </td>
</tr>
</tbody>
</table>


<h4>Work Request</h4>

<p>Work request act as a container for change list. A Work Request can have multiple change list but a Release can only have one work request. A typical WR contains 2 type of change list:</p>

<ul>
<li>1 Active change list: track changes that has not been released (all updates are write to this change list)</li>
<li>(0 ~ Many) Change Lists: all change list that has a release associated</li>
</ul>


<p>Concurrent update to work request are guaranteed by optimistic locking mechanism. A work request update always require both change list id and change list revision, if an older revision of change list is being submitted to the database, it will get rejected.</p>

<p>Initially work request were designed to have no revision associated, but as time goes, it became more obvious that add revision to work request can provide better audit history of work request updates and potential work request snapshot for running reproducible tests.</p>

<h4>Snapshot</h4>

<p>Snapshot is an important concept in DCS as it provides a way to represent an immutable set of configurations. This enable audit history of all configuration changes and also point-in-time recovery (or reproduce of the transaction). There are 3 types of Snapshot:</p>

<ul>
<li>Latest Snapshot (aka Base Snapshot or Release Snapshot): track the latest snapshot of a given domain</li>
<li>Config Update Snapshot: track a snapshot for change list</li>
<li>Merge Snapshot: containing multiple snapshots and a resolver containing instruction on how to merge them</li>
</ul>


<h4>Release Process</h4>

<p>An release process in DCS transform the latest state of DCS from 1 good snapshot to another. The soundness of change are guaranteed during the release process. A typical release workflow contains:</p>

<ul>
<li>Duplicate check</li>
<li>Reference check</li>
<li>Conflict check</li>
<li>Run test</li>
<li>Merge or Rebase</li>
</ul>


<p>A DCS cannot be successful without a well defined &amp; executed release process</p>

<h4>Concurrent release</h4>

<p>Config Update Snapshot -> Merge Snapshot -> Release Snapshot (Optimistic Locking)-> Latest Snapshot</p>

<p>concurrency were simply handled by an optimistic locking between building release snapshot and promote  as latest snapshot. latest snapshot table are updated by providing domain, release snapshot and latest snapshot. No duplicate revision can be created and that&rsquo;s guaranteed by database transactions which also guarantee the concurrent update to the DCS.</p>

<h4>Rebase</h4>

<p>There are a situation where 2 releases changing different config elements and trying to release at the same time, due to the fact that only 1 snapshot can be marked as live at given time, one of those 2 releases will always fail. However, there is a smarter way we can do to ensure both release success by rerun part of the release workflow (aka. Release process)</p>

<p>Whenever a release fail to be marked as succeeded, DCS will check the error type, if the type is OUT_OF_DATE_BASE_SNAPSHOT, which means there are other release succeeded before this release finishes, a rebase workflow can be kick off.</p>

<p>A rebase workflow essential bypass all the manual approval steps and only run the automated validation/testing steps and then trying to merge in again. However, it&rsquo;s possible for an unlucky release (starving) to keep running rebase workflow and maybe never succeed.</p>

<p>In order to solve release starving problem, preemptive rebase mechanism was introduced, all the pending rebase release will be put in a queue and every release will pre-computes changes that needs rebase base on release ahead of them in the queue. (A new RebaseAttemp object and Preemptive Rebase Workflow is introduced and replaced old rebase workflow)</p>

<h4>Partial release</h4>

<p>partial release is the feature of release only a subset config within the work request. It was originally implemented using a concept of Release Unit, which can be created from path of the tree. A request of partial release will have normal release object plus a specific Release Unit and DCS will figure out what need to be released.</p>

<p>Release Unit soon became a pain because it creates additional layer between change list and release/work request, its both programmatically difficult to figure out relationship between release unit, release and work request and un-intuitive for end user to create a correct Release Unit.</p>

<p>Release Unit based partial release was then deprecated by partial release via raw tree where release request will contain a tree that explicitly describing what should be released.</p>

<h4>Tree Operation</h4>

<h6>Merge</h6>

<p>Merge is a multiple tree operator which can be applied to 2 or more trees. Tree Merger folds the tree one by one and it first creates a conflict tree out of merging trees and then use resolver to transform them back into a normal tree, resolver is required by Tree Merger and sample resolvers are:</p>

<ul>
<li>last_one_wins: just use the last node seen</li>
<li>optimistic_locking: ensure right node (CE) must have larger revision than left node, otherwise merge will fail and this is the only resolver that might fail. This is also the default resolver used in release process.</li>
<li>latest_revision: use the latest dated_released_config_revision</li>
</ul>


<h6>Conflict Resolution</h6>

<p>Conflict happens all the time during release due to optimistic_locking resolver and simultaneously modification of the same config. Conflict Resolution mechanism provides a way for user to get the conflict tree in their release and select side of the tree, manually resolve the conflict and resume the release.</p>

<p>DCS did this by deleting conflicted configs and adding a new config back as user selected. However, this did introduced an interesting bug (and caused a COE). Because the way DCS are adding new configs instead of re-using existing ones to actually &ldquo;resolve&rdquo; the conflict, duplicate configs can easily be added. Someone actually took advantage of this bug and duplicated an entire namespace multiple times!!</p>

<p>This was later fixed by adding duplicate check across the platform but removing existing duplicate is very hard and still on going.</p>

<h6>Diff</h6>

<p>Diff is a dual tree operator which can only be applied to 2 trees. Tree Differ perform a transformation from 2 StandardTree to 1 DiffTree where each node is of type DiffNode and contains a left and right.</p>

<p>Diff tree can be transform to StandardTree again by traversal the tree and select left or right. In fact, config update snapshot should was produce by selection all right side of a Diff tree.</p>

<h4>Testing</h4>

<p>Test cases are in/out files that can be executed against certain snapshot, they are defined &amp; authored the same way as other configuration in DCS but in a separate namespace.</p>

<p>Testing will be done in a custom test suit which will take care of getting test configuration, convert it to java test cases and then start a in-memory DCS (processing engine) to process test cases.</p>

<p>We faced few performance issue where test run are getting extensively slow after sometime. Since we know  testing are CPU-intensive calculation, mostly the focus on optimization were done one CPU. However, it turns out with the increase in test case size, JVM is running out of heap. A lot of CPU cycle was wasted on busy GC. Simple increasing heap size improved the testing time to be 10x faster. (<a href="https://gceasy.io/">gceasy.io</a> was the tool helped a lot)</p>

<h3>Ownership</h3>

<p>Too low granular to use.</p>

<h2>Processing</h2>

<p>I wrote a very basic <a href="https://gist.github.com/Noeyfan/a9f58e2a447e8ed7773c87b6e0400723">haskell program</a> demonstrating how processing against tree works. It basically has a main process function where it loop through each record then try to derive attributes/record. Newly derived record will be directly append to original record list (so the function is not pure and it relies on IonList implementation to work correctly)</p>

<h4>Best Match</h4>

<h4>Execution Context</h4>

<h4>Namespace</h4>

<h2>Analytics</h2>

<p>TODO</p>

<h2>Future</h2>

<p>DSL and DCS</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[322. Coin Change and Classic DP]]></title>
    <link href="http://fyou.me/blog/2019/03/23/322-coin-change-and-classic-dp/"/>
    <updated>2019-03-23T17:35:31-07:00</updated>
    <id>http://fyou.me/blog/2019/03/23/322-coin-change-and-classic-dp</id>
    <content type="html"><![CDATA[<p>这题是一道经典dp题，最初在写这题的时候由于使用了backtracking，逻辑混乱不堪，想了一下区分back tracking和dfs的题目：</p>

<ul>
<li>back tracking: 需要列出所有的combination</li>
<li>dfs: 只需要一个最优解</li>
</ul>


<h4>最直观解法 dfs + memorization (slow but polynomial time)</h4>

<p>没什么好说的就是搜索加memorization.</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">coinChange</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">coins</span><span class="p">,</span> <span class="kt">int</span> <span class="n">amount</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="n">cache</span><span class="p">;</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">result</span> <span class="o">=</span> <span class="n">imp</span><span class="p">(</span><span class="n">coins</span><span class="p">,</span> <span class="n">amount</span><span class="p">,</span> <span class="n">cache</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">result</span> <span class="o">==</span> <span class="n">INT_MAX</span> <span class="o">?</span> <span class="o">-</span><span class="mi">1</span> <span class="o">:</span> <span class="n">result</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">imp</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">coins</span><span class="p">,</span> <span class="kt">int</span> <span class="n">remaining</span><span class="p">,</span> <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">cache</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">remaining</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">remaining</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="n">INT_MAX</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">cache</span><span class="p">.</span><span class="n">count</span><span class="p">(</span><span class="n">remaining</span><span class="p">))</span> <span class="k">return</span> <span class="n">cache</span><span class="p">[</span><span class="n">remaining</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>        <span class="kt">int</span> <span class="n">resultMin</span> <span class="o">=</span> <span class="n">INT_MAX</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">coins</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="kt">int</span> <span class="n">curMin</span> <span class="o">=</span> <span class="n">imp</span><span class="p">(</span><span class="n">coins</span><span class="p">,</span> <span class="n">remaining</span><span class="o">-</span><span class="n">coins</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">cache</span><span class="p">);</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">curMin</span> <span class="o">==</span> <span class="n">INT_MAX</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>  <span class="c1">// handle overflow</span>
</span><span class='line'>            <span class="n">resultMin</span> <span class="o">=</span> <span class="n">min</span><span class="p">(</span><span class="n">curMin</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">resultMin</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">cache</span><span class="p">[</span><span class="n">remaining</span><span class="p">]</span> <span class="o">=</span> <span class="n">resultMin</span><span class="p">;</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">resultMin</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>


<h4>最优解法 dp (O(A * N))</h4>

<p>子问题其实由dfs的解法很容易发现，<code>dp[i] = min(dp[i], dp[i-c] + 1)</code>, c在这里意味着coins里的任何一个。翻译过来就是对于每一个amount的最优解就是当前存下的值或者是拿coins里的某一个c之前的最优值+1。</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='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">coinChange</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">coins</span><span class="p">,</span> <span class="kt">int</span> <span class="n">amount</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">dp</span><span class="p">(</span><span class="n">amount</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">amount</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>  <span class="c1">// use amount+1 to prevent IN_MAX overflow.</span>
</span><span class='line'>        <span class="n">dp</span><span class="p">[</span><span class="mi">0</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">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="n">amount</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</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">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">coins</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">j</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">if</span> <span class="p">(</span><span class="n">coins</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                    <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">min</span><span class="p">(</span><span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="n">coins</span><span class="p">[</span><span class="n">j</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 class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="n">dp</span><span class="p">[</span><span class="n">amount</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">amount</span> <span class="o">?</span> <span class="o">-</span><span class="mi">1</span> <span class="o">:</span> <span class="n">dp</span><span class="p">[</span><span class="n">amount</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>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[621. Task Scheduler with Gaps]]></title>
    <link href="http://fyou.me/blog/2019/03/17/task-scheduler-with-gaps/"/>
    <updated>2019-03-17T17:53:38-07:00</updated>
    <id>http://fyou.me/blog/2019/03/17/task-scheduler-with-gaps</id>
    <content type="html"><![CDATA[<p><a href="https://leetcode.com/problems/task-scheduler/">https://leetcode.com/problems/task-scheduler/</a></p>

<p><a href="https://leetcode.com/problems/rearrange-string-k-distance-apart/">https://leetcode.com/problems/rearrange-string-k-distance-apart/</a></p>

<p>与一般的Scheduling问题不同，这题要求每个task之间最少间隔<code>x</code> gaps.</p>

<p>做法是priority_queue + greedy (未证明)，以&#8221;AAABBC&#8221;，x=3为例，greedy的过程大致为，从frequency最高的元素开始，依次填空</p>

<ol>
<li><code>A__A__A__</code></li>
<li><code>AB_AB_A__</code></li>
<li><code>ABCAB_A__</code> (注意trailing idle time是不需要的)</li>
</ol>


<p>所以最终的结果是<code>ABCAB_A</code>= <code>7</code></p>

<p>Implementation 复杂度为 <code>O(nlogn)</code> 应为每个元素都会被插入pq一次，这题有<code>O(n)</code>的<a href="https://leetcode.com/problems/task-scheduler/discuss/104500/Java-O(n">解法</a>-time-O(1)-space-1-pass-no-sorting-solution-with-detailed-explanation)</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='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">leastInterval</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">char</span><span class="o">&gt;&amp;</span> <span class="n">tasks</span><span class="p">,</span> <span class="kt">int</span> <span class="n">n</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">char</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="n">taskCounts</span><span class="p">;</span>
</span><span class='line'>        <span class="n">priority_queue</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">taskQ</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>          <span class="c1">// O(t) count</span>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="nl">t</span> <span class="p">:</span> <span class="n">tasks</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="o">++</span><span class="n">taskCounts</span><span class="p">[</span><span class="n">t</span><span class="p">];</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>          <span class="c1">// O(tlogt) insert</span>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="p">[</span><span class="n">t</span><span class="p">,</span> <span class="n">freq</span><span class="p">]</span><span class="o">:</span> <span class="n">taskCounts</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">taskQ</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">freq</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">cycle</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="o">!</span><span class="n">taskQ</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">remainingTasks</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>            <span class="kt">int</span> <span class="n">idle</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>            <span class="kt">int</span> <span class="n">gaps</span> <span class="o">=</span> <span class="n">n</span><span class="p">;</span>
</span><span class='line'>              <span class="c1">// note while (--i) and while (i--) executes different times</span>
</span><span class='line'>              <span class="c1">// * while (--i) i-1 times</span>
</span><span class='line'>              <span class="c1">// * while (i--) i   times</span>
</span><span class='line'>            <span class="k">while</span> <span class="p">(</span><span class="n">gaps</span><span class="o">--</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">)</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">taskQ</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>                    <span class="n">remainingTasks</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">taskQ</span><span class="p">.</span><span class="n">top</span><span class="p">());</span>
</span><span class='line'>                    <span class="n">taskQ</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span>
</span><span class='line'>                    <span class="o">++</span><span class="n">cycle</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="o">++</span><span class="n">idle</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="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="nl">tf</span> <span class="p">:</span> <span class="n">remainingTasks</span><span class="p">)</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">tf</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                    <span class="n">taskQ</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">tf</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="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">taskQ</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>                <span class="c1">// to avoid trailing idle time</span>
</span><span class='line'>                <span class="n">cycle</span> <span class="o">+=</span> <span class="n">idle</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="k">return</span> <span class="n">cycle</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>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[324.Wiggle Sort II and Dutch National Flag Problem]]></title>
    <link href="http://fyou.me/blog/2019/02/28/324-dot-wiggle-sort-ii-and-dutch-national-flag-problem/"/>
    <updated>2019-02-28T12:16:37-08:00</updated>
    <id>http://fyou.me/blog/2019/02/28/324-dot-wiggle-sort-ii-and-dutch-national-flag-problem</id>
    <content type="html"><![CDATA[<p>一种特殊排序，排完以后要满足奇数位大于左右，偶数位小于左右。</p>

<p><code>nums[0] &lt; nums[1] &gt; nums[2] &lt; nums[3] &gt; nums[4]...</code></p>

<h5>解法一 O(nlogn) time, O(n) space</h5>

<p>将原数组拷贝然后排序，最后从拷贝交叉插入原数组。</p>

<p>值得注意的点在于 <code>j = (n+1)/2</code>的选取，原因是当数组为奇数的时候，选取靠后的index可以避免<code>m</code> underflow.</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">void</span> <span class="n">wiggleSort</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">nums</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">nums</span><span class="p">;</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="n">nums</span><span class="p">.</span><span class="n">size</span><span class="p">(),</span> <span class="n">m</span> <span class="o">=</span> <span class="p">(</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="n">k</span> <span class="o">=</span> <span class="n">n</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">sort</span><span class="p">(</span><span class="n">tmp</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">tmp</span><span class="p">.</span><span class="n">end</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="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</span> <span class="o">&amp;</span> <span class="mi">1</span> <span class="o">?</span> <span class="n">tmp</span><span class="p">[</span><span class="o">--</span><span class="n">k</span><span class="p">]</span> <span class="o">:</span> <span class="n">tmp</span><span class="p">[</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="p">}</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<h5>解法二 O(n) time, O(n) space</h5>

<p>其实为了得到交叉排序的数组并不需要sort整个数组，只需要将数组一分为二 (按照median 做 partition)，然后再做交叉插入</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">void</span> <span class="n">wiggleSort</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">nums</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">nums</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="n">nums</span><span class="p">.</span><span class="n">size</span><span class="p">(),</span> <span class="n">m</span> <span class="o">=</span> <span class="p">(</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">;</span>
</span><span class='line'>        <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">copy</span> <span class="o">=</span> <span class="n">nums</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// find median</span>
</span><span class='line'>        <span class="n">nth_element</span><span class="p">(</span><span class="n">nums</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">nums</span><span class="p">.</span><span class="n">begin</span><span class="p">()</span> <span class="o">+</span> <span class="n">m</span><span class="p">,</span> <span class="n">nums</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">mid</span> <span class="o">=</span> <span class="n">nums</span><span class="p">[</span><span class="n">m</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">threeWay</span><span class="p">(</span><span class="n">copy</span><span class="p">,</span> <span class="n">mid</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// if odd pick from right partition</span>
</span><span class='line'>        <span class="c1">// if even pick from left partition</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">nums</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</span> <span class="o">&amp;</span> <span class="mi">1</span> <span class="o">?</span> <span class="n">copy</span><span class="p">[</span><span class="o">--</span><span class="n">n</span><span class="p">]</span> <span class="o">:</span> <span class="n">copy</span><span class="p">[</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="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// https://en.wikipedia.org/wiki/Dutch_national_flag_problem</span>
</span><span class='line'>    <span class="kt">void</span> <span class="n">threeWay</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">A</span><span class="p">,</span> <span class="kt">int</span> <span class="n">mid</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <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">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">k</span> <span class="o">=</span> <span class="n">A</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</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">j</span> <span class="o">&lt;=</span> <span class="n">k</span><span class="p">)</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">j</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">mid</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">swap</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">]);</span>
</span><span class='line'>                <span class="n">i</span><span class="o">++</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 class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">mid</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">swap</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="n">k</span><span class="p">]);</span>
</span><span class='line'>                <span class="n">k</span><span class="o">--</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="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="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>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[269. Alien Dictionary and Topological Sort]]></title>
    <link href="http://fyou.me/blog/2019/02/08/269-alien-dictionary-and-topological-sort/"/>
    <updated>2019-02-08T23:42:37-08:00</updated>
    <id>http://fyou.me/blog/2019/02/08/269-alien-dictionary-and-topological-sort</id>
    <content type="html"><![CDATA[<p>好久没碰到过拓扑排序的题目了，今天突然写到，花了4个小时 :( 这题的难点在于，找到它和拓扑排序的关系，以及如何构建graph.</p>

<h5>如何构建graph</h5>

<p>一开始想的有些复杂，其实就是两成对，找到第一个不相同的pair of char，即为graph的一条边</p>

<h5>拓扑排序</h5>

<p>拓扑排序适用于：</p>

<ul>
<li>多src和dependency的排序</li>
<li>找graph里是否有环</li>
</ul>


<p>这题正好需要这两点，拓扑排序首先将没有incoming edge的点加入queue中，当queue不为空时，一直循环并update queue里所有点的neighbor的 incoming edge count，如果update之后 count == 0则加入queue中。</p>

<p>如果有环的话那么环中的每个node的incoming edge都永远不会是0，所有最后只要比较一下结果的size是不是包含了所有node，就可以知道有没有环了。</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="n">string</span> <span class="n">mergeOrders</span><span class="p">(</span>
</span><span class='line'>        <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">char</span><span class="p">,</span> <span class="n">unordered_set</span><span class="o">&lt;</span><span class="kt">char</span><span class="o">&gt;&gt;&amp;</span> <span class="n">g</span><span class="p">,</span>
</span><span class='line'>        <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">char</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">cnt</span>
</span><span class='line'>    <span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">queue</span><span class="o">&lt;</span><span class="kt">char</span><span class="o">&gt;</span> <span class="n">q</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">ch</span><span class="p">,</span> <span class="n">c</span><span class="p">]</span> <span class="o">:</span> <span class="n">cnt</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">c</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">q</span><span class="p">.</span><span class="n">push</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="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">string</span> <span class="n">ret</span> <span class="o">=</span> <span class="s">&quot;&quot;</span><span class="p">;</span>
</span><span class='line'>        <span class="k">while</span><span class="p">(</span><span class="o">!</span><span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>            <span class="kt">char</span> <span class="n">c</span> <span class="o">=</span> <span class="n">q</span><span class="p">.</span><span class="n">front</span><span class="p">();</span>
</span><span class='line'>            <span class="n">q</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>            <span class="n">ret</span> <span class="o">+=</span> <span class="n">c</span><span class="p">;</span>
</span><span class='line'>            <span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="nl">e</span> <span class="p">:</span> <span class="n">g</span><span class="p">[</span><span class="n">c</span><span class="p">])</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">cnt</span><span class="p">[</span><span class="n">e</span><span class="p">]</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">cnt</span><span class="p">[</span><span class="n">e</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">e</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="k">if</span> <span class="p">(</span><span class="n">ret</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">!=</span> <span class="n">cnt</span><span class="p">.</span><span class="n">size</span><span class="p">())</span> <span class="k">return</span> <span class="s">&quot;&quot;</span><span class="p">;</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">string</span> <span class="n">alienOrder</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;&amp;</span> <span class="n">words</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">char</span><span class="p">,</span> <span class="n">unordered_set</span><span class="o">&lt;</span><span class="kt">char</span><span class="o">&gt;&gt;</span> <span class="n">g</span><span class="p">;</span>
</span><span class='line'>        <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">char</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="n">cnt</span><span class="p">;</span>
</span><span class='line'>
</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">words</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</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">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">words</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">j</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">cnt</span><span class="p">[</span><span class="n">words</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="mi">0</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="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">words</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">string</span><span class="o">&amp;</span> <span class="n">cur</span> <span class="o">=</span> <span class="n">words</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span><span class='line'>            <span class="n">string</span><span class="o">&amp;</span> <span class="n">next</span> <span class="o">=</span> <span class="n">words</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><span class='line'>            <span class="kt">int</span> <span class="n">limit</span> <span class="o">=</span> <span class="n">min</span><span class="p">(</span><span class="n">cur</span><span class="p">.</span><span class="n">size</span><span class="p">(),</span> <span class="n">next</span><span class="p">.</span><span class="n">size</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">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">limit</span><span class="p">;</span> <span class="o">++</span><span class="n">j</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">if</span> <span class="p">(</span><span class="n">cur</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">!=</span> <span class="n">next</span><span class="p">[</span><span class="n">j</span><span class="p">])</span> <span class="p">{</span>
</span><span class='line'>                    <span class="k">if</span> <span class="p">(</span><span class="n">g</span><span class="p">[</span><span class="n">cur</span><span class="p">[</span><span class="n">j</span><span class="p">]].</span><span class="n">find</span><span class="p">(</span><span class="n">next</span><span class="p">[</span><span class="n">j</span><span class="p">])</span> <span class="o">==</span> <span class="n">g</span><span class="p">[</span><span class="n">cur</span><span class="p">[</span><span class="n">j</span><span class="p">]].</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>                        <span class="n">g</span><span class="p">[</span><span class="n">cur</span><span class="p">[</span><span class="n">j</span><span class="p">]].</span><span class="n">insert</span><span class="p">(</span><span class="n">next</span><span class="p">[</span><span class="n">j</span><span class="p">]);</span>
</span><span class='line'>                        <span class="n">cnt</span><span class="p">[</span><span class="n">next</span><span class="p">[</span><span class="n">j</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">break</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="k">return</span> <span class="n">mergeOrders</span><span class="p">(</span><span class="n">g</span><span class="p">,</span> <span class="n">cnt</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>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[787. Shortest Path with Constraint]]></title>
    <link href="http://fyou.me/blog/2019/02/02/787-shortest-path-with-constraint/"/>
    <updated>2019-02-02T13:08:21-08:00</updated>
    <id>http://fyou.me/blog/2019/02/02/787-shortest-path-with-constraint</id>
    <content type="html"><![CDATA[<p><a href="https://leetcode.com/problems/cheapest-flights-within-k-stops/">https://leetcode.com/problems/cheapest-flights-within-k-stops/</a></p>

<p>在Weighted DAG里找到src到dst的最短路，且中间经过的点不能超过K. <a href="https://github.com/Noeyfan/CodingPractice/blob/master/leetcode/cheapestFlightsWitinKStopsImproved.cc">Solution with Path Tracking</a></p>

<h5>Dijkstra, 使用priority_queue：</h5>

<p>跟Dijkstra 最短路的思想类似，从src开始，一直往pq里插入所有可能的path，然后greedy的每轮只拿最小的vertice继续往前走，直到找到dst.</p>

<p>由于必须同时满足:</p>

<ul>
<li>v.k >= -1</li>
<li>v.index == dst</li>
</ul>


<p>而且一直都用priority_queue找最小的，所以不存在early return的情况。</p>

<p>这个解法有很多的element会被repeatedly insert，memory usage大约到达了第二种解法的两倍! （因为priority_queue不支持decreaseKey operation，所以我们没办法in-place update已经有的key）</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">struct</span> <span class="n">V</span> <span class="p">{</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">dist</span><span class="p">,</span> <span class="n">index</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><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">findCheapestPriceDijk</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">,</span>
</span><span class='line'>                          <span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;&amp;</span> <span class="n">flights</span><span class="p">,</span>
</span><span class='line'>                          <span class="kt">int</span> <span class="n">src</span><span class="p">,</span> <span class="kt">int</span> <span class="n">dst</span><span class="p">,</span> <span class="kt">int</span> <span class="n">K</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="c1">// build graph</span>
</span><span class='line'>        <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">g</span><span class="p">;</span>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="nl">e</span> <span class="p">:</span> <span class="n">flights</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">g</span><span class="p">[</span><span class="n">e</span><span class="p">[</span><span class="mi">0</span><span class="p">]][</span><span class="n">e</span><span class="p">[</span><span class="mi">1</span><span class="p">]]</span> <span class="o">=</span> <span class="n">e</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span> <span class="c1">// from, to, weight</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// tracker</span>
</span><span class='line'>        <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">pathTo</span><span class="p">(</span><span class="n">n</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Dijkstra</span>
</span><span class='line'>        <span class="k">using</span> <span class="n">T</span> <span class="o">=</span> <span class="n">tuple</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span><span class="p">;</span>
</span><span class='line'>        <span class="n">priority_queue</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">greater</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span> <span class="n">pq</span><span class="p">;</span>  <span class="c1">// dis, k, cur</span>
</span><span class='line'>        <span class="n">pq</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="mi">0</span><span class="p">,</span> <span class="n">K</span><span class="p">,</span> <span class="n">src</span><span class="p">});</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">pq</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">auto</span> <span class="p">[</span><span class="n">dis</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">from</span><span class="p">]</span> <span class="o">=</span> <span class="n">pq</span><span class="p">.</span><span class="n">top</span><span class="p">();</span>
</span><span class='line'>            <span class="n">pq</span><span class="p">.</span><span class="n">pop</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">k</span> <span class="o">&lt;</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">from</span> <span class="o">==</span> <span class="n">dst</span><span class="p">)</span> <span class="k">return</span> <span class="n">dis</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>            <span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">to</span><span class="p">,</span> <span class="n">price</span><span class="p">]</span> <span class="o">:</span> <span class="n">g</span><span class="p">[</span><span class="n">from</span><span class="p">])</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">pq</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="n">price</span> <span class="o">+</span> <span class="n">dis</span><span class="p">,</span> <span class="n">k</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">to</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="k">return</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></code></pre></td></tr></table></div></figure>


<h5>SPFA, 使用queue:</h5>

<p>SFPA（其实就是BFS!）从src一直往dst找，每轮挪动1，同时一直keep track cheapest，distTo存在的意义就在于cache 已经visited过的vertice (optimize performance)。</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">findCheapestPrice</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;&amp;</span> <span class="n">flights</span><span class="p">,</span> <span class="kt">int</span> <span class="n">src</span><span class="p">,</span> <span class="kt">int</span> <span class="n">dst</span><span class="p">,</span> <span class="kt">int</span> <span class="n">K</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">cheapest</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">adj_list</span><span class="p">;</span>
</span><span class='line'>        <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">distTo</span><span class="p">(</span><span class="n">n</span><span class="p">);</span>
</span><span class='line'>        <span class="n">distTo</span><span class="p">[</span><span class="n">src</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="nl">flight</span> <span class="p">:</span> <span class="n">flights</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">adj_list</span><span class="p">[</span><span class="n">flight</span><span class="p">[</span><span class="mi">0</span><span class="p">]][</span><span class="n">flight</span><span class="p">[</span><span class="mi">1</span><span class="p">]]</span> <span class="o">=</span> <span class="n">flight</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// {index, price}</span>
</span><span class='line'>        <span class="n">queue</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">q</span><span class="p">;</span>
</span><span class='line'>        <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="n">src</span><span class="p">,</span> <span class="mi">0</span><span class="p">});</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">K</span> <span class="o">&gt;=</span> <span class="o">-</span><span class="mi">1</span> <span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="kt">int</span> <span class="n">size</span> <span class="o">=</span> <span class="n">q</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>
</span><span class='line'>            <span class="k">while</span> <span class="p">(</span><span class="n">size</span><span class="o">--</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>    <span class="c1">// concise</span>
</span><span class='line'>                <span class="k">auto</span> <span class="n">cur</span> <span class="o">=</span> <span class="n">q</span><span class="p">.</span><span class="n">front</span><span class="p">();</span>
</span><span class='line'>                <span class="kt">int</span> <span class="n">index</span> <span class="o">=</span> <span class="n">cur</span><span class="p">.</span><span class="n">first</span><span class="p">,</span> <span class="n">price</span> <span class="o">=</span> <span class="n">cur</span><span class="p">.</span><span class="n">second</span><span class="p">;</span>
</span><span class='line'>                <span class="n">q</span><span class="p">.</span><span class="n">pop</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">index</span> <span class="o">==</span> <span class="n">dst</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                    <span class="n">cheapest</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span> <span class="o">==</span> <span class="n">cheapest</span> <span class="o">?</span> <span class="nl">price</span> <span class="p">:</span> <span class="n">min</span><span class="p">(</span><span class="n">cheapest</span><span class="p">,</span> <span class="n">price</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="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="nl">e</span> <span class="p">:</span> <span class="n">adj_list</span><span class="p">[</span><span class="n">index</span><span class="p">])</span> <span class="p">{</span>
</span><span class='line'>                        <span class="k">if</span> <span class="p">(</span><span class="n">distTo</span><span class="p">[</span><span class="n">e</span><span class="p">.</span><span class="n">first</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">distTo</span><span class="p">[</span><span class="n">e</span><span class="p">.</span><span class="n">first</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">e</span><span class="p">.</span><span class="n">second</span> <span class="o">+</span> <span class="n">price</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                            <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="n">e</span><span class="p">.</span><span class="n">first</span><span class="p">,</span> <span class="n">price</span> <span class="o">+</span> <span class="n">e</span><span class="p">.</span><span class="n">second</span><span class="p">});</span>
</span><span class='line'>                            <span class="n">distTo</span><span class="p">[</span><span class="n">e</span><span class="p">.</span><span class="n">first</span><span class="p">]</span> <span class="o">=</span> <span class="n">price</span> <span class="o">+</span> <span class="n">e</span><span class="p">.</span><span class="n">second</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><span class='line'>            <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><span class='line'>        <span class="k">return</span> <span class="n">cheapest</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>


<h5>SPFA Rev2</h5>

<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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">findCheapestPrice</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">,</span>
</span><span class='line'>                          <span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;&amp;</span> <span class="n">flights</span><span class="p">,</span>
</span><span class='line'>                          <span class="kt">int</span> <span class="n">src</span><span class="p">,</span> <span class="kt">int</span> <span class="n">dst</span><span class="p">,</span> <span class="kt">int</span> <span class="n">K</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="c1">// build graph</span>
</span><span class='line'>        <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">g</span><span class="p">;</span>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="nl">e</span> <span class="p">:</span> <span class="n">flights</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">g</span><span class="p">[</span><span class="n">e</span><span class="p">[</span><span class="mi">0</span><span class="p">]][</span><span class="n">e</span><span class="p">[</span><span class="mi">1</span><span class="p">]]</span> <span class="o">=</span> <span class="n">e</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span> <span class="c1">// from, to, weight</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// SPFA</span>
</span><span class='line'>        <span class="c1">// setup</span>
</span><span class='line'>        <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">distTo</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">INT_MAX</span><span class="p">);</span>
</span><span class='line'>        <span class="c1">// vector&lt;char&gt; inQueue(n, false);  -&gt; optional optimization</span>
</span><span class='line'>        <span class="n">queue</span><span class="o">&lt;</span><span class="n">tuple</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">q</span><span class="p">;</span>   <span class="c1">// cur, K, acc</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// init</span>
</span><span class='line'>        <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="n">src</span><span class="p">,</span> <span class="n">K</span><span class="p">,</span> <span class="mi">0</span><span class="p">});</span>
</span><span class='line'>        <span class="c1">// inQueue[src] = true;</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">auto</span> <span class="p">[</span><span class="n">cur</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">acc</span><span class="p">]</span> <span class="o">=</span> <span class="n">q</span><span class="p">.</span><span class="n">front</span><span class="p">();</span>
</span><span class='line'>            <span class="n">q</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span>
</span><span class='line'>            <span class="c1">// inQueue[src] = false;</span>
</span><span class='line'>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">k</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>  <span class="c1">// k stop, k+1 edges</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><span class='line'>            <span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">to</span><span class="p">,</span> <span class="n">weight</span><span class="p">]</span> <span class="o">:</span> <span class="n">g</span><span class="p">[</span><span class="n">cur</span><span class="p">])</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">if</span> <span class="p">(</span><span class="n">distTo</span><span class="p">[</span><span class="n">to</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">acc</span> <span class="o">+</span> <span class="n">weight</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                    <span class="n">distTo</span><span class="p">[</span><span class="n">to</span><span class="p">]</span> <span class="o">=</span> <span class="n">acc</span> <span class="o">+</span> <span class="n">weight</span><span class="p">;</span>
</span><span class='line'>                    <span class="c1">// if (!inQueue[to]) {</span>
</span><span class='line'>                        <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="n">to</span><span class="p">,</span> <span class="n">k</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">acc</span> <span class="o">+</span> <span class="n">weight</span><span class="p">});</span>
</span><span class='line'>                    <span class="c1">// }</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="k">return</span> <span class="n">distTo</span><span class="p">[</span><span class="n">dst</span><span class="p">]</span> <span class="o">==</span> <span class="n">INT_MAX</span> <span class="o">?</span> <span class="o">-</span><span class="mi">1</span> <span class="o">:</span> <span class="n">distTo</span><span class="p">[</span><span class="n">dst</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>


<h4>Floyd （复杂度高 O(n<sup>3</sup>)）</h4>

<p>基于动态规划的做法。</p>

<h4>Dijkstra（不能处理负环和负边）</h4>

<p>复杂度为<code>O(E*logV)</code></p>

<p>适合dense 和 sparse graph</p>

<p>从这里让我想到了implement 一下Dijkstra。其实跟解法1确实非常相似，但是也有同样的问题就是priority_queue没办法in-place update key。</p>

<p>还有一点不一样的是，Dijkstra没有K的限制，所以可以keep track两个东西:</p>

<ul>
<li>distTo</li>
<li>edgeTo</li>
</ul>


<p>然后在插入的时候只有最优解的时候才插入，其他时候直接跳过。（priority_queue的解法则不行，必须得插入所有的元素因为不到找到dst不知道哪个会是最短的）</p>

<p><a href="https://github.com/Noeyfan/noey_algos/blob/master/trivival/dijkstra.cc">Code</a></p>

<h4>Bellman-Ford （都能处理）</h4>

<p>复杂度为<code>O(E*V)</code></p>

<p>不适合dense graph</p>

<h4>SPFA（都能处理，但复杂度不稳定）</h4>

<p>复杂度为<code>O(E*V)</code> in worst case，但是average running time是 <code>O(E)</code>, 可惜并没有办法证明。</p>

<p>不适合dense graph</p>

<p><a href="https://github.com/Noeyfan/noey_algos/blob/master/trivival/spfa.cc">Code</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[774. Minimize Max Distance to Gas Station]]></title>
    <link href="http://fyou.me/blog/2018/05/09/minimize-max-distance-to-gas-station/"/>
    <updated>2018-05-09T22:25:00-07:00</updated>
    <id>http://fyou.me/blog/2018/05/09/minimize-max-distance-to-gas-station</id>
    <content type="html"><![CDATA[<p><a href="https://leetcode.com/problems/minimize-max-distance-to-gas-station">https://leetcode.com/problems/minimize-max-distance-to-gas-station</a></p>

<p>题意为：给定一些坐标点，表示坐标轴上已有的gas station，同时给定K，表示将要再插入K个gas station，插完以后使gas station之间的最大距离最小。</p>

<p>首先要从离散的点抽象出Interval的概念，其实已有的gas station就是一个个Interval。更为关键的是，这些interval可以视为永远不变，唯一变化的就是他们里边可能插入多少个K。基于这些interval，我们每次选择插入K的时候，只要选择插入当前所有interval中dist最大的那个，一直插入直到它比第二大小为止。插完所有的K，我们就得到了最后的解。</p>

<p>有了以上的理解，一个priority_queue就可以轻易的解决问题，用addK()去update当前interval里的value，然后把update完的top重新插回priority_queue。解法复杂度为O(klogn)</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='c++'><span class='line'><span class="k">struct</span> <span class="n">Interval</span> <span class="p">{</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">length</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">dist</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">Interval</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="p">)</span> <span class="o">:</span> <span class="n">length</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="mi">1</span><span class="p">),</span> <span class="n">dist</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="p">{}</span>
</span><span class='line'>
</span><span class='line'>    <span class="kt">bool</span> <span class="k">operator</span><span class="o">&lt;</span> <span class="p">(</span><span class="k">const</span> <span class="n">Interval</span><span class="o">&amp;</span> <span class="n">other</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">dist</span> <span class="o">&lt;</span> <span class="n">other</span><span class="p">.</span><span class="n">dist</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="n">addK</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">k</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>        <span class="n">dist</span> <span class="o">=</span> <span class="n">length</span><span class="o">/</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><span class='line'><span class="n">priority_queue</span><span class="o">&lt;</span><span class="n">Interval</span><span class="o">&gt;</span> <span class="n">buildQueue</span><span class="p">(</span><span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">v</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">ret</span><span class="p">(</span><span class="n">v</span><span class="p">.</span><span class="n">size</span><span class="p">());</span>
</span><span class='line'>    <span class="n">adjacent_difference</span><span class="p">(</span><span class="n">v</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">v</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="n">ret</span><span class="p">.</span><span class="n">begin</span><span class="p">());</span>
</span><span class='line'>    <span class="n">ret</span><span class="p">.</span><span class="n">erase</span><span class="p">(</span><span class="n">ret</span><span class="p">.</span><span class="n">begin</span><span class="p">());</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">priority_queue</span><span class="o">&lt;</span><span class="n">Interval</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ret</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">ret</span><span class="p">.</span><span class="n">end</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">minMaxDist</span><span class="p">(</span><span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">k</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">auto</span> <span class="n">pq</span> <span class="o">=</span> <span class="n">buildQueue</span><span class="p">(</span><span class="n">v</span><span class="p">);</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">maxDist</span> <span class="o">=</span> <span class="p">(</span><span class="n">v</span><span class="p">.</span><span class="n">back</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">.</span><span class="n">front</span><span class="p">())</span><span class="o">/</span><span class="p">(</span><span class="n">k</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// just for optimization</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">while</span><span class="p">(</span><span class="n">k</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">Interval</span> <span class="n">top</span> <span class="o">=</span> <span class="n">pq</span><span class="p">.</span><span class="n">top</span><span class="p">();</span>
</span><span class='line'>        <span class="n">pq</span><span class="p">.</span><span class="n">pop</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">pq</span><span class="p">.</span><span class="n">top</span><span class="p">()</span> <span class="o">&lt;</span> <span class="n">top</span> <span class="o">||</span> <span class="n">top</span><span class="p">.</span><span class="n">dist</span> <span class="o">&gt;</span> <span class="n">maxDist</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">top</span><span class="p">.</span><span class="n">addK</span><span class="p">();</span>
</span><span class='line'>            <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="n">pq</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">top</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="n">pq</span><span class="p">.</span><span class="n">top</span><span class="p">().</span><span class="n">dist</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>这题的难点在于正确理解题意并抽象化后找出算法，关键点在于：</p>

<ul>
<li>由于最早给定的gas station，随着K的插入，变化的并不是interval，而是每个interval内部的dist。</li>
<li>只关注最后的最大距离，并不关心每个gas station插在了哪里。</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[5. Kth Largest Element (快排之思)]]></title>
    <link href="http://fyou.me/blog/2018/04/01/5-kth-largest-element/"/>
    <updated>2018-04-01T14:23:39-07:00</updated>
    <id>http://fyou.me/blog/2018/04/01/5-kth-largest-element</id>
    <content type="html"><![CDATA[<p>起因源于我与同事争论，find kth largest element是O(n)的复杂度还是O(nlogn) 。我一直认为find kth largest element 最优解与快排同源，所以应该是O(nlogn)，事实证明我是错的，实际的解法是快速选择，O(n)最优情况，O(n<sup>2</sup>)最差情况。</p>

<p>解法都大同小异如下: （我取了中间点作为pivot，最简单的做法是取头或者尾作为pivot）</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">findKthLargest</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">nums</span><span class="p">,</span> <span class="kt">int</span> <span class="n">k</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">find</span><span class="p">(</span><span class="n">nums</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">nums</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">1</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><span class='line'>    <span class="kt">int</span> <span class="n">partition</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">nums</span><span class="p">,</span> <span class="kt">int</span> <span class="n">begin</span><span class="p">,</span> <span class="kt">int</span> <span class="n">end</span><span class="p">,</span> <span class="kt">int</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">if</span> <span class="p">(</span><span class="n">begin</span> <span class="o">&gt;</span> <span class="n">end</span><span class="p">)</span> <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="c1">// should not happend</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">p</span> <span class="o">=</span> <span class="n">nums</span><span class="p">[(</span><span class="n">end</span> <span class="o">+</span> <span class="n">begin</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">];</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">i</span>  <span class="o">=</span> <span class="n">begin</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="n">end</span><span class="p">;</span>
</span><span class='line'>        <span class="k">while</span><span class="p">(</span><span class="n">i</span> <span class="o">!=</span> <span class="n">j</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">nums</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">p</span><span class="p">)</span>
</span><span class='line'>            <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="p">}</span>
</span><span class='line'>            <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">p</span><span class="p">)</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <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">else</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="n">std</span><span class="o">::</span><span class="n">swap</span><span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">nums</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">nums</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">==</span> <span class="n">p</span><span class="p">)</span> <span class="n">i</span><span class="o">++</span><span class="p">;</span> <span class="c1">// edge case where after swap if nums[j] == p then we can&#39;t --j</span>
</span><span class='line'>                <span class="k">else</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="p">}</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">diff</span> <span class="o">=</span> <span class="n">end</span><span class="o">-</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="o">-</span><span class="n">k</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">diff</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="k">return</span> <span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">diff</span> <span class="o">&gt;</span> <span class="mi">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">find</span><span class="p">(</span><span class="n">nums</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="n">end</span><span class="p">,</span><span class="n">k</span><span class="p">);</span> <span class="c1">// i j are the same anyways</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="k">return</span> <span class="n">find</span><span class="p">(</span><span class="n">nums</span><span class="p">,</span><span class="n">begin</span><span class="p">,</span><span class="n">j</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="n">diff</span><span class="p">);</span> <span class="c1">// i j are the same anyways</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>关键在于复杂度的分析。</p>

<h4>快排：</h4>

<p>快排的(average)复杂度之所以为O(nlogn)，因为每次partition需要O(n)，</p>

<p><strong>最差情况：</strong>每次partition正好为<code>[]和[0..n]</code> ，也就是<code>T(n)=T(n-1)+T(0)+O(n) -&gt; T(n)=T(n-1)+O(n)-&gt; T(n)=O(n^2)</code></p>

<p><strong>最优情况：</strong>每次partition正好为<code>[0..n/2-1]和[n/2..n]</code> ，也就是<code>T(n)=2T(n/2)+O(n) -&gt; T(n)=O(nlogn)</code></p>

<p>同时也可以简单理解为最差需要partition O(n)次而最优只需要partition O(logn)次</p>

<h4><strong>快速选择：</strong></h4>

<p>快速选择的(average)复杂度之所以为O(n)，因为每次递归只需要partition整个array的一半，</p>

<p><strong>最差情况：</strong>依旧与快排类似，如果每次pivot都选择了最小或者最大，那么还是需要O(n<sup>2</sup>)去完成整个操作</p>

<p><strong>最优情况：</strong>如果pivot正好选择了中间值，那么<code>T(n)=T(n/2)+O(n) -&gt; T(n)=2O(n) -&gt; T(n)=O(n)</code></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[427. Generate Parentheses]]></title>
    <link href="http://fyou.me/blog/2018/03/28/427-generate-parentheses/"/>
    <updated>2018-03-28T00:05:47-07:00</updated>
    <id>http://fyou.me/blog/2018/03/28/427-generate-parentheses</id>
    <content type="html"><![CDATA[<p><a href="http://www.lintcode.com/en/problem/generate-parentheses/">http://www.lintcode.com/en/problem/generate-parentheses/</a></p>

<p>这道题给定n，然后输出所有长度为2n的valid parentheses.</p>

<p><strong>解法一：</strong></p>

<p>最简单的解法是枚举，用两个变量num_of_left, num_of_right去track还有多少个左括号和右括号可以使用。只要有左括号可以用就可以继续递归generate，但是只有可用右括号大于左括号时候才可以继续递归generate，防止&#8221;)(&ldquo;的情况。</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</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">generateParenthesis</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">)</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">ret</span><span class="p">;</span>
</span><span class='line'>        <span class="n">generate</span><span class="p">(</span><span class="n">ret</span><span class="p">,</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">n</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">ret</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="n">generate</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;&amp;</span> <span class="n">ret</span><span class="p">,</span>
</span><span class='line'>        <span class="n">string</span> <span class="n">s</span><span class="p">,</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">num_of_left</span><span class="p">,</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">num_of_right</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">num_of_left</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">num_of_right</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">ret</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">s</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><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">num_of_left</span> <span class="o">&gt;</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">generate</span><span class="p">(</span><span class="n">ret</span><span class="p">,</span> <span class="n">s</span><span class="o">+</span><span class="s">&quot;(&quot;</span><span class="p">,</span> <span class="n">num_of_left</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">num_of_right</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">num_of_right</span> <span class="o">&gt;</span> <span class="n">num_of_left</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">generate</span><span class="p">(</span><span class="n">ret</span><span class="p">,</span> <span class="n">s</span><span class="o">+</span><span class="s">&quot;)&quot;</span><span class="p">,</span> <span class="n">num_of_left</span><span class="p">,</span> <span class="n">num_of_right</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 class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>解法二：</strong></p>

<p>dp的思路 ，想求第f(n)，就是将&#8221;()&ldquo;加入f(n-1)的结果：</p>

<p>f(0): &ldquo;&rdquo;</p>

<p>f(1): &ldquo;(&#8220;f(0)&rdquo;)&#8221;</p>

<p>f(2): &ldquo;(&#8220;f(0)&rdquo;)&ldquo;f(1), &rdquo;(&ldquo;f(1)&rdquo;)&#8221;</p>

<p>f(3): &ldquo;(&#8220;f(0)&rdquo;)&ldquo;f(2), &rdquo;(&ldquo;f(1)&rdquo;)&ldquo;f(1), &rdquo;(&ldquo;f(2)&rdquo;)&#8221;</p>

<p>所以 f(n) = &ldquo;(&#8220;f(0)&rdquo;)&ldquo;f(n-1) , &rdquo;(&ldquo;f(1)&rdquo;)&ldquo;f(n-2) &rdquo;(&ldquo;f(2)&rdquo;)&ldquo;f(n-3) … &rdquo;(&ldquo;f(i)&rdquo;)&ldquo;f(n-1-i) … &rdquo;(f(n-1)&ldquo;)&rdquo;</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</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">generateParenthesis</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;&gt;</span> <span class="n">tmp</span> <span class="o">=</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">j</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;=</span> <span class="n">n</span><span class="p">;</span> <span class="o">++</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">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">vec</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">j</span><span class="p">;</span> <span class="o">++</span><span class="n">i</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="k">auto</span> <span class="nl">fst</span> <span class="p">:</span> <span class="n">tmp</span><span class="p">[</span><span class="n">i</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="k">auto</span> <span class="nl">snd</span> <span class="p">:</span> <span class="n">tmp</span><span class="p">[</span><span class="n">j</span><span class="o">-</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="p">{</span>
</span><span class='line'>                        <span class="n">vec</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="s">&quot;(&quot;</span><span class="o">+</span><span class="n">fst</span><span class="o">+</span><span class="s">&quot;)&quot;</span><span class="o">+</span><span class="n">snd</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="n">tmp</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">vec</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">tmp</span><span class="p">.</span><span class="n">back</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>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[919. Meeting Rooms II]]></title>
    <link href="http://fyou.me/blog/2018/03/21/919-meeting-rooms-ii/"/>
    <updated>2018-03-21T22:24:39-07:00</updated>
    <id>http://fyou.me/blog/2018/03/21/919-meeting-rooms-ii</id>
    <content type="html"><![CDATA[<p>考察Interval intersection, 一次遍历内解决问题和多维数组一直是我的弱项。</p>

<h4>920. <a href="http://www.lintcode.com/en/problem/meeting-rooms/">Meeting Rooms</a></h4>

<p>这道题给一个Interval list只考察Interval有无交集，所以从第二个element开始，只要test自己的start是否小于前一个Interval的end。(前提：List以Interval start sorted)</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='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">bool</span> <span class="n">canAttendMeetings</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">Interval</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">intervals</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">intervals</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">)</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
</span><span class='line'>        <span class="n">sort</span><span class="p">(</span>
</span><span class='line'>            <span class="n">intervals</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span>
</span><span class='line'>            <span class="n">intervals</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span>
</span><span class='line'>            <span class="p">[](</span><span class="k">const</span> <span class="n">Interval</span> <span class="o">&amp;</span><span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">Interval</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 class="k">return</span> <span class="n">a</span><span class="p">.</span><span class="n">start</span> <span class="o">&lt;</span> <span class="n">b</span><span class="p">.</span><span class="n">start</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="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">intervals</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</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">intervals</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">start</span> <span class="o">&lt;</span> <span class="n">intervals</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="n">end</span><span class="p">)</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">return</span> <span class="nb">true</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>


<h4>919. <a href="http://www.lintcode.com/en/problem/meeting-rooms-ii/">Meeting Rooms II</a></h4>

<p>这道题唯一的区别是要算出在同一时间点，有多少同时进行的meeting，得出需要多少个不同的meeting room。</p>

<p>我的初始想法是将每一个interval的时间点都存入hashmap，然后遍历一遍map，算出最大值。这个解法works，但是耗费了很多空间，大部分的时间点存在hashmap里都毫无意义，唯有start和end才是我们关注的，所以改进的解法是将start和end同时存进一个vector并mark上每个点是start还是end，然后sort这个vector，最后遍历一遍vector，start的点counter++，end的点counter&#8211;，同时track max value。</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">bool</span> <span class="n">START</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">bool</span> <span class="n">END</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="kt">int</span> <span class="nf">minMeetingRooms</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">Interval</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">intervals</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">vector</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">bool</span><span class="o">&gt;&gt;</span> <span class="n">vec</span><span class="p">;</span>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="nl">itv</span> <span class="p">:</span> <span class="n">intervals</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">vec</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">make_pair</span><span class="p">(</span><span class="n">itv</span><span class="p">.</span><span class="n">start</span><span class="p">,</span> <span class="n">START</span><span class="p">));</span>
</span><span class='line'>            <span class="n">vec</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">make_pair</span><span class="p">(</span><span class="n">itv</span><span class="p">.</span><span class="n">end</span><span class="p">,</span> <span class="n">END</span><span class="p">));</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">std</span><span class="o">::</span><span class="n">sort</span><span class="p">(</span><span class="n">vec</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">vec</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span>
</span><span class='line'>        <span class="p">[](</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">r</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">return</span> <span class="n">l</span><span class="p">.</span><span class="n">first</span> <span class="o">&lt;</span> <span class="n">r</span><span class="p">.</span><span class="n">first</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">rooms</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">current</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="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="nl">it</span> <span class="p">:</span> <span class="n">vec</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">it</span><span class="p">.</span><span class="n">second</span><span class="p">)</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="n">current</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">current</span><span class="o">--</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="n">rooms</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">max</span><span class="p">(</span><span class="n">rooms</span><span class="p">,</span> <span class="n">current</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="n">rooms</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>同时在网上看到了两个不错的解法。</p>

<h5>解法一：</h5>

<p>还是使用hashmap，但是只存start和end点的count，最后遍历map，然后sum所有start和end，并且track max value，最后max value就是结果。</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">minMeetingRooms</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">Interval</span><span class="o">&gt;&amp;</span> <span class="n">intervals</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="n">m</span><span class="p">;</span>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="nl">a</span> <span class="p">:</span> <span class="n">intervals</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="o">++</span><span class="n">m</span><span class="p">[</span><span class="n">a</span><span class="p">.</span><span class="n">start</span><span class="p">];</span>
</span><span class='line'>            <span class="o">--</span><span class="n">m</span><span class="p">[</span><span class="n">a</span><span class="p">.</span><span class="n">end</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">rooms</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">res</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="k">auto</span> <span class="nl">it</span> <span class="p">:</span> <span class="n">m</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">res</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="n">res</span><span class="p">,</span> <span class="n">rooms</span> <span class="o">+=</span> <span class="n">it</span><span class="p">.</span><span class="n">second</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">res</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>


<h5>解法二：</h5>

<p>使用最小堆去track离当前最近的会议结束的时间(last.end)，如果last.end &lt;= cur.start，就表示上一个会议已经结束，可以将其从heap里pop出去，这样我们动态的maintain了一个heap，heap的size就表示当前的会议一共要多少间会议室。</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">minMeetingRooms</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">Interval</span><span class="o">&gt;&amp;</span> <span class="n">intervals</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">sort</span><span class="p">(</span><span class="n">intervals</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">intervals</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="p">[](</span><span class="k">const</span> <span class="n">Interval</span> <span class="o">&amp;</span><span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">Interval</span> <span class="o">&amp;</span><span class="n">b</span><span class="p">){</span><span class="k">return</span> <span class="n">a</span><span class="p">.</span><span class="n">start</span> <span class="o">&lt;</span> <span class="n">b</span><span class="p">.</span><span class="n">start</span><span class="p">;});</span>
</span><span class='line'>        <span class="n">priority_queue</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">greater</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">q</span><span class="p">;</span>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="nl">a</span> <span class="p">:</span> <span class="n">intervals</span><span class="p">)</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">q</span><span class="p">.</span><span class="n">empty</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">q</span><span class="p">.</span><span class="n">top</span><span class="p">()</span> <span class="o">&lt;=</span> <span class="n">a</span><span class="p">.</span><span class="n">start</span><span class="p">)</span> <span class="n">q</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span>
</span><span class='line'>            <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">end</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">q</span><span class="p">.</span><span class="n">size</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>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[736. Parse Lisp Expression]]></title>
    <link href="http://fyou.me/blog/2018/03/11/736-parse-lisp-expression/"/>
    <updated>2018-03-11T21:46:05-07:00</updated>
    <id>http://fyou.me/blog/2018/03/11/736-parse-lisp-expression</id>
    <content type="html"><![CDATA[<p><a href="https://leetcode.com/problems/parse-lisp-expression/description/">https://leetcode.com/problems/parse-lisp-expression/description/</a></p>

<p>(很喜欢leetcode里的这个解法，故此记录一下，不太喜欢的是使用了deque存symbol table，如果直接用map作为递归参数会更好。)</p>

<p>解法用了top-down parsing，用getToken和++pos来consume token，优先处理add/mult的简单情况，然后处理let，逻辑清晰，值得学些。</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">Solution</span> <span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">evaluate</span><span class="p">(</span><span class="n">string</span> <span class="n">expression</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">scopes_</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">pos</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>        <span class="k">return</span> <span class="nf">eval</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">pos</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="k">private</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">eval</span><span class="p">(</span><span class="k">const</span> <span class="n">string</span><span class="o">&amp;</span> <span class="n">s</span><span class="p">,</span> <span class="kt">int</span><span class="o">&amp;</span> <span class="n">pos</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">scopes_</span><span class="p">.</span><span class="n">push_front</span><span class="p">(</span><span class="n">unordered_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="p">());</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">value</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// The return value of current expr</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span> <span class="o">==</span> <span class="sc">&#39;(&#39;</span><span class="p">)</span> <span class="o">++</span><span class="n">pos</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// command, variable or number</span>
</span><span class='line'>        <span class="k">const</span> <span class="n">string</span> <span class="n">token</span> <span class="o">=</span> <span class="n">getToken</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">pos</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">token</span> <span class="o">==</span> <span class="s">&quot;add&quot;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="kt">int</span> <span class="n">v1</span> <span class="o">=</span> <span class="n">eval</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="o">++</span><span class="n">pos</span><span class="p">);</span>
</span><span class='line'>            <span class="kt">int</span> <span class="n">v2</span> <span class="o">=</span> <span class="n">eval</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="o">++</span><span class="n">pos</span><span class="p">);</span>
</span><span class='line'>            <span class="n">value</span> <span class="o">=</span> <span class="n">v1</span> <span class="o">+</span> <span class="n">v2</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">token</span> <span class="o">==</span> <span class="s">&quot;mult&quot;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="kt">int</span> <span class="n">v1</span> <span class="o">=</span> <span class="n">eval</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="o">++</span><span class="n">pos</span><span class="p">);</span>
</span><span class='line'>            <span class="kt">int</span> <span class="n">v2</span> <span class="o">=</span> <span class="n">eval</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="o">++</span><span class="n">pos</span><span class="p">);</span>
</span><span class='line'>            <span class="n">value</span> <span class="o">=</span> <span class="n">v1</span> <span class="o">*</span> <span class="n">v2</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">token</span> <span class="o">==</span> <span class="s">&quot;let&quot;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">string</span> <span class="n">var</span><span class="p">;</span>
</span><span class='line'>            <span class="c1">// expecting &quot; var1 exp1 var2 exp2 ... last_expr)&quot;</span>
</span><span class='line'>            <span class="k">while</span> <span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">&#39;)&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="o">++</span><span class="n">pos</span><span class="p">;</span>
</span><span class='line'>                <span class="c1">// Must be last_expr</span>
</span><span class='line'>                <span class="k">if</span> <span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span> <span class="o">==</span> <span class="sc">&#39;(&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                    <span class="n">value</span> <span class="o">=</span> <span class="n">eval</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="o">++</span><span class="n">pos</span><span class="p">);</span>
</span><span class='line'>                    <span class="k">break</span><span class="p">;</span>
</span><span class='line'>                <span class="p">}</span>
</span><span class='line'>                <span class="c1">// Get a token, could be &quot;x&quot; or &quot;-12&quot; for last_expr</span>
</span><span class='line'>                <span class="n">var</span> <span class="o">=</span> <span class="n">getToken</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">pos</span><span class="p">);</span>
</span><span class='line'>                <span class="c1">// End of let, var is last_expr</span>
</span><span class='line'>                <span class="k">if</span> <span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span> <span class="o">==</span> <span class="sc">&#39;)&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                    <span class="k">if</span> <span class="p">(</span><span class="n">isalpha</span><span class="p">(</span><span class="n">var</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
</span><span class='line'>                        <span class="n">value</span> <span class="o">=</span> <span class="n">getValue</span><span class="p">(</span><span class="n">var</span><span class="p">);</span>
</span><span class='line'>                    <span class="k">else</span>
</span><span class='line'>                        <span class="n">value</span> <span class="o">=</span> <span class="n">stoi</span><span class="p">(</span><span class="n">var</span><span class="p">);</span>
</span><span class='line'>                    <span class="k">break</span><span class="p">;</span>
</span><span class='line'>                <span class="p">}</span>
</span><span class='line'>                <span class="c1">// x -12 -&gt; set x to -12 and store in the current scope and take it as the current return value</span>
</span><span class='line'>                <span class="n">value</span> <span class="o">=</span> <span class="n">scopes_</span><span class="p">.</span><span class="n">front</span><span class="p">()[</span><span class="n">var</span><span class="p">]</span> <span class="o">=</span> <span class="n">eval</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="o">++</span><span class="n">pos</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">isalpha</span><span class="p">(</span><span class="n">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">value</span> <span class="o">=</span> <span class="n">getValue</span><span class="p">(</span><span class="n">token</span><span class="p">);</span> <span class="c1">// symbol</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">value</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">stoi</span><span class="p">(</span><span class="n">token</span><span class="p">);</span> <span class="c1">// number</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">s</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span> <span class="o">==</span> <span class="sc">&#39;)&#39;</span><span class="p">)</span> <span class="o">++</span><span class="n">pos</span><span class="p">;</span>
</span><span class='line'>        <span class="n">scopes_</span><span class="p">.</span><span class="n">pop_front</span><span class="p">();</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">value</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">getValue</span><span class="p">(</span><span class="k">const</span> <span class="n">string</span><span class="o">&amp;</span> <span class="n">symbol</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="nl">scope</span> <span class="p">:</span> <span class="n">scopes_</span><span class="p">)</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">scope</span><span class="p">.</span><span class="n">count</span><span class="p">(</span><span class="n">symbol</span><span class="p">))</span> <span class="k">return</span> <span class="n">scope</span><span class="p">.</span><span class="n">at</span><span class="p">(</span><span class="n">symbol</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="c1">// Get a token from current pos.</span>
</span><span class='line'>    <span class="c1">// &quot;let x&quot; -&gt; &quot;let&quot;</span>
</span><span class='line'>    <span class="c1">// &quot;-12 (add x y)&quot; -&gt; &quot;-12&quot;</span>
</span><span class='line'>    <span class="n">string</span> <span class="n">getToken</span><span class="p">(</span><span class="k">const</span> <span class="n">string</span><span class="o">&amp;</span> <span class="n">s</span><span class="p">,</span> <span class="kt">int</span><span class="o">&amp;</span> <span class="n">pos</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">string</span> <span class="n">token</span><span class="p">;</span>
</span><span class='line'>        <span class="k">while</span> <span class="p">(</span><span class="n">pos</span> <span class="o">&lt;</span> <span class="n">s</span><span class="p">.</span><span class="n">length</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span> <span class="o">==</span> <span class="sc">&#39;)&#39;</span> <span class="o">||</span> <span class="n">s</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span> <span class="o">==</span> <span class="sc">&#39; &#39;</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
</span><span class='line'>            <span class="n">token</span> <span class="o">+=</span> <span class="n">s</span><span class="p">[</span><span class="n">pos</span><span class="o">++</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">token</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">deque</span><span class="o">&lt;</span><span class="n">unordered_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;&gt;</span> <span class="n">scopes_</span><span class="p">;</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[10. Regular Expression Matching]]></title>
    <link href="http://fyou.me/blog/2017/06/07/regex-matching/"/>
    <updated>2017-06-07T01:30:00-07:00</updated>
    <id>http://fyou.me/blog/2017/06/07/regex-matching</id>
    <content type="html"><![CDATA[<p>准备督促自己刷刷题／打打codejam，保持手感，记录一些难倒过自己的题目，从错误开始到正确思路，（也许）包括一些深入的拓展。</p>

<h4>题目</h4>

<p>第一题就从<a href="https://leetcode.com/problems/regular-expression-matching/">Regular Expression Matching</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="kt">bool</span> <span class="nf">isMatch</span><span class="p">(</span><span class="n">string</span> <span class="n">s</span><span class="p">,</span> <span class="n">string</span> <span class="n">regex</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<h4>思路</h4>

<p>超简化的Regular Expression Matching，通常只包含：<code>* . [a-Z]</code>几种元素，所以从简单入手分析所有可能的match情形:</p>

<ul>
<li><code>[a-Z]</code> 和 <code>[a-Z]</code>，属于exact match，只需要关注当前位置</li>
<li><code>[a-Z]</code> 和 <code>.</code>， 属于any match，与上种情况类似，但是<code>\0</code> 和 <code>.</code> 是不能match的</li>
<li><code>[a-Z]</code> 和 <code>([a-Z]|.)*</code>，属于repeat match, 也是这题的唯一难点，有两种情况，且可以用DFS暴力解决：

<ul>
<li><code>*</code> match >=1 次: <code>[a-Z]</code> match <code>[a-Z]|.</code>  &amp;&amp; <code>s+1</code> 也要match <code>regex</code></li>
<li><code>*</code> match 0 次: <code>s</code> match <code>regex+2</code></li>
</ul>
</li>
</ul>


<h4>曾犯错误</h4>

<p>之下都是我在面试或者写题中出现过的错误：</p>

<ul>
<li>与WildCardMatching混淆，认为一个for loop可以解决（非DP）</li>
<li>边界情况 <code>""</code> 与 <code>.*</code>的match</li>
<li>For loop 和DFS 在此处混用，逻辑不清（紧张？？？）</li>
<li>强行用c++ string 进DFS却又不想用index （<code>string::data() -&gt; const char*</code>）</li>
<li>没有处理<code>\0</code> 和 <code>.</code> 的情况</li>
</ul>


<p>不怕笑话，试着回忆一些面试写的丑逼代码：</p>

<h5>丑1:</h5>

<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='c++'><span class='line'><span class="kt">bool</span> <span class="nf">isMatch</span><span class="p">(</span><span class="n">string</span> <span class="n">s</span><span class="p">,</span> <span class="n">string</span> <span class="n">regex</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">empty</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">regex</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">r_i</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="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">s</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="n">regex</span><span class="p">[</span><span class="n">r_i</span><span class="p">])</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">isMatch</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">substr</span><span class="p">(</span><span class="n">i</span><span class="p">),</span> <span class="n">regex</span><span class="p">.</span><span class="n">substr</span><span class="p">(</span><span class="n">r_i</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">regex</span><span class="p">[</span><span class="n">r_i</span><span class="p">]</span> <span class="o">==</span> <span class="sc">&#39;*&#39;</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// should be regex[r_i+1] == &#39;*&#39;</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">isMatch</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">substr</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="n">regex</span><span class="p">.</span><span class="n">substr</span><span class="p">(</span><span class="n">r_i</span><span class="o">-</span><span class="mi">1</span><span class="p">))</span>
</span><span class='line'>        <span class="o">||</span> <span class="n">isMatch</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">substr</span><span class="p">(</span><span class="n">i</span><span class="p">),</span> <span class="n">regex</span><span class="p">.</span><span class="n">substr</span><span class="p">(</span><span class="n">r_i</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">if</span> <span class="p">(</span><span class="n">regex</span><span class="p">[</span><span class="n">r_i</span><span class="p">]</span> <span class="o">==</span> <span class="sc">&#39;.&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">isMatch</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">substr</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="n">regex</span><span class="p">.</span><span class="n">substr</span><span class="p">(</span><span class="n">r_i</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">return</span> <span class="nb">false</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h5>丑2：</h5>

<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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="kt">bool</span> <span class="nf">isMatch</span><span class="p">(</span><span class="n">string</span> <span class="n">s</span><span class="p">,</span> <span class="n">string</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">imp</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">data</span><span class="p">(),</span> <span class="n">p</span><span class="p">.</span><span class="n">data</span><span class="p">());</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">bool</span> <span class="nf">imp</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">c</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">p</span><span class="p">)</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">c</span> <span class="o">==</span> <span class="sc">&#39;\0&#39;</span> <span class="o">&amp;&amp;</span> <span class="o">*</span><span class="n">p</span> <span class="o">==</span> <span class="sc">&#39;\0&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="nb">true</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">p</span> <span class="o">==</span> <span class="sc">&#39;\0&#39;</span> <span class="o">||</span> <span class="o">*</span><span class="n">c</span> <span class="o">==</span> <span class="sc">&#39;\0&#39;</span><span class="p">)</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="c1">// ??? patching</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">p</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="sc">&#39;*&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">isMatch</span><span class="p">(</span><span class="n">c</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span> <span class="o">||</span> <span class="n">isMatch</span><span class="p">(</span><span class="n">c</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">p</span><span class="o">+</span><span class="mi">2</span><span class="p">);</span> <span class="c1">// should be || isMatch(c, p+2)</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">c</span> <span class="o">==</span> <span class="o">*</span><span class="n">p</span> <span class="o">||</span> <span class="o">*</span><span class="n">p</span> <span class="o">==</span> <span class="sc">&#39;.&#39;</span><span class="p">)</span> <span class="p">{</span>  <span class="c1">// &#39;\0&#39; and &#39;.&#39;</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">isMatch</span><span class="p">(</span><span class="n">c</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">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">return</span> <span class="nb">false</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h4>正确姿势</h4>

<h5>DFS</h5>

<p>算法清晰的情况下，DFS 解法基本等同于直接翻译：</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="kt">bool</span> <span class="nf">isMatch</span><span class="p">(</span><span class="n">string</span> <span class="n">s</span><span class="p">,</span> <span class="n">string</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">imp</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">data</span><span class="p">(),</span> <span class="n">p</span><span class="p">.</span><span class="n">data</span><span class="p">());</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">bool</span> <span class="nf">imp</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">c</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="c1">// only when regex reaches the end, *c check make sense</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="o">*</span><span class="n">p</span> <span class="o">==</span> <span class="sc">&#39;\0&#39;</span><span class="p">)</span> <span class="k">return</span> <span class="o">*</span><span class="n">c</span> <span class="o">==</span> <span class="sc">&#39;\0&#39;</span><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">p</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="sc">&#39;*&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span>
</span><span class='line'>          <span class="n">imp</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">p</span><span class="o">+</span><span class="mi">2</span><span class="p">)</span>
</span><span class='line'>          <span class="c1">// test if c is end of string then we can safely</span>
</span><span class='line'>          <span class="c1">// recursively call imp(c+1, p)</span>
</span><span class='line'>          <span class="o">||</span> <span class="p">((</span><span class="o">*</span><span class="n">p</span> <span class="o">==</span> <span class="o">*</span><span class="n">c</span> <span class="o">||</span> <span class="p">(</span><span class="o">*</span><span class="n">c</span> <span class="o">!=</span> <span class="sc">&#39;\0&#39;</span> <span class="o">&amp;&amp;</span> <span class="o">*</span><span class="n">p</span> <span class="o">==</span> <span class="sc">&#39;.&#39;</span><span class="p">))</span>
</span><span class='line'>                <span class="o">&amp;&amp;</span> <span class="n">imp</span><span class="p">(</span><span class="n">c</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">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="o">*</span><span class="n">c</span> <span class="o">==</span> <span class="o">*</span><span class="n">p</span> <span class="o">||</span> <span class="p">(</span><span class="o">*</span><span class="n">c</span> <span class="o">!=</span> <span class="sc">&#39;\0&#39;</span> <span class="o">&amp;&amp;</span> <span class="o">*</span><span class="n">p</span> <span class="o">==</span> <span class="sc">&#39;.&#39;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">imp</span><span class="p">(</span><span class="n">c</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">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">return</span> <span class="nb">false</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h5>DP</h5>

<p>DP的关键在于构建状态转移矩阵，而此处构建的方法为：令 <code>bool f[i][j]</code>为 <code>s[i-1]</code> match <code>p[j-1]</code> 的情况，然后写出 <code>f[i][j]</code> 与 <code>p[i-1]</code> <code>j[i-1]</code> 的关系，相同<strong>思路</strong>。</p>

<p>其中初始化<code>f[0][j]</code>要有讲究（也就是<code>empty string</code> 与 什么样的<code>regex</code>算matching）。</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="c1">// Copy from Leetcode</span>
</span><span class='line'><span class="kt">bool</span> <span class="nf">isMatch</span><span class="p">(</span><span class="n">string</span> <span class="n">s</span><span class="p">,</span> <span class="n">string</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="cm">/**</span>
</span><span class='line'><span class="cm">     * f[i][j]: if s[0..i-1] matches p[0..j-1]</span>
</span><span class='line'><span class="cm">     * if p[j - 1] != &#39;*&#39;</span>
</span><span class='line'><span class="cm">     *      f[i][j] = f[i - 1][j - 1] &amp;&amp; s[i - 1] == p[j - 1]</span>
</span><span class='line'><span class="cm">     * if p[j - 1] == &#39;*&#39;, denote p[j - 2] with x</span>
</span><span class='line'><span class="cm">     *      f[i][j] is true iff any of the following is true</span>
</span><span class='line'><span class="cm">     *      1) &quot;x*&quot; repeats 0 time and matches empty: f[i][j - 2]</span>
</span><span class='line'><span class="cm">     *      2) &quot;x*&quot; repeats &gt;= 1 times and matches &quot;x*x&quot;: s[i - 1] == x &amp;&amp; f[i - 1][j]</span>
</span><span class='line'><span class="cm">     * &#39;.&#39; matches any single character</span>
</span><span class='line'><span class="cm">     */</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">m</span> <span class="o">=</span> <span class="n">s</span><span class="p">.</span><span class="n">size</span><span class="p">(),</span> <span class="n">n</span> <span class="o">=</span> <span class="n">p</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>
</span><span class='line'>    <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;&gt;</span> <span class="n">f</span><span class="p">(</span><span class="n">m</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="p">(</span><span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">false</span><span class="p">));</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">f</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</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">1</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">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>        <span class="n">f</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
</span><span class='line'>    <span class="c1">// p[0.., j - 3, j - 2, j - 1] matches empty iff p[j - 1] is &#39;*&#39; </span>
</span><span class='line'>      <span class="c1">// and p[0..j - 3] matches empty</span>
</span><span class='line'>    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;=</span> <span class="n">n</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">f</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">j</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="sc">&#39;*&#39;</span> <span class="o">==</span> <span class="n">p</span><span class="p">[</span><span class="n">j</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">f</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">j</span> <span class="o">-</span> <span class="mi">2</span><span class="p">];</span>
</span><span class='line'>
</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">1</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">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="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;=</span> <span class="n">n</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">p</span><span class="p">[</span><span class="n">j</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">&#39;*&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">f</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">f</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="n">j</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="n">s</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="o">==</span> <span class="n">p</span><span class="p">[</span><span class="n">j</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
</span><span class='line'>                                              <span class="o">||</span> <span class="sc">&#39;.&#39;</span> <span class="o">==</span> <span class="n">p</span><span class="p">[</span><span class="n">j</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="c1">// p[0] cannot be &#39;*&#39; so no need to check &quot;j &gt; 1&quot; here</span>
</span><span class='line'>                <span class="n">f</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">f</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span> <span class="o">-</span> <span class="mi">2</span><span class="p">]</span> <span class="o">||</span> <span class="p">(</span><span class="n">s</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="o">==</span> <span class="n">p</span><span class="p">[</span><span class="n">j</span> <span class="o">-</span> <span class="mi">2</span><span class="p">]</span>
</span><span class='line'>                                          <span class="o">||</span> <span class="sc">&#39;.&#39;</span> <span class="o">==</span> <span class="n">p</span><span class="p">[</span><span class="n">j</span> <span class="o">-</span> <span class="mi">2</span><span class="p">])</span> <span class="o">&amp;&amp;</span> <span class="n">f</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="n">j</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">return</span> <span class="n">f</span><span class="p">[</span><span class="n">m</span><span class="p">][</span><span class="n">n</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h4>拓展</h4>

<ul>
<li>尝试用NFA解决真正的<code>regex</code>问题，尝试自己土制了一个小 <a href="https://github.com/Noeyfan/noey_algos/blob/master/noey_regex.h">regex lib</a>.</li>
<li>还有Tim的 <a href="https://gist.github.com/Noeyfan/1c60fa6555f6cdc50fd2f55d78aed8a9">compile time regex (no parsing)</a></li>
</ul>


<h4>相似题目</h4>

<p><code>// placeholder，将遇到的相似题目加入此处</code></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2015 小结]]></title>
    <link href="http://fyou.me/blog/2015/09/07/gsoc2015/"/>
    <updated>2015-09-07T00:02:53-04:00</updated>
    <id>http://fyou.me/blog/2015/09/07/gsoc2015</id>
    <content type="html"><![CDATA[<p>GSoC 2015 也算是结束了，期间学到了很多，也认识到了很多不足，拖延症患者拖到今天终于决定下笔记录下这一段经历，以便往后温习，吹逼之用。</p>

<h2>Extend shared_ptr to support arrays</h2>

<p>第一个Propose的项目是<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4335.html#memory.smartptr.shared">extend shared_ptr to support arrays</a>. 初始由于C＋＋技艺不精，甚至不知道shared_ptr是什么，所以先从shared_ptr的源码讲起吧。</p>

<h4>shared_ptr</h4>

<p>shared_ptr位于<code>libstdc++-v3/include/bits/shared_ptr.h</code>，这里的shared_ptr其实是对所有开放接口的一个封装，真正的实现在<code>shared_ptr_base.h</code>里。</p>

<p>找到__shared_ptr定义的private member，会发现只有两个东西</p>

<ol>
<li><em>Tp* </em>M_ptr;_                                                 // Contained Pointer</li>
<li>_<em>shared_count<_LP> </em>M_refcount;           // Reference counter</li>
</ol>


<p>shared_ptr的实现也就依赖这两个东西，一个raw pointer，另一个引用计数。有新的object使用raw pointer refcount++, 同样destructor调用一次refcount- -,如果refcount ＝＝ 0，那么就释放_M_ptr;</p>

<p>// 注（</p>

<p>一个裸指针被托管以后，任何想要使用这个指针的行为都得通过shared_ptr，否则UB</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="kt">int</span><span class="o">*</span> <span class="n">a</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
</span><span class='line'><span class="n">std</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">sp</span><span class="p">(</span><span class="n">a</span><span class="p">);</span>
</span><span class='line'><span class="c1">// int* b = a;</span>
</span><span class='line'><span class="c1">// std::shared_ptr sb(b); undefined behavior</span>
</span><span class='line'><span class="k">auto</span> <span class="n">sb</span> <span class="o">=</span> <span class="n">sp</span><span class="p">;</span> <span class="c1">// refcount+1</span>
</span></code></pre></td></tr></table></div></figure>


<p>）</p>

<p>说起来很简单，但是shared_ptr确实还是有不少坑。</p>

<h4>weak_ptr</h4>

<p>shared_ptr难免会出现这样的情况（cyclic reference），weak_ptr可以让持有执政却不增加引用计数。</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='c++'><span class='line'><span class="k">struct</span> <span class="n">A</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">std</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="n">ptr</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">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">std</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="n">x</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">make_shared</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span><span class="p">();</span>
</span><span class='line'>  <span class="n">std</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="n">y</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">make_shared</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">x</span><span class="o">-&gt;</span><span class="n">ptr</span> <span class="o">=</span> <span class="n">y</span><span class="p">;</span> <span class="c1">// not quite a cycle yet</span>
</span><span class='line'>  <span class="n">y</span><span class="o">-&gt;</span><span class="n">ptr</span> <span class="o">=</span> <span class="n">x</span><span class="p">;</span> <span class="c1">// now we got a cycle x keeps y alive and y keeps x alive</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>这样的情况，如果x 拿了一个指向y的weak_ptr就不存在这样的问题了。weak_ptr的用处很多，如<a href="http://stackoverflow.com/questions/12030650/when-is-stdweak-ptr-useful">cache</a>。</p>

<h4>enable_shared_from_this</h4>

<p>参见我在知乎的<a href="http://zhihu.com/question/30957800/answer/50181754?utm_campaign=webshare&amp;utm_source=weibo&amp;utm_medium=zhihu">答案</a>。用于在类内部拿取自身的shared_ptr。</p>

<p>在每次构造一个<code>shared_ptr&lt;T&gt;</code>时都会检查T是否继承自enable_shared_from_this，如果是，会在自身的private member里保存一个weak_ptr，以后用shared_from_this()拿取自身的shared_ptr.</p>

<h4>support for arrays</h4>

<p>来到正题，shared_ptr虽然好用，但是对数组的支持并不好，也就是说，可以用但是基本没用。需要传入自己的destructor以保证资源正确释放。</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="cp">#include &lt;memory&gt;</span>
</span><span class='line'>
</span><span class='line'> <span class="kt">int</span> <span class="nf">main</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">array</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
</span><span class='line'>   <span class="n">std</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span><span class="o">&gt;</span> <span class="n">p</span><span class="p">(</span><span class="o">&amp;</span><span class="n">array</span><span class="p">,</span> <span class="p">[](</span><span class="kt">int</span><span class="o">*</span><span class="n">p</span> <span class="p">){</span><span class="k">delete</span> <span class="n">p</span><span class="p">;});</span>
</span><span class='line'> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>为了将数组支持加入shared_ptr且保证之前使用shared_ptr的代码不出错，决定使用一个新的tag</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">_Tp</span><span class="o">&gt;</span>
</span><span class='line'>  <span class="k">struct</span> <span class="n">__libfund_v1</span> <span class="p">{</span> <span class="k">using</span> <span class="n">type</span> <span class="o">=</span> <span class="n">_Tp</span><span class="p">;</span> <span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>来和原本的__shared_ptr加以区分。</p>

<ol>
<li><p>做一个</p>

<pre><code class="c++">class __shared_ptr&lt;__libfund_v1&lt;T&gt;&gt;
:__shared_ptr&lt;typename remove_extent&lt;_Tp&gt;::type, _Lp&gt;{ }
</code></pre>

<p>//注（此处应做成private继承）</p></li>
<li><p>内部准备两个Deleter: _Array_Deleter 和 _Normal_Deleter。</p></li>
<li><p>根据T的类型选择使用Deleter</p>

<pre><code class="c++">using _Deleter_type
= typename conditional&lt;is_array&lt;_Tp&gt;::value,_Array_Deleter,_Normal_Deleter&gt;::type;
</code></pre></li>
<li><p>其他的情况只要pass到基类处理就好。</p></li>
</ol>


<p>整体的难度不是很大，但摸清gcc的coding style和这些代码的工作原理，着实费了番工夫。</p>

<p>当shared_ptr用在array时，其中有种情况跟原本不一样, 原本shared_ptr的构造函数可以接受能够进行implicit cast的类型。当放到数组是这一规则不再适用。</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='c++'><span class='line'><span class="k">class</span> <span class="nc">Base</span> <span class="p">{</span> <span class="p">};</span>
</span><span class='line'><span class="k">class</span> <span class="nc">Derived</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Base</span> <span class="p">{</span> <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="p">{</span>
</span><span class='line'>  <span class="n">Base</span><span class="o">*</span> <span class="n">b</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Derived</span><span class="p">();</span> <span class="c1">// ok</span>
</span><span class='line'>  <span class="n">Base</span> <span class="n">b_array</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
</span><span class='line'>  <span class="n">b_array</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Derived</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span> <span class="c1">// if Base and Derived are of difference</span>
</span><span class='line'>                              <span class="c1">// b_array[1] may cause trouble. &quot;pointer arithmatic&quot;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h4>技巧</h4>

<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='c++'><span class='line'><span class="c1">// helper for _Compatible</span>
</span><span class='line'><span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="n">_From_type</span><span class="p">,</span> <span class="k">typename</span> <span class="n">_To_type</span><span class="o">&gt;</span>
</span><span class='line'>  <span class="k">struct</span> <span class="n">__sp_compatible_helper</span>
</span><span class='line'>  <span class="p">{</span> <span class="k">static</span> <span class="k">constexpr</span> <span class="kt">bool</span> <span class="n">value</span>
</span><span class='line'>    <span class="o">=</span> <span class="n">is_convertible</span><span class="o">&lt;</span><span class="n">_From_type</span><span class="o">*</span><span class="p">,</span> <span class="n">_To_type</span><span class="o">*&gt;::</span><span class="n">value</span><span class="p">;</span> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="k">template</span><span class="o">&lt;</span><span class="kt">size_t</span> <span class="n">_Nm</span><span class="p">,</span> <span class="k">typename</span> <span class="n">_Tp</span><span class="o">&gt;</span>
</span><span class='line'>  <span class="k">struct</span> <span class="n">__sp_compatible_helper</span><span class="o">&lt;</span><span class="n">_Tp</span><span class="p">[</span><span class="n">_Nm</span><span class="p">],</span> <span class="n">_Tp</span><span class="p">[]</span><span class="o">&gt;</span>
</span><span class='line'>  <span class="p">{</span> <span class="k">static</span> <span class="k">constexpr</span> <span class="kt">bool</span> <span class="n">value</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>C++中用偏特化做SFINAE的例子非常常见，是很好的技巧，要铭记。</p>

<h2>Polymorphic Allocator</h2>

<p>allocator这个概念应该还不是很常见，大多数时候这些都有stl内部进行管理，不用担心，但是有些时候，当用户想用自定义的allocator的时候，问题随之而来。</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='c++'><span class='line'><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">A</span><span class="p">,</span> <span class="n">alloc1</span><span class="o">&gt;</span> <span class="n">vec1</span><span class="p">;</span>
</span><span class='line'><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">A</span><span class="p">,</span> <span class="n">alloc2</span><span class="o">&gt;</span> <span class="n">vec2</span><span class="p">;</span>
</span><span class='line'><span class="c1">// oops, vec1 and vec2 now have different types now, which should not happen.</span>
</span></code></pre></td></tr></table></div></figure>


<p>Polymorphic Allocator 也就为了解决这个问题而生。</p>

<h4>Allocator</h4>

<p>一个完备的allocator需要具备一些<a href="http://en.cppreference.com/w/cpp/concept/Allocator">条件</a>，一个最简单的allocator可以仅仅是malloc和free的封装。</p>

<h4>memory_resource</h4>

<p>在Polymorphic Allocator的实现里，根据proposal引入了一个新的虚类<code>memory_resource</code>定义了三个virtual接口:</p>

<ol>
<li>do_allocate();</li>
<li>do_deallocate();</li>
<li>do_is_equal();</li>
</ol>


<h4>polymorphic_allocator</h4>

<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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">_Tp</span><span class="o">&gt;</span>
</span><span class='line'>  <span class="k">class</span> <span class="nc">polymorphic_allocator</span> <span class="p">{</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>这个class就是memory_resource的wrapper，给予了一个完备（前边提到）allocator的所有接口。这样让比如<code>list&lt;int, polymorphic_allocator&lt;int&gt;&gt;</code>虽然类型一样却使用可能了不同的allocator（在这里插一句，标准库容器std::vector之类比较于shared_ptr（多态）的实现，shared_ptr将allocator通过actor的方式传进来，不得不说是一种设计上的进步。）</p>

<p>这些接口主要负责两个功能：</p>

<ol>
<li>分配memory</li>
<li>构造对象</li>
</ol>


<p>polymorphic_allocator里存着个memory_resource*，负责真正进行allocator和deallocate，没有指定时默认为get_default_resource();</p>

<p>构造基于uses-allocator construction用::new(…);（placement new）进行构造。比较恶心的是pair 的piecewise construction，感兴趣的自行搜索，我是看都不想多看一眼。</p>

<h4>resource_adaptor</h4>

<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='c++'><span class='line'><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">_Alloc</span><span class="o">&gt;</span>
</span><span class='line'>  <span class="k">class</span> <span class="nc">__resource_adaptor_imp</span> <span class="o">:</span> <span class="k">public</span> <span class="n">memory_resource</span> <span class="p">{</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">_Alloc</span><span class="o">&gt;</span>
</span><span class='line'>  <span class="k">using</span> <span class="n">resource_adaptor</span> <span class="o">=</span> <span class="n">__resource_adaptor_imp</span><span class="o">&lt;</span>
</span><span class='line'>    <span class="k">typename</span> <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">_Alloc</span><span class="o">&gt;::</span><span class="k">template</span> <span class="n">rebind_alloc</span><span class="o">&lt;</span><span class="kt">char</span><span class="o">&gt;&gt;</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>这个class是对allocator的wrapper，把_Alloc包装成memory_resource，这样resource_adaptor&lt;X&lt;T>>和resource_adaptor&lt;X&lt;U>>就是一种类型了（都是memory_resource）。</p>

<p>所以通常可以这样，resource_adaptor包装allocator，送给polymorphic_allocator使用。</p>

<h4>Global Resource</h4>

<p>在写Global Resource的时候遇到了一个static和inline的<a href="http://stackoverflow.com/questions/185624/static-variables-in-an-inlined-function">问题</a>值得讨论：</p>

<p>在头文件中如果写了static function/variable，那么每个编译单元都会有一个自己的function造成浪费。所以一半生成global resource的方法是inline function返回static variable;</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="kr">inline</span> <span class="n">std</span><span class="o">::</span><span class="n">atomic</span><span class="o">&lt;</span><span class="n">memory_resource</span><span class="o">*&gt;&amp;</span>
</span><span class='line'><span class="n">__get_default_resource</span><span class="p">()</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">atomic</span><span class="o">&lt;</span><span class="n">memory_resource</span><span class="o">*&gt;</span>
</span><span class='line'>    <span class="n">_S_default_resource</span><span class="p">(</span><span class="n">new_delete_resource</span><span class="p">());</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">_S_default_resource</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>补充一些关于static的知识：</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">static</span> <span class="kt">int</span> <span class="n">a</span><span class="p">;</span> <span class="o">-&gt;</span> <span class="k">static</span> <span class="kt">int</span> <span class="n">a</span><span class="p">;</span> <span class="c1">//multiple copies</span>
</span><span class='line'><span class="k">struct</span> <span class="n">A</span> <span class="p">{</span> <span class="k">static</span> <span class="kt">int</span> <span class="n">a</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="n">A</span><span class="o">::</span><span class="n">a</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span> <span class="o">-&gt;</span> <span class="k">struct</span> <span class="n">A</span> <span class="p">{};</span> <span class="kt">int</span> <span class="n">A_a</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>第二种纯粹表示生命周期比较长（相当于有个只有自己能访问的全局变量。）</p>

<p>static in class == static in function;</p>

<p>static class/type == static function;</p>

<h4>技巧</h4>

<p>bit manipulation来计算alignment的技巧也非常酷炫，值得学习。</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>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">static</span> <span class="kt">size_t</span> <span class="nf">_S_aligned_size</span><span class="p">(</span><span class="kt">size_t</span> <span class="n">__size</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">__alignment</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span> <span class="k">return</span> <span class="p">((</span><span class="n">__size</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span><span class="o">|</span><span class="p">(</span><span class="n">__alignment</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="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h1>后记</h1>

<p>感谢tim和john给了个充实的暑假，以后想起来啥在写吧，就这样了:)</p>

<p>（特别鸣谢老婆给的关心与支持，爱你❤️）</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[libstdc++ 初窥]]></title>
    <link href="http://fyou.me/blog/2015/03/29/stdlibc-plus-plus/"/>
    <updated>2015-03-29T00:02:53-04:00</updated>
    <id>http://fyou.me/blog/2015/03/29/stdlibc-plus-plus</id>
    <content type="html"><![CDATA[<p>写了两周stdlibc++.纪录点对c++的理解吧.</p>

<h3><a href="http://en.cppreference.com/w/cpp/language/default_constructor">default constructor</a></h3>

<ol>
<li>constructor 是不能被定义在class外的</li>
<li>当constructor被定义为default, compiler 会生成一个implicity declared constructor, calls the default constructors of the bases and of the non-static members of this class.</li>
</ol>


<h3><a href="http://en.cppreference.com/w/cpp/language/copy_constructor">copy constructors</a></h3>

<ol>
<li>当user没有定义copy ctor的时候, compiler 会生成一个implicity declared的版本.</li>
<li>这个implicity的版本在一定情况下会被delete,详情见cppreference.</li>
</ol>


<h3><a href="http://en.cppreference.com/w/cpp/language/sfinae">SFINAE</a></h3>

<p>Substitution failure is not an error - 编译器不会立刻炸,会搜索next</p>

<h3>类型擦除(把原来的类型去掉，换成统一类型,换言之cast)</h3>

<figure class='code'><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=''><span class='line'>char a[10];
</span><span class='line'>void* ap = (void*)a;
</span><span class='line'>int b;
</span><span class='line'>void* bp = (void*)&b;</span></code></pre></td></tr></table></div></figure>


<p>这里就都cast成了void指针。</p>

<p>再来看个Any的例子:</p>

<figure class='code'><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>
</pre></td><td class='code'><pre><code class=''><span class='line'>class Any {
</span><span class='line'>public:
</span><span class='line'>  Any() : ptr(nullptr) {}
</span><span class='line'>
</span><span class='line'>  Any(const Any& other) {
</span><span class='line'>      ptr = other.ptr-&gt;Copy();
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  Any& operator=(const Any& other) {
</span><span class='line'>      this-&gt;~Any();
</span><span class='line'>      ptr = other.ptr-&gt;Copy();
</span><span class='line'>      return *this;
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  ~Any() {
</span><span class='line'>      if (ptr != nullptr) {
</span><span class='line'>    delete ptr;
</span><span class='line'>      }
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  template&lt;typename T&gt;
</span><span class='line'>    void Assign(const T& data) {
</span><span class='line'>  this-&gt;~Any();
</span><span class='line'>  ptr = new Wrapper&lt;T&gt;(data);
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>  template&lt;typename T&gt;
</span><span class='line'>    T* Get() {
</span><span class='line'>  auto wrapper = dynamic_cast&lt;Wrapper&lt;T&gt;*&gt;(ptr);
</span><span class='line'>  if (wrapper != nullptr) {
</span><span class='line'>      return &wrapper-&gt;data;
</span><span class='line'>  }
</span><span class='line'>  return nullptr;
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>private:
</span><span class='line'>  struct AnyData {
</span><span class='line'>      virtual ~AnyData() { }
</span><span class='line'>
</span><span class='line'>      virtual AnyData* Copy() = 0;
</span><span class='line'>  };
</span><span class='line'>
</span><span class='line'>  template&lt;typename T&gt;
</span><span class='line'>    struct Wrapper : public AnyData {
</span><span class='line'>  Wrapper(const T& data) : data(data) {}
</span><span class='line'>
</span><span class='line'>  AnyData* Copy() override {
</span><span class='line'>      return new Wrapper&lt;T&gt;(data);
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  T data;
</span><span class='line'>    };
</span><span class='line'>
</span><span class='line'>  AnyData* ptr;
</span><span class='line'>};
</span><span class='line'>
</span><span class='line'>#include &lt;iostream&gt;
</span><span class='line'>
</span><span class='line'>int main() {
</span><span class='line'>    Any a;
</span><span class='line'>    a.Assign&lt;int&gt;(3);
</span><span class='line'>    std::cout &lt;&lt; (a.Get&lt;char&gt;() == nullptr) &lt;&lt; "\n";
</span><span class='line'>    std::cout &lt;&lt; (*a.Get&lt;int&gt;() == 3) &lt;&lt; "\n";
</span><span class='line'>
</span><span class='line'>    Any b;
</span><span class='line'>    b = a;
</span><span class='line'>    std::cout &lt;&lt; (*b.Get&lt;int&gt;() == 3) &lt;&lt; "\n";
</span><span class='line'>
</span><span class='line'>    return 0;
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<h3>Placement new</h3>

<p>通常的new = malloc + ctor, 所以palcement new 就是在分配好的内存地址上再调用一次ctor</p>

<p>通常的delete = dctor + free</p>

<h3>Vtable 的 C 实现</h3>

<figure class='code'><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>
</pre></td><td class='code'><pre><code class=''><span class='line'>#include &lt;stdio.h&gt;
</span><span class='line'>
</span><span class='line'>typedef void (*GenericFuncPtr)(void);
</span><span class='line'>//use general ptr array store vf pointer
</span><span class='line'>
</span><span class='line'>struct Cat {
</span><span class='line'>    GenericFuncPtr* vtable_ptr;
</span><span class='line'>};
</span><span class='line'>
</span><span class='line'>void cat_speak(struct Cat* this) {
</span><span class='line'>    printf("miao");
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>void cat_die(struct Cat* this) {
</span><span class='line'>    printf("ewww");
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>GenericFuncPtr cat_vtable[] = {
</span><span class='line'>    // do in the compile time
</span><span class='line'>    (GenericFuncPtr)cat_speak,
</span><span class='line'>    (GenericFuncPtr)cat_die,
</span><span class='line'>};
</span><span class='line'>
</span><span class='line'>void construct_cat(struct Cat* c) {
</span><span class='line'>    c-&gt;vtable_ptr = cat_vtable;
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>struct Lion {
</span><span class='line'>    struct Cat base;
</span><span class='line'>};
</span><span class='line'>
</span><span class='line'>void lion_speak(struct Lion* this) {
</span><span class='line'>    printf("ow");
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>void lion_die(struct Lion* this) {
</span><span class='line'>    printf("ahhh");
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>GenericFuncPtr lion_vtable[] = {
</span><span class='line'>    (GenericFuncPtr)lion_speak,
</span><span class='line'>    (GenericFuncPtr)lion_die,
</span><span class='line'>};
</span><span class='line'>
</span><span class='line'>void construct_lion(struct Lion* l) {
</span><span class='line'>    construct_cat(&l-&gt;base);
</span><span class='line'>    l-&gt;base.vtable_ptr = lion_vtable;
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>int main () {
</span><span class='line'>    struct Lion l;
</span><span class='line'>    struct Cat* c;
</span><span class='line'>    construct_lion(&l);
</span><span class='line'>    c = &l.base;
</span><span class='line'>    // c-&gt;speak
</span><span class='line'>    ((void (*)(struct Lion*))c-&gt;vtable_ptr[0])((struct Lion*)c);
</span><span class='line'>    // c-&gt;die
</span><span class='line'>    ((void (*)(struct Lion*))c-&gt;vtable_ptr[1])((struct Lion*)c);
</span><span class='line'>    return 0;
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<h3><a href="http://en.cppreference.com/w/cpp/language/partial_specialization">Partial specialization</a></h3>

<p>Partial specialization 只是针对模版参数,而且function不支持partial specialization.</p>

<figure class='code'><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>
</pre></td><td class='code'><pre><code class=''><span class='line'>template &lt;typename _Tp&gt; // primary
</span><span class='line'>class A {
</span><span class='line'>};
</span><span class='line'>
</span><span class='line'>template &lt;typename _Tp&gt;
</span><span class='line'>class A&lt;_Tp[]&gt; {
</span><span class='line'>};
</span><span class='line'>
</span><span class='line'>template &lt;typename _Tp&gt;
</span><span class='line'>class A&lt;_Tp*&gt; {
</span><span class='line'>};
</span><span class='line'>
</span><span class='line'>//template &lt;typename _Tp&gt; //error
</span><span class='line'>//class A&lt;_Tp&gt; {
</span><span class='line'>//};</span></code></pre></td></tr></table></div></figure>


<h3><a href="http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers">Universal ref</a></h3>

<figure class='code'><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=''><span class='line'>template&lt;typename T&gt;
</span><span class='line'>struct A {
</span><span class='line'>    void Foo(T&& /*rvalue ref*/);
</span><span class='line'>};
</span><span class='line'>struct A {
</span><span class='line'>    template&lt;typename T&gt;
</span><span class='line'>      void Foo(T&& /*forwarding ref, or `universal ref`*/);
</span><span class='line'>};
</span><span class='line'>//上面的例子虽然T是模板参数，但不是等着被推出来的。</span></code></pre></td></tr></table></div></figure>


<h3><a href="http://en.cppreference.com/w/cpp/utility/variadic">Variadic functions</a></h3>

<p>用法与用处。</p>

<figure class='code'><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>
</pre></td><td class='code'><pre><code class=''><span class='line'>#include &lt;iostream&gt;
</span><span class='line'>template &lt;typename T&gt;
</span><span class='line'>class A {
</span><span class='line'>public:
</span><span class='line'>  A() { std::cout &lt;&lt; "without size" &lt;&lt; "\n"; }
</span><span class='line'>  A(size_t size) { std::cout &lt;&lt; "with size" &lt;&lt; "\n"; }
</span><span class='line'>  A(size_t size, size_t idx) { std::cout &lt;&lt; "with size, idx" &lt;&lt; "\n"; }
</span><span class='line'>  ~A() { std::cout &lt;&lt; "dtor" &lt;&lt; "\n"; }
</span><span class='line'>};
</span><span class='line'>
</span><span class='line'>template &lt;typename _Tp, typename... Args&gt;
</span><span class='line'>class B : A&lt;_Tp&gt; {
</span><span class='line'>public:
</span><span class='line'>  //B() { std::cout &lt;&lt; "B ctor" &lt;&lt; "\n"; } B&lt;int&gt;b1 wont work;
</span><span class='line'>  B(Args&&... _args) : A&lt;_Tp&gt;(_args...) { }
</span><span class='line'>private:
</span><span class='line'>  //A&lt;_Tp&gt; _a;
</span><span class='line'>};
</span><span class='line'>
</span><span class='line'>class Tmp {
</span><span class='line'>public:
</span><span class='line'>  Tmp() { std::cout &lt;&lt; "Tmp ctor" &lt;&lt; "\n"; }
</span><span class='line'>};
</span><span class='line'>
</span><span class='line'>int main () {
</span><span class='line'>    //B&lt;int&gt; b1;
</span><span class='line'>    B&lt;int,size_t&gt; b2(1);
</span><span class='line'>    //B&lt;int,size_t&gt; b(1,2); //error
</span><span class='line'>    B&lt;int,size_t,size_t&gt; b3(1,2);
</span><span class='line'>
</span><span class='line'>    Tmp tmp;
</span><span class='line'>    Tmp tmp1(); // function !!!!!!!!!!!!
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<h3><a href="http://stackoverflow.com/questions/6627651/enable-if-method-specialization">function specialization</a></h3>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[面试总结]]></title>
    <link href="http://fyou.me/blog/2015/03/01/epic/"/>
    <updated>2015-03-01T15:41:09-05:00</updated>
    <id>http://fyou.me/blog/2015/03/01/epic</id>
    <content type="html"><![CDATA[<h3>Epic</h3>

<p>说来这也算是这辈子第一次tech interview, 总结一下把。总体面试还是分为两块,技术性问题和非技术性问题。</p>

<h3>Non-Tech</h3>

<p>非技术性问题问了目前为止解决的最难的bug是什么, 你最喜欢的游戏是什么，给你一个机会improve，你会怎么improve。</p>

<h3>Tech</h3>

<p>问了Array, List, Tree, Hashtable 各自的优劣,我萌萌的完全不知道该怎么答。回头整理了下发在<a href="https://docs.google.com/spreadsheets/d/1RdcEWxH6dcAfvAEpaDvLp4lW7AwC2C0RNDvXfqlq5yI/edit?usp=sharing">这里</a>,基本从两个角度作答:1.复杂度 2.overhead</p>

<h3>C++</h3>

<ul>
<li>什么是Virtual Destructor: 不用作<a href="https://github.com/Noeyfan/CodingPractice/blob/master/virtual/vf_destructor.cc">owned base class pointer</a>的时候不用.</li>
</ul>


<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>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="n">A</span><span class="o">*</span> <span class="n">p</span> <span class="o">=</span> <span class="n">new</span> <span class="n">B</span><span class="p">();</span>
</span><span class='line'><span class="n">delete</span> <span class="n">p</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>virtual function 是怎么样实现的(一般实现virtual function的时候会把所有的函数指针放到一个<a href="http://en.wikipedia.org/wiki/Virtual_method_table">表(vtable)里</a>,</li>
</ul>


<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='C'><span class='line'><span class="err">一个类有</span><span class="mi">10</span><span class="err">个</span><span class="n">virtual</span> <span class="n">function</span><span class="err">你初始化一个子类对象这个子类对象一般多大？</span>
</span><span class='line'><span class="err">假设基类</span><span class="n">size</span><span class="err">为</span><span class="n">A</span><span class="err">，子类</span><span class="n">size</span><span class="err">为</span><span class="n">B</span><span class="err">假设基类所有成员</span><span class="n">size</span><span class="err">和为</span><span class="n">A</span><span class="err">，</span>
</span><span class='line'><span class="err">子类自己所有成员</span><span class="n">size</span><span class="err">和为</span><span class="n">B</span><span class="err">创建一个子类对象，占多大空间？</span>
</span><span class='line'>
</span><span class='line'><span class="err">答案</span><span class="o">:</span><span class="n">A</span><span class="o">+</span><span class="n">B</span><span class="o">+</span><span class="k">sizeof</span><span class="p">(</span><span class="n">pointer_type</span><span class="p">),</span> <span class="err">另外</span><span class="n">alignment</span><span class="err">可能让他更大</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>几何问题: 做一个2D game, 不用ray cast如何知道A是否看的见B, 很简单, Va*(Pb-Pa) > 0 说明能看得见, 反之看不见。</li>
</ul>


<h3>More</h3>

<p>还是要学好C/C++,<a href="http://www.slideshare.net/olvemaudal/deep-c">deep-C</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[关于堆分配和栈分配思考以及指针和引用]]></title>
    <link href="http://fyou.me/blog/2014/12/31/heapstack/"/>
    <updated>2014-12-31T01:33:26-05:00</updated>
    <id>http://fyou.me/blog/2014/12/31/heapstack</id>
    <content type="html"><![CDATA[<h4>栈分配</h4>

<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>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="kt">int</span> <span class="nf">GiveVal</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="n">a</span><span class="p">;</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">x</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>这是合法的栈分配意思是在执行完整个方法后,将里边的数据copy一份,return给外边以后,再将自身的数据a,x释放掉。</p>

<h4>堆分配的产生</h4>

<p>由于栈分配在小规模操作的时候还好,但是上升到大规模的运算时候,拷贝的速度会变的非常的慢。
所以就干脆不释放运算过程中的数据，直接将地址return出来。
传统做法是这样的:</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>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="n">FWidget</span><span class="o">*</span> <span class="nf">CreateWidget</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="kt">int</span> <span class="n">z</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">FWidget</span><span class="o">*</span> <span class="n">NewWidgetPointer</span> <span class="o">=</span> <span class="n">new</span> <span class="n">FWidget</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">z</span><span class="p">);</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">NewWidgetPointer</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h4>引用</h4>

<p>int b = 3;
int&amp; a = b;
这个等价于
int b = 3;
int<em> ap = &b;
a = 4; 等价于 </em>ap = 4;
&amp;a 等价于 ap
唯一不等价的是你没法改ap指向谁
ap只能指向b，不能换人</p>

<h4>例题</h4>

<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>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="n">FWidget</span><span class="o">&amp;</span> <span class="n">CreateWidget</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="kt">int</span> <span class="n">z</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">FWidget</span> <span class="n">NewWidget</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">z</span><span class="p">);</span> <span class="c1">// 栈分配</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">NewWidget</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>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="n">FWidget</span><span class="o">*</span> <span class="nf">CreateWidget</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="kt">int</span> <span class="n">z</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">FWidget</span>  <span class="n">NewWidget</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">z</span><span class="p">);</span>
</span><span class='line'>  <span class="k">return</span> <span class="o">&amp;</span><span class="n">NewWidget</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>问题:
return 出去以后原来的东西就被释放了。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[对于int64, int32的一点理解]]></title>
    <link href="http://fyou.me/blog/2014/12/30/int/"/>
    <updated>2014-12-30T14:34:44-05:00</updated>
    <id>http://fyou.me/blog/2014/12/30/int</id>
    <content type="html"><![CDATA[<h3>基本概念</h3>

<p>32/64 表示的是数字长度</p>

<h4>int32_t 4byte * 8 = 32</h4>

<p>表示范围是: -(2<sup>31</sup>+1) ~ 2<sup>31</sup>-1</p>

<h4>uint32_t</h4>

<p>表示范围是: 0 ~ 2<sup>32</sup>-1</p>

<h4>int64_t 8byte * 8 = 62</h4>

<p>表示范围是: -(2<sup>63</sup>+1) ~ 2<sup>63</sup>-1</p>

<h4>uint64_t</h4>

<p>表示范围是: 0 ~ 2<sup>64</sup>-1</p>

<h3>进制转换</h3>

<p>hex(10) = dec(16)</p>

<h3>编译区别</h3>

<p>cc -m32 a.cc
cc -m64 a.cc</p>

<p>指针大小是不相同的64位下是8byte, 32位下是4byte.</p>

<p>原因:就是说,现代操作系统比较贴心,每个程序运行的时候都给你一个大大的独占的内存条,对于32位系统来说，给的内存条大小为2<sup>32</sup>字节,也就是4GB
对于64位系统来说,给的内存条大小是2<sup>64</sup>字节,也就是数不清的字节
当然不可能真给你这么大。策略是你用多少就给你多少
但是你仿佛有一个超大内存可以独霸
所有的指针都是存的这个超大内存的地址
自然,32位系统的指针是4字节，因为一共有2<sup>32</sup>个格子嘛,4字节就是32位数,每个数对应一个格子,也就是存了32个01.
64位的话只是更多而已,依然是一一对应</p>

<h3>数组与指针后移</h3>

<p>假设T a[] = {};
已知a地址为A
a+1 的地址是&mdash;&ndash;> A + sizeof(T); // 此处是T而不是T*</p>

<h3>补码反码表示</h3>

<p>C中 ^表示异或计算 (不同为1,相同为0)
      ~表示按位取反 (计算机中求负数 = 取反+1)
        如果出现要求返回是uint却返回了负数的情况,计算机会吧他取反+1当成uint来计算。 -8 = ~8 + 1 = 2<sup>32</sup> -1 -8 +1</p>

<h3>关于所谓的符号位</h3>

<pre><code>    举例说明:
    比如一个一字节的数:
    0 ~ 0111 1111是正数,表示0~127
    1000 0000 ~ 1111 1111是负数,表示-128 ~ -1
    每个正数取反加一就是相应的负数
    -128比较诡异,因为没有对应的正数

    也就是说最高位是1表示正,是0表示负这个没错,但是具体求的时候,始终是取反+1
</code></pre>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[TCP Server-Client 实现]]></title>
    <link href="http://fyou.me/blog/2014/11/24/tcp-prectise/"/>
    <updated>2014-11-24T22:22:50-05:00</updated>
    <id>http://fyou.me/blog/2014/11/24/tcp-prectise</id>
    <content type="html"><![CDATA[<p>出于练习目的，决定自己实现一遍client-server的基础模型.
<a href="https://github.com/Noeyfan/crack_code_interview/tree/master/socket">源码</a></p>

<h4>Server端</h4>

<p>1.申明并取得启用服务地址的一系列参数(这里通过命令行输入).</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='C'><span class='line'><span class="k">struct</span> <span class="n">sockaddr_in</span> <span class="n">server</span><span class="p">;</span>
</span><span class='line'><span class="k">struct</span> <span class="n">sockaddr_in</span> <span class="n">client</span><span class="p">;</span>
</span><span class='line'><span class="kt">int</span> <span class="n">port</span><span class="p">,</span> <span class="n">connectfd</span><span class="p">,</span> <span class="n">sin_size</span><span class="p">;</span>
</span><span class='line'><span class="n">sin_size</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="k">struct</span> <span class="n">sockaddr_in</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="n">port</span> <span class="o">=</span> <span class="n">htons</span><span class="p">(</span><span class="n">atoi</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]));</span> <span class="c1">//端叙转换,atoi只用于转换数字</span>
</span><span class='line'><span class="c1">//转化时跳过前面的空格字符，直到遇上数字或正负符号才开始做转换，而再遇到非数字或字符串结束时(&#39;/0&#39;)才结束转换，并将结果返回。</span>
</span><span class='line'>
</span><span class='line'><span class="n">server</span><span class="p">.</span><span class="n">sin_family</span> <span class="o">=</span> <span class="n">AF_INET</span><span class="p">;</span>
</span><span class='line'><span class="n">server</span><span class="p">.</span><span class="n">sin_port</span> <span class="o">=</span> <span class="n">port</span><span class="p">;</span>
</span><span class='line'><span class="n">server</span><span class="p">.</span><span class="n">sin_addr</span><span class="p">.</span><span class="n">s_addr</span> <span class="o">=</span> <span class="n">htonl</span><span class="p">(</span><span class="n">INADDR_ANY</span><span class="p">);</span> <span class="c1">//localhost</span>
</span></code></pre></td></tr></table></div></figure>


<p>2.创建socket, 并设置为resuable(并发服务器)</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='C'><span class='line'><span class="kt">int</span> <span class="n">socketfd</span> <span class="o">=</span> <span class="n">socket</span><span class="p">(</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">SOCK_STREAM</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="c1">//返回int</span>
</span><span class='line'><span class="kt">int</span> <span class="n">opt</span> <span class="o">=</span> <span class="n">SO_REUSEADDR</span><span class="p">;</span>
</span><span class='line'><span class="n">setsockopt</span><span class="p">(</span><span class="n">socketfd</span><span class="p">,</span> <span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">SO_REUSEADDR</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">opt</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">opt</span><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<p>3.bind 和listen</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='C'><span class='line'><span class="k">if</span><span class="p">(</span><span class="n">bind</span><span class="p">(</span><span class="n">socketfd</span><span class="p">,</span> <span class="p">(</span><span class="k">struct</span> <span class="n">sockaddr</span> <span class="o">*</span><span class="p">)</span> <span class="o">&amp;</span><span class="n">server</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="k">struct</span> <span class="n">sockaddr</span><span class="p">))</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">perror</span><span class="p">(</span><span class="s">&quot;Bind error&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="n">exit</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><span class='line'><span class="k">if</span><span class="p">(</span><span class="n">listen</span><span class="p">(</span><span class="n">socketfd</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">perror</span><span class="p">(</span><span class="s">&quot;listen() error</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>4.accept卡住程序，等待客户连入，一但连入，开thread处理client</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>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="k">if</span><span class="p">((</span><span class="n">connectfd</span> <span class="o">=</span> <span class="n">accept</span><span class="p">(</span><span class="n">socketfd</span><span class="p">,</span> <span class="p">(</span><span class="k">struct</span> <span class="n">sockaddr</span> <span class="o">*</span><span class="p">)</span><span class="o">&amp;</span><span class="n">client</span><span class="p">,</span> <span class="p">(</span><span class="kt">socklen_t</span> <span class="o">*</span><span class="p">)</span><span class="o">&amp;</span><span class="n">sin_size</span><span class="p">))</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">){</span> <span class="c1">//connectfd is only for process request</span>
</span><span class='line'>  <span class="n">perror</span> <span class="p">(</span><span class="s">&quot;accept() error </span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">struct</span> <span class="n">ARG</span><span class="o">*</span> <span class="n">arg</span> <span class="o">=</span> <span class="p">(</span><span class="k">struct</span> <span class="n">ARG</span><span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="k">struct</span> <span class="n">ARG</span><span class="p">));</span>
</span><span class='line'>  <span class="n">arg</span><span class="o">-&gt;</span><span class="n">connfd</span> <span class="o">=</span> <span class="n">connectfd</span><span class="p">;</span>
</span><span class='line'>  <span class="n">connarr</span><span class="p">[</span><span class="n">cnt</span><span class="o">++</span><span class="p">]</span> <span class="o">=</span> <span class="n">connectfd</span><span class="p">;</span>
</span><span class='line'>  <span class="n">printf</span><span class="p">(</span><span class="s">&quot;connect fd after is : %d&quot;</span><span class="p">,</span> <span class="n">arg</span><span class="o">-&gt;</span><span class="n">connfd</span><span class="p">);</span>
</span><span class='line'>  <span class="n">arg</span><span class="o">-&gt;</span><span class="n">client</span> <span class="o">=</span> <span class="n">client</span><span class="p">;</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">pthread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="kr">thread</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">start_routine</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span><span class="o">*</span><span class="p">)</span><span class="n">arg</span><span class="p">))</span> <span class="p">{</span> <span class="c1">//if get strange thing, most likely is pass parameter</span>
</span><span class='line'>      <span class="n">perror</span><span class="p">(</span><span class="s">&quot;pthread create error&quot;</span><span class="p">);</span>
</span><span class='line'>      <span class="n">exit</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="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h4>Client端</h4>

<p>1.载入server参数</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='C'><span class='line'><span class="k">struct</span> <span class="n">sockaddr_in</span> <span class="n">server_addr</span><span class="p">;</span>
</span><span class='line'><span class="c1">//两种方法获取server_addr</span>
</span><span class='line'><span class="c1">//1. 可以读取localhost</span>
</span><span class='line'><span class="k">struct</span> <span class="n">hostent</span> <span class="o">*</span><span class="n">server</span><span class="p">;</span>
</span><span class='line'><span class="n">server</span> <span class="o">=</span> <span class="n">gethostbyname</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
</span><span class='line'><span class="n">bcopy</span><span class="p">(</span><span class="n">server</span><span class="o">-&gt;</span><span class="n">h_addr</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">server_addr</span><span class="p">.</span><span class="n">sin_addr</span><span class="p">,</span><span class="n">server</span><span class="o">-&gt;</span><span class="n">h_length</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">//2. 直接对server_addr放入ipaddr</span>
</span><span class='line'><span class="n">socketaddr</span><span class="p">.</span><span class="n">sin_addr</span><span class="p">.</span><span class="n">s_addr</span> <span class="o">=</span> <span class="n">inet_addr</span><span class="p">(</span><span class="s">&quot;127.0.0.1&quot;</span><span class="p">);</span> <span class="c1">// 127.0.0.1可以是任何string</span>
</span></code></pre></td></tr></table></div></figure>


<p>2.connect to the Server</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='C'><span class='line'><span class="k">if</span><span class="p">(</span><span class="n">connect</span><span class="p">(</span><span class="n">sockfd</span><span class="p">,</span> <span class="p">(</span><span class="k">const</span> <span class="k">struct</span> <span class="n">sockaddr</span> <span class="o">*</span><span class="p">)</span><span class="o">&amp;</span><span class="n">server_addr</span><span class="p">,</span><span class="k">sizeof</span><span class="p">(</span><span class="n">server_addr</span><span class="p">))</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">printf</span><span class="p">(</span><span class="s">&quot;fail to connect&quot;</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>3.开thread去处理服务器发来的信息</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>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="k">if</span><span class="p">(</span><span class="n">pthread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">thread1</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">start_receive</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span><span class="o">*</span><span class="p">)</span><span class="n">arg</span><span class="p">)){</span>
</span><span class='line'>  <span class="n">perror</span><span class="p">(</span><span class="s">&quot;listen create error&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>4.在另外的while loop里进行发送</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>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="k">while</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// must</span>
</span><span class='line'>  <span class="n">sendRequest</span><span class="p">(</span><span class="n">sockfd</span><span class="p">,</span> <span class="n">argv</span><span class="p">[</span><span class="mi">3</span><span class="p">]);</span>
</span><span class='line'>  <span class="c1">//在sendRequest里用fegets卡住程序.</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h4>I/O复用提高效率</h4>

<p>基本概念(从非阻塞轮询到select/poll到epoll)</p>

<p>1.非阻塞轮询:不停检测所有io,有数据则读取</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>
</pre></td><td class='code'><pre><code class='C'><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="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="n">in</span> <span class="n">stream</span><span class="p">[]){</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="n">has</span> <span class="n">data</span><span class="p">){</span>
</span><span class='line'>          <span class="n">read</span> <span class="n">all</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>2.为了避免cpu空转:引入select代理
同时观察许多流的I/O事件，在空闲的时候，会把当前线程阻塞掉，当有一个或多个流有I/O事件时，就从阻塞态中醒来，于是我们的程序就会轮询一遍所有的流</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='C'><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="n">select</span><span class="p">(</span><span class="n">stream</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="n">in</span> <span class="n">stream</span><span class="p">[]){</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="n">has</span> <span class="n">data</span><span class="p">){</span>
</span><span class='line'>          <span class="n">read</span> <span class="n">all</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>于是，如果没有I/O事件产生，我们的程序就会阻塞在select处。但是依然有个问题，我们从select那里仅仅知道了，有I/O事件发生了，但却并不知道是那几个流（可能有一个，多个，甚至全部），我们只能无差别轮询所有流，找出能读出数据，或者写入数据的流，对他们进行操作。使用select，我们有O(n)的无差别轮询复杂度，同时处理的流越多，每一次无差别轮询时间就越长。</p>

<p>3.epoll (event poll)
epoll会把哪个流发生了怎样的I/O事件通知我们。此时我们对这些流的操作都是有意义的,复杂度降低到了O(k)，k为产生I/O事件的流的个数.</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='C'><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="n">active_stream</span><span class="p">[]</span> <span class="o">=</span> <span class="n">epoll_wait</span><span class="p">(</span><span class="n">epollfd</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="n">in</span> <span class="n">active_stream</span><span class="p">[])</span> <span class="p">{</span>
</span><span class='line'>          <span class="n">read</span> <span class="n">or</span> <span class="n">write</span> <span class="n">till</span> <span class="n">unavailable</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>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Function Pointer]]></title>
    <link href="http://fyou.me/blog/2014/11/22/p-thread/"/>
    <updated>2014-11-22T16:19:47-05:00</updated>
    <id>http://fyou.me/blog/2014/11/22/p-thread</id>
    <content type="html"><![CDATA[<p>今天才知道各各系统的man是不一样的,mac下查man还是上网查把。</p>

<p>0.前言 <a href="https://github.com/Noeyfan/CodingPractice/blob/master/virtual/virtualFunctionC.c">C实现virtual function</a></p>

<figure class='code'><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=''><span class='line'>函数:
</span><span class='line'>{返回值类型} {函数名}({参数列表})这个格式你应该很熟悉了，就是函数
</span><span class='line'>
</span><span class='line'>函数指针:函数指针也是一种变量，可以直接以函数名赋值
</span><span class='line'>{返回值类型} （*{变量名}）({参数列表})
</span><span class='line'>
</span><span class='line'>变量声明:
</span><span class='line'>{类型} {和表达式很像的东西}</span></code></pre></td></tr></table></div></figure>


<p>1.基础应用(1)</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='C'><span class='line'><span class="k">typedef</span> <span class="nf">float</span> <span class="p">(</span><span class="o">*</span><span class="n">pf</span><span class="p">)</span> <span class="p">(</span><span class="kt">float</span><span class="p">,</span> <span class="kt">float</span><span class="p">);</span>
</span><span class='line'><span class="c1">//pf 是函数指针类型,注意此处*的位置，表示取值</span>
</span><span class='line'><span class="c1">//typedef 将pf变成一个类型</span>
</span><span class='line'><span class="c1">//如果没有typedef,需要对每个同样函数指针的定义做相同的事情</span>
</span><span class='line'><span class="c1">//float (*pf)(float, float);</span>
</span><span class='line'><span class="c1">//float (*a)(float, float);</span>
</span><span class='line'><span class="c1">//此处变量名也可以省去，方便YY :)</span>
</span><span class='line'>
</span><span class='line'><span class="kt">float</span> <span class="nf">foo</span><span class="p">(</span><span class="n">flaot</span> <span class="n">a</span><span class="p">,</span> <span class="kt">float</span> <span class="n">b</span><span class="p">)</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">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">pf</span> <span class="n">a</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">foo</span><span class="p">;</span>
</span><span class='line'>  <span class="p">(</span><span class="o">*</span><span class="n">a</span><span class="p">)(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>2.基础应用(2)</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>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="k">typedef</span> <span class="nf">int</span> <span class="p">(</span><span class="o">*</span><span class="n">fp</span><span class="p">)(</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kt">int</span> <span class="nf">add</span> <span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">a</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><span class='line'><span class="kt">int</span> <span class="nf">imp</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">,</span> <span class="n">fp</span> <span class="n">f</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)(</span><span class="n">a</span><span class="p">,</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="kt">int</span> <span class="nf">main</span> <span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;result is %i&quot;</span><span class="p">,</span> <span class="n">imp</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="n">add</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>3.两种定义形式</p>

<ul>
<li>C: 返回类型 (*函数指针名称)(参数类型,参数类型,参数类型，…);</li>
<li>C++: 返回类型 (类名称::*函数成员名称)(参数类型，参数类型，参数类型，…);</li>
</ul>


<p>4.函数指针作为返回值</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>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">foo</span><span class="p">(</span><span class="kt">char</span> <span class="n">op</span><span class="p">))(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">op</span> <span class="o">==</span> <span class="sc">&#39;+&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">add</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="mi">0</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="p">(</span><span class="o">*</span><span class="n">signal</span><span class="p">)(</span><span class="kt">int</span> <span class="n">signo</span><span class="p">,</span><span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">func</span><span class="p">)(</span><span class="kt">int</span><span class="p">))(</span><span class="kt">int</span><span class="p">);</span>
</span><span class='line'><span class="c1">//unix 系统函数</span>
</span><span class='line'><span class="c1">//函数名称signal</span>
</span><span class='line'><span class="c1">//接受两个参数- int 和 一个函数指针</span>
</span><span class='line'><span class="c1">//返回函数指针类型为: void(*)(int)</span>
</span><span class='line'><span class="c1">//照着读signal 调用两次以后返回void</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="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">returnpf</span><span class="p">)(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">);</span> <span class="c1">// (*returnpf) 这个括号不能少</span>
</span><span class='line'>  <span class="n">returnpf</span> <span class="o">=</span> <span class="n">foo</span><span class="p">(</span><span class="sc">&#39;+&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="n">printf</span><span class="p">(</span><span class="s">&quot;result is %i</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="p">(</span><span class="o">*</span><span class="n">returnpf</span><span class="p">)(</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">));</span>
</span><span class='line'>  <span class="c1">//or</span>
</span><span class='line'>  <span class="n">printf</span><span class="p">(</span><span class="s">&quot;result is %i</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">foo</span><span class="p">(</span><span class="sc">&#39;+&#39;</span><span class="p">)(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">));</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>5.函数指针数组</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='C'><span class='line'><span class="kt">float</span> <span class="p">(</span><span class="o">*</span><span class="n">pFunctionArray</span><span class="p">[</span><span class="mi">10</span><span class="p">])(</span><span class="kt">float</span><span class="p">,</span> <span class="kt">float</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>6.用typedef 简化函数</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>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="k">typedef</span> <span class="nf">void</span> <span class="p">(</span><span class="o">*</span><span class="n">pf</span><span class="p">)(</span><span class="kt">int</span><span class="p">);</span>
</span><span class='line'><span class="c1">//void (*signal)(int signo,void (*func)(int))(int);</span>
</span><span class='line'><span class="c1">//= pf signal(int signo, pf func);</span>
</span><span class='line'>
</span><span class='line'><span class="k">typedef</span> <span class="kt">void</span> <span class="nf">pf</span><span class="p">(</span><span class="kt">int</span><span class="p">);</span>
</span><span class='line'><span class="c1">//void (*signal)(int signo,void (*func)(int))(int);</span>
</span><span class='line'><span class="c1">// = pf* signal(int signo, pf* func);</span>
</span></code></pre></td></tr></table></div></figure>


<p>7.附言，米米的教导 <a href="http://www.zhihu.com/question/20635559/answer/19669437">米米知乎解答</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='C'><span class='line'><span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">signal</span><span class="p">[</span><span class="mi">4</span><span class="p">])(</span><span class="kt">int</span><span class="p">)(</span><span class="kt">char</span><span class="p">)[</span><span class="mi">6</span><span class="p">];</span>
</span><span class='line'><span class="c1">//变量申明</span>
</span><span class='line'><span class="c1">//该表达式返回int</span>
</span><span class='line'><span class="c1">//所以(*signal[4])(int)(char)返回一个int指针(可以用作[6])</span>
</span><span class='line'><span class="c1">//(*signal[4])(int)是一个函数指针，接受参数char，返回int指针</span>
</span><span class='line'><span class="c1">//signal[4]是一个函数指针，接受int，返回另一个函数指针，后者的函数类型如上所述，“接受char，返回int指针”</span>
</span><span class='line'><span class="c1">//现在signal是啥呢，肯定是个数组。什么数组呢？上一条那玩意的数组</span>
</span><span class='line'><span class="c1">//结论:signal是一个函数指针数组，函数指针的函数类型为：接受int，返回另一个函数指针，后者的函数类型为“接受char，返回int指针”</span>
</span></code></pre></td></tr></table></div></figure>


<p>8.如何使用<code>function pointer</code> 实现dynamic dispatch?</p>

<p>原理非常简单就是在初始化时候将内部的function pointer，指向implementation的真实function从而达到目的。</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>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="kt">void</span> <span class="nf">funA_imp</span><span class="p">()</span> <span class="p">{</span> <span class="n">printf</span><span class="p">(</span><span class="s">&quot;world&quot;</span><span class="p">);</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">funBase_imp</span><span class="p">()</span> <span class="p">{</span> <span class="n">printf</span><span class="p">(</span><span class="s">&quot;hello&quot;</span><span class="p">);</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">struct</span> <span class="n">Base</span> <span class="p">{</span> <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">fun</span><span class="p">)();</span> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="k">struct</span> <span class="n">A</span> <span class="p">{</span> <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">fun</span><span class="p">)();</span> <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="p">{</span>
</span><span class='line'>    <span class="k">struct</span> <span class="n">Base</span> <span class="n">b</span><span class="p">;</span>
</span><span class='line'>    <span class="c1">// dynamic dispatch</span>
</span><span class='line'>    <span class="c1">// struct A a;</span>
</span><span class='line'>    <span class="c1">// a.fun = &amp;funA_imp;</span>
</span><span class='line'>    <span class="c1">// b.fun = a.fun;</span>
</span><span class='line'>    <span class="n">b</span><span class="p">.</span><span class="n">fun</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">funBase_imp</span><span class="p">;</span>
</span><span class='line'>    <span class="n">b</span><span class="p">.</span><span class="n">fun</span><span class="p">();</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>virtual function</code> 也是同理</p>

<p><code>Base class</code> maintain 一个<code>__vptr*</code> 指向真实的<code>vtable (array of functions)</code> implementation，而所有的<code>derived class</code> 包括 <code>base</code> 自己都有一个 <code>vtable</code> 的implementation.</p>

<p>下面 class A in 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>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">A</span> <span class="p">{</span>
</span><span class='line'><span class="k">protected</span><span class="o">:</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">a</span><span class="p">;</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'>    <span class="n">A</span><span class="p">()</span> <span class="p">{</span><span class="n">a</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;}</span>
</span><span class='line'>    <span class="k">virtual</span> <span class="kt">void</span> <span class="n">update</span><span class="p">()</span> <span class="p">{</span><span class="n">a</span><span class="o">++</span><span class="p">;}</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">access</span><span class="p">()</span> <span class="p">{</span><span class="n">update</span><span class="p">();</span> <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="k">class</span> <span class="nc">B</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">public</span><span class="o">:</span>
</span><span class='line'>      <span class="kt">void</span> <span class="n">update</span><span class="p">()</span> <span class="p">{</span><span class="n">a</span><span class="o">--</span><span class="p">;}</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>可以用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>
<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>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="k">struct</span> <span class="n">A</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">void</span> <span class="p">(</span><span class="o">*</span><span class="n">A</span><span class="p">)(</span><span class="k">struct</span> <span class="n">A</span><span class="o">*</span><span class="p">);</span>
</span><span class='line'>    <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">update</span><span class="p">)(</span><span class="k">struct</span> <span class="n">A</span><span class="o">*</span><span class="p">);</span>
</span><span class='line'>    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">access</span><span class="p">)(</span><span class="k">struct</span> <span class="n">A</span><span class="o">*</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span> <span class="n">A_functable</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="n">A</span><span class="p">{</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">a</span><span class="p">;</span>
</span><span class='line'>    <span class="n">A_functable</span> <span class="o">*</span><span class="n">vmt</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span> <span class="n">A</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">A_A</span><span class="p">(</span><span class="n">A</span> <span class="o">*</span><span class="n">this</span><span class="p">);</span>
</span><span class='line'><span class="kt">void</span> <span class="nf">A_update</span><span class="p">(</span><span class="n">A</span><span class="o">*</span> <span class="n">this</span><span class="p">);</span>
</span><span class='line'><span class="kt">int</span> <span class="nf">A_access</span><span class="p">(</span><span class="n">A</span><span class="o">*</span> <span class="n">this</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="n">A_functable</span> <span class="n">A_vmt</span> <span class="o">=</span> <span class="p">{</span><span class="n">A_A</span><span class="p">,</span> <span class="n">A_update</span><span class="p">,</span> <span class="n">A_access</span><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">A_A</span><span class="p">(</span><span class="n">A</span> <span class="o">*</span><span class="n">this</span><span class="p">)</span> <span class="p">{</span><span class="n">this</span><span class="o">-&gt;</span><span class="n">vmt</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">A_vmt</span><span class="p">;</span> <span class="n">this</span><span class="o">-&gt;</span><span class="n">a</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;}</span>
</span><span class='line'><span class="kt">void</span> <span class="nf">A_update</span><span class="p">(</span><span class="n">A</span><span class="o">*</span> <span class="n">this</span><span class="p">)</span> <span class="p">{</span><span class="n">this</span><span class="o">-&gt;</span><span class="n">a</span><span class="o">++</span><span class="p">;}</span>
</span><span class='line'><span class="kt">int</span> <span class="nf">A_access</span><span class="p">(</span><span class="n">A</span><span class="o">*</span> <span class="n">this</span><span class="p">)</span> <span class="p">{</span><span class="n">this</span><span class="o">-&gt;</span><span class="n">vmt</span><span class="o">-&gt;</span><span class="n">update</span><span class="p">(</span><span class="n">this</span><span class="p">);</span> <span class="k">return</span> <span class="n">this</span><span class="o">-&gt;</span><span class="n">a</span><span class="p">;}</span>
</span><span class='line'>
</span><span class='line'><span class="cm">/*</span>
</span><span class='line'><span class="cm">class B: public A {</span>
</span><span class='line'><span class="cm">public:</span>
</span><span class='line'><span class="cm">    void update() {a--;}</span>
</span><span class='line'><span class="cm">};</span>
</span><span class='line'><span class="cm">*/</span>
</span><span class='line'>
</span><span class='line'><span class="k">struct</span> <span class="n">B</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">void</span> <span class="p">(</span><span class="o">*</span><span class="n">B</span><span class="p">)(</span><span class="k">struct</span> <span class="n">B</span><span class="o">*</span><span class="p">);</span>
</span><span class='line'>    <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">update</span><span class="p">)(</span><span class="k">struct</span> <span class="n">B</span><span class="o">*</span><span class="p">);</span>
</span><span class='line'>    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">access</span><span class="p">)(</span><span class="k">struct</span> <span class="n">A</span><span class="o">*</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span> <span class="n">B_functable</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="n">B</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">A</span> <span class="n">inherited</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span> <span class="n">B</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">B_B</span><span class="p">(</span><span class="n">B</span> <span class="o">*</span><span class="n">this</span><span class="p">);</span>
</span><span class='line'><span class="kt">void</span> <span class="nf">B_update</span><span class="p">(</span><span class="n">B</span><span class="o">*</span> <span class="n">this</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="n">B_functable</span> <span class="n">B_vmt</span> <span class="o">=</span> <span class="p">{</span><span class="n">B_B</span><span class="p">,</span> <span class="n">B_update</span><span class="p">,</span> <span class="n">A_access</span><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">B_B</span><span class="p">(</span><span class="n">B</span> <span class="o">*</span><span class="n">this</span><span class="p">)</span> <span class="p">{</span><span class="n">A_A</span><span class="p">(</span><span class="n">this</span><span class="p">);</span> <span class="n">this</span><span class="o">-&gt;</span><span class="n">inherited</span><span class="p">.</span><span class="n">vmt</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">B_vmt</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="kt">void</span> <span class="nf">B_update</span><span class="p">(</span><span class="n">B</span><span class="o">*</span> <span class="n">this</span><span class="p">)</span> <span class="p">{</span><span class="n">this</span><span class="o">-&gt;</span><span class="n">inherited</span><span class="p">.</span><span class="n">a</span><span class="o">--</span><span class="p">;}</span>
</span><span class='line'><span class="kt">int</span> <span class="nf">B_access</span><span class="p">(</span><span class="n">B</span><span class="o">*</span> <span class="n">this</span><span class="p">)</span> <span class="p">{</span><span class="n">this</span><span class="o">-&gt;</span><span class="n">inherited</span><span class="p">.</span><span class="n">vmt</span><span class="o">-&gt;</span><span class="n">update</span><span class="p">(</span><span class="n">this</span><span class="p">);</span> <span class="k">return</span> <span class="n">this</span><span class="o">-&gt;</span><span class="n">inherited</span><span class="p">.</span><span class="n">a</span><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="p">{</span>
</span><span class='line'>    <span class="n">A</span> <span class="n">x</span><span class="p">;</span>
</span><span class='line'>    <span class="n">B</span> <span class="n">y</span><span class="p">;</span>
</span><span class='line'>    <span class="n">A_A</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">B_B</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">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">x</span><span class="p">.</span><span class="n">vmt</span><span class="o">-&gt;</span><span class="n">access</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">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">y</span><span class="p">.</span><span class="n">inherited</span><span class="p">.</span><span class="n">vmt</span><span class="o">-&gt;</span><span class="n">access</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="p">}</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Github Notes]]></title>
    <link href="http://fyou.me/blog/2014/10/16/githubnotes/"/>
    <updated>2014-10-16T17:00:06-04:00</updated>
    <id>http://fyou.me/blog/2014/10/16/githubnotes</id>
    <content type="html"><![CDATA[<h3>Normal Usage</h3>

<figure class='code'><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>
</pre></td><td class='code'><pre><code class=''><span class='line'>git reset --hard 加上要回滚到的那个hash tag
</span><span class='line'>
</span><span class='line'>git init 
</span><span class='line'>
</span><span class='line'>git status
</span><span class='line'>
</span><span class='line'>git add filename
</span><span class='line'>
</span><span class='line'>git add '\*.name'
</span><span class='line'>
</span><span class='line'>git log 
</span><span class='line'>
</span><span class='line'>git remote add origin https://github.com/try-git/try\_git.git
</span><span class='line'>
</span><span class='line'>git push -u origin master  记得加上remote name(origin) 和branch name(master)
</span><span class='line'>
</span><span class='line'>git pull  origin master 
</span><span class='line'>
</span><span class='line'>git diff HEAD
</span><span class='line'>
</span><span class='line'>git add octofamily/octodog.txt
</span><span class='line'>
</span><span class='line'>git diff --staged
</span><span class='line'>
</span><span class='line'>git reset octofamily/octodog.txt 但是文件还会存在
</span><span class='line'>
</span><span class='line'>git checkout -- octocat.txt 回到octocat的last commit时候
</span><span class='line'>
</span><span class='line'>git checkout -- octocat.txt 新建clean up branch , 且同时switch to it
</span><span class='line'>
</span><span class='line'>git branch 
</span><span class='line'>
</span><span class='line'>git rm '\*.txt'
</span><span class='line'>
</span><span class='line'>git commit -m ""
</span><span class='line'>
</span><span class='line'>git checkout master
</span><span class='line'>
</span><span class='line'>git merge clean\_up
</span><span class='line'>
</span><span class='line'>git branch -d clean\_up
</span><span class='line'>
</span><span class='line'>git push</span></code></pre></td></tr></table></div></figure>


<h3>Bvw Learn</h3>

<figure class='code'><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>
</pre></td><td class='code'><pre><code class=''><span class='line'>git clean -f  清除所有untrack的文件
</span><span class='line'>
</span><span class='line'>git add -u 添加所有改动文件
</span><span class='line'>
</span><span class='line'>git checkout -- &lt;filename&gt; 解除单个文件的改动
</span><span class='line'>
</span><span class='line'>git reset 取消add变回untracked file
</span></code></pre></td></tr></table></div></figure>


<h3>Stash</h3>

<figure class='code'><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>
</pre></td><td class='code'><pre><code class=''><span class='line'>git status 查看那些改动
</span><span class='line'>
</span><span class='line'>git stash 将所有改动放进stash
</span><span class='line'>
</span><span class='line'>git stash list 看stash里的东西
</span><span class='line'>
</span><span class='line'>git checkout -b &lt;branch name&gt; 创建新branch
</span><span class='line'>
</span><span class='line'>git stash apply 将所有改动放进去
</span><span class='line'>
</span><span class='line'>//在branch 里修改以后回到master进行merge
</span><span class='line'>
</span><span class='line'>git checkout master
</span><span class='line'>
</span><span class='line'>git merge &lt;branch name&gt;
</span><span class='line'>
</span><span class='line'>git branch -d &lt;branch name&gt;</span></code></pre></td></tr></table></div></figure>


<h3>More</h3>

<p><a href="https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/">Add project to github using command line</a></p>
]]></content>
  </entry>
  
</feed>
