<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>string &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/string/</link>
	<description>Feed of posts on WordPress.com tagged "string"</description>
	<pubDate>Tue, 24 Nov 2009 13:31:23 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[Beberapa Field Calculation yang Umum Digunakan dalam Perhitungan  Field Tipe String]]></title>
<link>http://arcgistip.wordpress.com/2009/11/24/beberapa-field-calculation-yang-umum-digunakan-dalam-perhitungan-field-tipe-string/</link>
<pubDate>Tue, 24 Nov 2009 12:25:11 +0000</pubDate>
<dc:creator>Beni Raharjo</dc:creator>
<guid>http://arcgistip.wordpress.com/2009/11/24/beberapa-field-calculation-yang-umum-digunakan-dalam-perhitungan-field-tipe-string/</guid>
<description><![CDATA[[Field Name]&amp;[Field Name] Menggabungkan beberapa field ke dalam satu field Contoh: [NamaKota]]]></description>
<content:encoded><![CDATA[[Field Name]&amp;[Field Name] Menggabungkan beberapa field ke dalam satu field Contoh: [NamaKota]]]></content:encoded>
</item>
<item>
<title><![CDATA[Tu seras bienvenu chez moi]]></title>
<link>http://zebigbooster.wordpress.com/2009/11/24/tu-seras-bienvenu-chez-moi/</link>
<pubDate>Tue, 24 Nov 2009 05:01:35 +0000</pubDate>
<dc:creator>LittleBigMonster</dc:creator>
<guid>http://zebigbooster.wordpress.com/2009/11/24/tu-seras-bienvenu-chez-moi/</guid>
<description><![CDATA[Euh&#8230; oui. Merci pour l&#8217;accueil, c&#8217;est gentil. Cinq autres photos en regardant la s]]></description>
<content:encoded><![CDATA[Euh&#8230; oui. Merci pour l&#8217;accueil, c&#8217;est gentil. Cinq autres photos en regardant la s]]></content:encoded>
</item>
<item>
<title><![CDATA[cozy]]></title>
<link>http://danipoppins.wordpress.com/2009/11/23/cozy/</link>
<pubDate>Tue, 24 Nov 2009 04:13:17 +0000</pubDate>
<dc:creator>dani poppins</dc:creator>
<guid>http://danipoppins.wordpress.com/2009/11/23/cozy/</guid>
<description><![CDATA[I started this scarf back in late February, right around my birthday, when the wind was still whippi]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I started this scarf back in late February, right around my birthday, when the wind was still whipping and snow was still falling.  I finished it late April just in time for spring to peep it&#8217;s little head out and my need for much of anything wool fading fast.  While pawing through the stash the other day, I stumbled on it.  just in time&#8230; just in time indeed.</p>
<p><a href="http://www.flickr.com/photos/44241905@N07/4123788668/"><img class="alignnone" src="http://farm3.static.flickr.com/2738/4123788668_25c3bb6357.jpg" alt="" width="500" height="373" /></a></p>
<p>Pattern: <a href="http://www.sheepinthecity.prettyposies.com/archives/000079.html">My So Called Scarf</a></p>
<p>Yarn: worsted weight &#8220;Victoria Patchwork&#8221; spun by my uncle&#8217;s wife</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Quelques photos du Victoria's Secret Fashion Show]]></title>
<link>http://zebigbooster.wordpress.com/2009/11/23/quelques-photos-du-victorias-secret-fashion-show/</link>
<pubDate>Mon, 23 Nov 2009 17:29:38 +0000</pubDate>
<dc:creator>LittleBigMonster</dc:creator>
<guid>http://zebigbooster.wordpress.com/2009/11/23/quelques-photos-du-victorias-secret-fashion-show/</guid>
<description><![CDATA[Voilà, ça s&#8217;est passé à New-York le 19 novembre. Il y avait Candice Swanepoel, Doutzen Kroes, ]]></description>
<content:encoded><![CDATA[Voilà, ça s&#8217;est passé à New-York le 19 novembre. Il y avait Candice Swanepoel, Doutzen Kroes, ]]></content:encoded>
</item>
<item>
<title><![CDATA[Le jour où j'ai chopé]]></title>
<link>http://ungrenoblois.wordpress.com/2009/11/23/le-jour-ou-jai-chope/</link>
<pubDate>Sun, 22 Nov 2009 23:32:26 +0000</pubDate>
<dc:creator>Grenoblois</dc:creator>
<guid>http://ungrenoblois.wordpress.com/2009/11/23/le-jour-ou-jai-chope/</guid>
<description><![CDATA[L&#8217;évènement inter-planétaire, à reléguer la main de Thierry Henry au rang des faits divers, s]]></description>
<content:encoded><![CDATA[L&#8217;évènement inter-planétaire, à reléguer la main de Thierry Henry au rang des faits divers, s]]></content:encoded>
</item>
<item>
<title><![CDATA[String To Boolean for Grid Control]]></title>
<link>http://thepebkac.wordpress.com/2009/11/22/string-to-boolean-for-grid-control/</link>
<pubDate>Sun, 22 Nov 2009 06:37:53 +0000</pubDate>
<dc:creator>thepebkac</dc:creator>
<guid>http://thepebkac.wordpress.com/2009/11/22/string-to-boolean-for-grid-control/</guid>
<description><![CDATA[I always have to hunt down the snippet in some other project, of which I can never remember which, t]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I always have to hunt down the snippet in some other project, of which I can never remember which, to do this. So, as I said in my intro post &#8211; This is where I store snippets of code to do things.</p>
<p>checked=&#8217;&#60;%# Eval(&#8220;Required&#8221;).ToString().ToLower().Equals(&#8220;true&#8221;)?Convert.ToBoolean(&#8220;True&#8221;):Convert.ToBoolean(&#8220;False&#8221;) %&#62;&#8217;</p>
<p>To bind a boolean value requires a small trick. I&#8217;ve seen other methods of doing this, I just find this one to be the most elegant and adaptable.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[deux]]></title>
<link>http://danipoppins.wordpress.com/2009/11/21/deux/</link>
<pubDate>Sun, 22 Nov 2009 03:08:31 +0000</pubDate>
<dc:creator>dani poppins</dc:creator>
<guid>http://danipoppins.wordpress.com/2009/11/21/deux/</guid>
<description><![CDATA[Pattern:  Saartje&#8217;s Bootees (ravelry link) Yarn: wool, hand spun by my uncle&#8217;s wife (can]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://www.flickr.com/photos/44241905@N07/4123788762/"><img class="alignnone" src="http://farm3.static.flickr.com/2745/4123788762_100d769f8a.jpg" alt="" width="500" height="334" /></a></p>
<p>Pattern:  <a href="http://www.ravelry.com/patterns/library/saartjes-bootees">Saartje&#8217;s Bootees</a> (ravelry link)</p>
<p>Yarn: wool, hand spun by my uncle&#8217;s wife (can you see the subtle iridescent flecks?)</p>
<p>Needles: size 2</p>
<p>Hand Model: Hopper</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Is std::string's storage contiguous?]]></title>
<link>http://debugfailure.wordpress.com/2009/11/20/is-stdstrings-storage-contiguous/</link>
<pubDate>Sat, 21 Nov 2009 04:58:05 +0000</pubDate>
<dc:creator>systemfault</dc:creator>
<guid>http://debugfailure.wordpress.com/2009/11/20/is-stdstrings-storage-contiguous/</guid>
<description><![CDATA[Take a look at the following code: #include &lt;cstddef&gt; #include &lt;cstring&gt; #include &lt;io]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Take a look at the following code:</p>
<pre class="brush: cpp;">
#include &#60;cstddef&#62;
#include &#60;cstring&#62;
#include &#60;iostream&#62;
#include &#60;string&#62;

/* Dummy recv function */
size_t recv(int socket, void *buffer, size_t length, int flags)
{
 std::memcpy(buffer, &#34;Some stuff&#34;, 10);
 return 10;
}

int main()
{
 //Create a string with space for some characters
 std::string x(64, char());

 std::cout &#60;&#60; &#34;x.size() = &#34; &#60;&#60; x.size() &#60;&#60; &#34;, x.capacity() = &#34;
           &#60;&#60; x.capacity() &#60;&#60; std::endl;

 //filling the string with data assuming that &#38;x[0]
 //is pointing at the beginning a contiguous array
 std::size_t bytes_read = recv(0, &#38;x[0], x.size(), 0);

 //Using the good old swap trick to free excess space
 std::string(&#38;x[0], bytes_read).swap(x);

 std::cout &#60;&#60; &#34;x.size() = &#34; &#60;&#60; x.size() &#60;&#60; &#34;, x.capacity() = &#34;
           &#60;&#60; x.capacity() &#60;&#60; std::endl;
 std::cout &#60;&#60; x &#60;&#60; std::endl;
}
</pre>
<p>Is that code&#8230; valid? I always thought it wasn&#8217;t since I heard lots of people telling me that storage for a std::string isn&#8217;t guaranteed to be contiguous (I&#8217;ve yet to see an implementation with storage that isn&#8217;t) so the preceding code would possibly cause undefined behavior. A few days ago, I was on Freenode&#8217;s ##C++ when some guy asked the same question, I was responding him with the  classical answer&#8230; when another guy &#8220;Tinodidriksen&#8221; replied that I was wrong. What?!? What if he&#8217;s right? I mean, I&#8217;ve never actually looked at the standard about it, I only took the usual answer as being the truth. Let&#8217;s see what the standard says about it.</p>
<blockquote><p><strong>1) basic_string constructor requirements(See tables 38-43 in the 14882:2003 standard):</strong><br />
Excerpt from table 39: &#8220;<em>data() points at the first element of an allocated copy of rlen consecutive elements of the string controlled by str beginning at position pos&#8221;, rlen being equal to size() according to the same table.</em></p></blockquote>
<blockquote><p><strong>2) 21.3.4 paragraph 1, basic_string indexed access:</strong><br />
&#8220;<em>Returns: If pos &#60; size(), returns data()[pos]. Otherwise, if pos == size(), the const version returns charT().</em>&#8220;</p></blockquote>
<blockquote><p><strong>3) 21.3.6 paragraph 4, const charT* data() const:</strong><br />
&#8220;<em>Requires: The program shall not alter any of the values stored in the character array.</em>&#8220;</p></blockquote>
<p>Well, these are the three relevant excerpts I found, the first one guarantees that the storage is contiguous because it&#8217;s allocated in a single block of X consecutive elements. The second proves that when you modify the string using the index operator, it modifies the buffer pointed by data(). (data() in that specific sentence is probably meaning the pointer to the underlying storage and not the data() member function itself since using it would force the implementor to use an ugly const cast and would violate the third and last point).</p>
<p>My conclusion, the standard does not say explicitly &#8220;std::basic_string must have contiguous storage&#8221; like std::vector (ISO/IEC 14882:2003 only) but there are enough constraints available to state that it can&#8217;t be otherwise. If I missed something or you have a different opinion, I&#8217;d love to hear it.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Micro Bikini - String Bikini Dos and Don'ts]]></title>
<link>http://mygiginas.wordpress.com/2009/11/21/micro-bikini-string-bikini-dos-and-donts/</link>
<pubDate>Sat, 21 Nov 2009 00:43:23 +0000</pubDate>
<dc:creator>jaydcaswell1234</dc:creator>
<guid>http://mygiginas.wordpress.com/2009/11/21/micro-bikini-string-bikini-dos-and-donts/</guid>
<description><![CDATA[It may seem like choosing a micro bikini (or string bikini) is a no brainer, especially since micro ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>It may seem like choosing a micro bikini (or string bikini) is a no brainer, especially since micro bikinis cover very little of your body. But there are some things you should be aware of when choosing string bikinis.</p>
<p>Dos</p>
<p>As with choosing any type of apparel, color is very important. Make sure, when picking which string bikini you want, that your string bikini compliments your skin color. Don&#8217;t know how? Warmer colors don&#8217;t look so hot on tanned bodies, but rather lighter skin. Solid bikinis look good on some people, while mixed designs look better on others.</p>
<p>Since you&#8217;re going to be wearing your micro bikini in public, it&#8217;s important that it fits you properly and does not fall down. Since micro bikinis are built with straps, they will most likely be able to adjust to the shape of your body.</p>
<p>One of the most important things you&#8217;ll need to do when wearing a string bikini is wax. If you can see hair in those areas of yours that you&#8217;re trying to sport around, it can be quite a nasty turn off. You can get a wax at your local salon or buy DIY waxing supplies and, well, DIY.</p>
<p>Also be sure to check if the micro bikini covers a good area of your real, that is, if you&#8217;re not wearing a g-string type of micro bikini. If you&#8217;re not, make sure the micro bikini doesn&#8217;t ride up (how uncomfortable) by sitting, walking around, and doing other activities you might do while casually wearing a micro bikini. If you are wearing a g-string style micro bikini, make sure you look yourself over in a three way mirror.</p>
<p>Be sure to mix and match string bikini tops and bottoms as well. You just may find the perfect complimenting pair of pieces by searching for the right amount of time.</p>
<p>Don&#8217;ts</p>
<p>Don&#8217;t hold onto your string bikini if it&#8217;s showing its age. That is a serious fashion problem and can sometimes lead to discomfort. This is due particularly to the fact that your string bikini has been through salt water, chlorine, and other degrading substances. This also can weaken the elasticity of the strings, making you want to tie the bikini tighter. That can lead to the strings breaking and possibly having the string bikini fall off you.</p>
<p>Do not forget your SPF. Apply it to every area of your body, even under your strings as they may move around and expose different places of your body. Burns are not attractive, nor are they in style.</p>
<p>If you don&#8217;t think you look good in your string bikini, or you are un-confident when wearing it, don&#8217;t wear it. Consider other pieces of lingerie besides string bikinis.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[evening]]></title>
<link>http://danipoppins.wordpress.com/2009/11/20/evening/</link>
<pubDate>Sat, 21 Nov 2009 00:13:00 +0000</pubDate>
<dc:creator>dani poppins</dc:creator>
<guid>http://danipoppins.wordpress.com/2009/11/20/evening/</guid>
<description><![CDATA[Inter-Library Loan&#8230; felted bag that usually houses my camera as an impromptu knitting bag]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://www.flickr.com/photos/44241905@N07/4120297933/"><img class="alignnone" src="http://farm3.static.flickr.com/2763/4120297933_23c7f50144.jpg" alt="" width="500" height="334" /></a></p>
<p>Inter-Library Loan&#8230; felted bag that usually houses my camera as an impromptu knitting bag&#8230; putting the finishing touches on the second pair of <a href="http://www.saartjeknits.nl/">bootees</a>&#8230; listening to <a href="http://marcscibilia.com/">Marc Scibilia</a>&#8230; a quiet dinner of herbed salmon with the Man&#8230; readying for Hopper and Pip to come home tomorrow.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[String]]></title>
<link>http://contrasdiana.wordpress.com/2009/11/20/string-7/</link>
<pubDate>Fri, 20 Nov 2009 20:37:48 +0000</pubDate>
<dc:creator>Contras</dc:creator>
<guid>http://contrasdiana.wordpress.com/2009/11/20/string-7/</guid>
<description><![CDATA[1.Să se scrie un program care citeşte un text de la tastatură şi îl traduce în limba păsărească astf]]></description>
<content:encoded><![CDATA[1.Să se scrie un program care citeşte un text de la tastatură şi îl traduce în limba păsărească astf]]></content:encoded>
</item>
<item>
<title><![CDATA[Online communities]]></title>
<link>http://matthiessenandmay.wordpress.com/2009/11/20/crochet-pencil-case/</link>
<pubDate>Fri, 20 Nov 2009 15:15:27 +0000</pubDate>
<dc:creator>matthiessenandmay</dc:creator>
<guid>http://matthiessenandmay.wordpress.com/2009/11/20/crochet-pencil-case/</guid>
<description><![CDATA[Lately, have been in search of ways to connect with artists in my community. Numerous blogs have poi]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Lately,  have been in search of ways to connect with artists in my community. Numerous blogs have pointed me in the direction of <a href="https://www.ravelry.com/">Ravelry</a> which is knit and crochet online community. You can share projects, patterns, patterns and tips. A very useful resource if you are a beginner to knitting and crocheting. My specialty is i sewing, but I would love to learn how to crochet.  That led me to a small local <a href="http://www.stitchyourartout.com/">studio</a> that offers classes on quilting, sewing, knitting and crocheting. I came across these fabulous examples on <a href="http://www.flickr.com">flickr </a> of how simple and beautiful the patterns can be. The bold colors are delicious&#8230;</p>
<div style="text-align:left;padding:3px;">
<a href="http://www.flickr.com/photos/cornflowerbluestudio/2415691189/" title="photo sharing"><img src="http://farm4.static.flickr.com/3272/2415691189_ac114c2b34.jpg" style="border:solid 2px #000000;" alt="" /></a><br />
<br />
<span style="font-size:.8em;margin-top:0;"><a href="http://www.flickr.com/photos/cornflowerbluestudio/2415691189/">crochet pencil case</a>, originally uploaded by <a href="http://www.flickr.com/people/cornflowerbluestudio/">cornflowerbluestudio</a>.</span>
</div>
</p>
<div style="text-align:left;padding:3px;">
<a href="http://www.flickr.com/photos/lindsaystreemdesigns/254410378/" title="photo sharing"><img src="http://farm1.static.flickr.com/122/254410378_a3e127163a.jpg" style="border:solid 2px #000000;" alt="" /></a><br />
<br />
<span style="font-size:.8em;margin-top:0;"><a href="http://www.flickr.com/photos/lindsaystreemdesigns/254410378/">Flower Harvest Crocheted Brooch</a>, originally uploaded by <a href="http://www.flickr.com/people/lindsaystreemdesigns/">lindsaystreem</a>.</span>
</div>
</p>
<div style="text-align:left;padding:3px;">
<a href="http://www.flickr.com/photos/shutterkate/3472316086/" title="photo sharing"><img src="http://farm4.static.flickr.com/3401/3472316086_203ee9a243.jpg" style="border:solid 2px #000000;" alt="" /></a><br />
<br />
<span style="font-size:.8em;margin-top:0;"><a href="http://www.flickr.com/photos/shutterkate/3472316086/">Crocheted Tea Mug Cozy</a>, originally uploaded by <a href="http://www.flickr.com/people/shutterkate/">KnitStorm</a>.</span>
</div></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Beaded jewelry - Beaded earrings or Earrings for bellydance]]></title>
<link>http://mybeading.wordpress.com/2009/11/20/beaded-jewelry-beaded-earrings-or-earrings-for-bellydance/</link>
<pubDate>Fri, 20 Nov 2009 11:51:30 +0000</pubDate>
<dc:creator>Katerinka</dc:creator>
<guid>http://mybeading.wordpress.com/2009/11/20/beaded-jewelry-beaded-earrings-or-earrings-for-bellydance/</guid>
<description><![CDATA[Today we&#8217;ll make such interesting laced earrings: Maybe the colour of earrings is not very nic]]></description>
<content:encoded><![CDATA[Today we&#8217;ll make such interesting laced earrings: Maybe the colour of earrings is not very nic]]></content:encoded>
</item>
<item>
<title><![CDATA[An iPhone photo: Body language ...]]></title>
<link>http://djmobilepics.wordpress.com/2009/11/20/an-iphone-photo-body-language/</link>
<pubDate>Fri, 20 Nov 2009 05:24:15 +0000</pubDate>
<dc:creator>dominiquejames</dc:creator>
<guid>http://djmobilepics.wordpress.com/2009/11/20/an-iphone-photo-body-language/</guid>
<description><![CDATA[This says it all.]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><div class="pp_items">
<div class="pp_item" align="center"><img src="http://static.pixelpipe.com/06db7ce8-2405-449e-b8aa-e0526c616b69_b.jpg" style="max-width:100%;" />
<p>This says it all.</p>
</div>
</div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[notion]]></title>
<link>http://danipoppins.wordpress.com/2009/11/19/notion/</link>
<pubDate>Fri, 20 Nov 2009 01:52:30 +0000</pubDate>
<dc:creator>dani poppins</dc:creator>
<guid>http://danipoppins.wordpress.com/2009/11/19/notion/</guid>
<description><![CDATA[My favorite church rummage sale was a few weeks back.  Among other things, I came home with this pil]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>My favorite church rummage sale was a few weeks back.  Among other things, I came home with this pile of goodies&#8230;</p>
<p><a href="http://www.flickr.com/photos/44241905@N07/4118880352/"><img class="alignnone" src="http://farm3.static.flickr.com/2743/4118880352_22b52b91f3.jpg" alt="" width="500" height="313" /></a></p>
<p>Check out all the sew on snaps&#8230; can you read the description&#8230; one dozen for ten cents.  And the pearly belt fastener&#8230; swoon.</p>
<p>Two of my favorites in the bunch&#8230; not so much for function, but form&#8230;</p>
<p><a href="http://www.flickr.com/photos/44241905@N07/4118110983/"><img class="alignnone" src="http://farm3.static.flickr.com/2746/4118110983_e6a1b9a656.jpg" alt="" width="500" height="313" /></a></p>
<p>The cardboard bi-fold once contained needles and a needle threader.  How spiffy is that? Love the dad and his pipe.  And peeking out over on the left there&#8230; that trim.  I might have actually squealed out loud when I came across it.  Can&#8217;t you see it at the bottom of a sweet cotton dress or skirt for Hopper?</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[String]]></title>
<link>http://contrasdiana.wordpress.com/2009/11/19/string-6/</link>
<pubDate>Thu, 19 Nov 2009 20:12:31 +0000</pubDate>
<dc:creator>Contras</dc:creator>
<guid>http://contrasdiana.wordpress.com/2009/11/19/string-6/</guid>
<description><![CDATA[Probleme string:problemestring Se citesc de la tastatură 2 cuvinte şi o valoare p. Să se verifice da]]></description>
<content:encoded><![CDATA[Probleme string:problemestring Se citesc de la tastatură 2 cuvinte şi o valoare p. Să se verifice da]]></content:encoded>
</item>
<item>
<title><![CDATA[I Love Wine Coolers!]]></title>
<link>http://thereifixedit.com/2009/11/19/i-love-wine-coolers/</link>
<pubDate>Thu, 19 Nov 2009 20:00:11 +0000</pubDate>
<dc:creator>Ms. Fix-It</dc:creator>
<guid>http://thereifixedit.com/2009/11/19/i-love-wine-coolers/</guid>
<description><![CDATA[Submitted by: Sergey M via Submit a Kludge! Favorite Comment: Fixer Daniel says, &#8220;And after yo]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p class='mine_asset assetid_2832616960'><img src='http://thereifixedit.files.wordpress.com/2009/11/129025059540051279.jpg' title='I Love Wine Coolers!' alt='I Love Wine Coolers!' /></p>
</p>
<p> Submitted by: Sergey M via <a href='http://thereifixedit.com/submit' rel='nofollow'>Submit a Kludge!</a></p>
<p><strong>Favorite Comment:</strong> Fixer Daniel says,<em> &#8220;And after you drink them you hang them again and they double as air fresheners.&#8221;</em></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Beyoncé garde son string mais perd ses seins]]></title>
<link>http://zebigbooster.wordpress.com/2009/11/19/beyonce-garde-son-string-mais-perd-ses-seins/</link>
<pubDate>Thu, 19 Nov 2009 18:00:20 +0000</pubDate>
<dc:creator>LittleBigMonster</dc:creator>
<guid>http://zebigbooster.wordpress.com/2009/11/19/beyonce-garde-son-string-mais-perd-ses-seins/</guid>
<description><![CDATA[Comme vous le savez, les stars aiment dévoiler certaines parties de leur corps. Elles le font car el]]></description>
<content:encoded><![CDATA[Comme vous le savez, les stars aiment dévoiler certaines parties de leur corps. Elles le font car el]]></content:encoded>
</item>
<item>
<title><![CDATA[IntereString: String Vs string, == or .Equals, @, Stringbuilder ]]></title>
<link>http://bishoponvsto.wordpress.com/2009/11/19/interestring-string-vs-string-or-equals-stringbuilder/</link>
<pubDate>Thu, 19 Nov 2009 15:27:48 +0000</pubDate>
<dc:creator>bishoponvsto</dc:creator>
<guid>http://bishoponvsto.wordpress.com/2009/11/19/interestring-string-vs-string-or-equals-stringbuilder/</guid>
<description><![CDATA[A lot of my C# development time involves working with and manipulating strings (a task common to mos]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>A lot of my C# development time involves working with and manipulating strings (a task common to most programmers). Here are some short answers to a few issues/questions I came accross:</p>
<p><strong>String vs string</strong><br />
Lower case <em>string</em> is simply an alias for <em>System.String</em> in the .NET Framework.</p>
<p><strong>== or .Equals</strong><br />
A rule of thumb is that for almost all reference types e.g. objects, use Equals when you want to test <em>equality</em>.  == compares whether two references (i.e. object instances) refer to the same object.<br />
Primitive types can be compared for equality using ==, but in the case of strings, the variables on each side of the operators must be of type string.<br />
Have a look at the following code and output, taken from Jon Skeet&#8217;s <a href="http://blogs.msdn.com/csharpfaq/archive/2004/03/29/102224.aspx">blog</a>.</p>
<pre class="brush: csharp;">

using System;

public class Test
{
	static void Main()
	{
        // Create two equal but distinct strings
        string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
        string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'});

        Console.WriteLine (a==b);
        Console.WriteLine (a.Equals(b));

        // Now let's see what happens with the same tests but
        // with variables of type object
        object c = a;
        object d = b;

        Console.WriteLine (c==d);
        Console.WriteLine (c.Equals(d));
    }
}
The results are: 

True
True
False
True
</pre>
<p><strong>@ before a string</strong><br />
Using @ before a string means the escape sequences are not processed. This making it easier to write fully qualified path names for example.<br />
@&#8221;c:\Docs\Source\a.txt&#8221;  // rather than &#8220;c:\\Docs\\Source\\a.txt&#8221;</p>
<p><strong>Stringbuilder</strong><br />
String objects are immutable, and so editing them, using Replace for example, results in a entirely new string being created, with new memory allocation. The original string is left intact in memory.<br />
The StringBuilder class is designed for situations when one needs to work with a single string and make an arbitrary number of iterative changes to it. New memory allocation is not needed.</p>
<p>Hope this helps, cos it helped me!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[SQL – How To Check If A String Contains Numbers]]></title>
<link>http://robbamforth.wordpress.com/2009/11/19/sql-%e2%80%93-how-to-check-if-a-string-contains-numbers/</link>
<pubDate>Thu, 19 Nov 2009 13:46:49 +0000</pubDate>
<dc:creator>Rob Bamforth</dc:creator>
<guid>http://robbamforth.wordpress.com/2009/11/19/sql-%e2%80%93-how-to-check-if-a-string-contains-numbers/</guid>
<description><![CDATA[Use the PATINDEX function to check for an integer value continued in the string. If PATINDEX returns]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Use the PATINDEX function to check for an integer value continued in the string.</p>
<p>If PATINDEX returns a value greater than 0 then the string does contain an integer, you can use PATINDEX to determine the position of the integer within the string.</p>
<p>If PATINDEX is not greater than zero then the string does not contain an integer value.</p>
<blockquote><p>DECLARE @string varchar(50)<br />
SET @string = &#8216;this is a string with numb3rs in it&#8217;</p>
<p>IF PATINDEX(&#8216;%[0-9]%&#8217;,@string) &#62; 0 <br />
      PRINT &#8216;YES, The string has contains the number &#8216; +<br />
                  substring(@string,PATINDEX(&#8216;%[0-9]%&#8217;,@string),1) +<br />
                  &#8216; at position &#8216; +<br />
                  cast(PATINDEX(&#8216;%[0-9]%&#8217;,@string) as char)<br />
ELSE <br />
      PRINT &#8216;NO, The string does not have numbers&#8217;</p></blockquote>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[String Distance and Refactoring in Scala]]></title>
<link>http://oldfashionedsoftware.com/2009/11/19/string-distance-and-refactoring-in-scala/</link>
<pubDate>Thu, 19 Nov 2009 05:19:04 +0000</pubDate>
<dc:creator>Matt</dc:creator>
<guid>http://oldfashionedsoftware.com/2009/11/19/string-distance-and-refactoring-in-scala/</guid>
<description><![CDATA[Here&#8217;s a three-for-one special for you: A post about implementing the Levenshtein string dista]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Here&#8217;s a three-for-one special for you: A post about implementing the Levenshtein string distance algorithm in Scala AND refactoring it from an imperative style to a functional style AND I even throw in a short lesson on memoization. To make sure that our refactoring is correct and preserves the expected behavior, I&#8217;ll unit test the code along the way using ScalaTest. ScalaCheck, JUnit, or TestNG would work just as well, but I used ScalaTest.</p>
<h2>First Things First</h2>
<p>&#8220;What, exactly,&#8221; some of you may be asking, &#8220;is Levenshtein string distance?  Some kind of Teutonic tailoring terminology?&#8221; Not at all.  It&#8217;s a way of measuring how alike or different two strings of symbols are.  For example, the string &#8220;sturgeon&#8221; is a lot more similar to &#8220;surgeon&#8221; than to &#8220;urgently&#8221;.  &#8220;Sturgeon&#8221; and &#8220;surgeon&#8221; are only a single letter (t) apart.  They have a string distance of 1.  &#8220;Sturgeon&#8221; and &#8220;urgently&#8221; share some letters, but each has some letters not present in the other.  So what&#8217;s their string distance?  It&#8217;s not so obvious now.</p>
<p>String distance is useful.  The use that most quickly springs to mind is spelling correction.  If I type &#8220;computwr&#8221; a string distance algoritm could tell us that &#8220;computwr&#8221; is very close to the dictionary word &#8220;computer&#8221;.  But there&#8217;s more to it than that.  There are a lot of fuzzy problems in which you want to find which two sets of complex data are most similar.  One way to solve a problem like that is to encode it into a string compare using string distance.  For example, you could write a program to find pen strokes in an image and encode their shapes (up, curve left, down, angle right, etc) as a string which could be compared to known encodings for handwritten letters.  By finding the closest matches you can create a handwriting recognition program.  String distance is useful in DNA analysis, of course, recognizing patterns in signals, and a host of other situations.</p>
<p>The Levenshtein string distance algorithm was developed by Vladimir Levenshtein in 1965.  It can easily tell us the distance from &#8220;sturgeon&#8221; to &#8220;urgently&#8221;.  This algorithm breaks down string transformation into three basic operations:  adding a character, deleting a character, and replacing a character.  Each of these operations is assigned a cost, usually a cost of 1 for each operation.  Leaving a character unchanged has a cost of 0.  So to go from &#8220;sturgeon&#8221; to &#8220;surgeon&#8221; you leave the &#8220;s&#8221; unchanged for a cost of 0.  Then you add a &#8220;t&#8221; for a cost of 1.  All the other letters also remained unchanged, so the total cost is 1, just as we expected.</p>
<p>To change &#8220;sturgeon&#8221; to &#8220;urgently&#8221; is harder.  They have the same number of letters, so we could just do a replacement on each one for a distance of 8.  But is that the shortest distance?  What if we try to re-use that &#8220;urge&#8221; from &#8220;sturgeon&#8221;?  Can we re-use the &#8220;n&#8221;?  Does that help?  What about the &#8220;t&#8221;?  We need an algorithm that we can follow.</p>
<h2>The Grid</h2>
<p>What we need is a way to find the cheapest combination of operations which changes the first string to the second.  That&#8217;s the Levenshtein algorithm.  It works like this.  Write the first string vertically from top to bottom.  To the right of each letter write 1, 2, 3, etc.  Write a 0 above the number 1.  Then write the second string horizontally and again add the numbers 1, 2, 3 etc. to the right of the 0.  It will look something like this:</p>
<pre class="brush: python;">
    u r g e n t l y
  0 1 2 3 4 5 6 7 8
s 1
t 2
u 3
r 4
g 5
e 6
o 7
n 8
</pre>
<p>That&#8217;s the first step.  The grid remains un-filled-in at this point.  Can you guess what the grid positions are going to hold?  They are going to hold the cost to convert the various prefixes of &#8220;sturgeon&#8221; to the various prefixes of &#8220;urgently&#8221;.  The position at the intersection of row r4, and the column a2, for example, will contain the cost to convert &#8220;stur&#8221; to &#8220;ur&#8221;.  We fill in these positions (left-to-right then top to bottom) with the smallest of the following three numbers:</p>
<ul>
<li>The number above the current position plus one.
<li>The number to the left of the current position plus one.
<li>The above-left number if row letter and column letter are the same, or the above-left number plus one otherwise.
</ul>
<p>When we finish, the bottom right corner contains the cost to convert the first string to the second.</p>
<h2>But Why?  (Understanding the Algorithm)</h2>
<p>Those are some shockingly simple rules!  Let&#8217;s examine how they translate into string distance.</p>
<p>First, what are those numbers 0 to n that we write along the top and left?  They&#8217;re not just indices.  The numbers along the top represent the cost to convert the empty string to the various prefixes of &#8220;urgently&#8221;.  The cost is 0 to convert &#8220;&#8221; to &#8220;&#8221;, 1 to convert &#8220;&#8221; to &#8220;u&#8221;, 2 to convert &#8220;&#8221; to &#8220;ur&#8221;, and so on.  The numbers on the left are the cost to convert the prefixes of &#8220;sturgeon&#8221; to the the empty string .  &#8220;&#8221; to &#8220;&#8221; is 0, &#8220;s&#8221; to &#8220;&#8221; is 1, and so forth.  These costs are obvious.  The only way to convert &#8220;&#8221; to &#8220;urgently&#8221; is to add eight letters.  There&#8217;s nothing to delete, nothing to replace.  The only way to convert &#8220;sturgeon&#8221; to &#8220;&#8221; is to delete all eight letters.</p>
<p>Each position, as we have established, represents the cost to convert the string of characters down the left side ending in the current row&#8217;s character into the the string of characters along the top ending at the current column&#8217;s character.  Put another way, for any given position let&#8217;s call the current row&#8217;s letter A, and the current column&#8217;s letter B.  If we use a colon (:) to indicate string concatenation then the beginning string, the one along the left of the grid, can be written Prefix1:A.  So for our example word &#8220;sturgeon&#8221; if we look at a position in row e6 then Prefix1 is &#8220;sturg&#8221; and the final letter, which we&#8217;re calling A, is &#8220;e&#8221;.</p>
<p>So, speaking in terms of Prefix1, Prefix2, A, and B, we use the following inputs:</p>
<ul>
<li>The cost to change Prefix1 to Prefix2:<b>B</b> (the number above the current position).
<li>The cost to change Prefix1:<b>A</b> to Prefix2 (the number to the left).
<li>The cost to change Prefix1 to Prefix2 (the above-left number).
</ul>
<p>If we know the costs of these three conversions we can find the cost to change Prefix1:A to Prefix2:B using this logic:</p>
<ul>
<li>We know that if converting Prefix1 to Prefix2:B has a cost of X, then Prefix1:A can be converted to Prefix2:B for the cost of X plus the cost of deleting A, or X + 1.
<li>We know that if converting Prefix1:A to Prefix2 has a cost of Y, then Prefix1:A can be converted to Prefix2:B for the cost of Y plus the cost of adding B, or Y + 1.
<li>We know that if converting Prefix1 to Prefix2 has a cost of Z, then Prefix1:A can be converted to Prefix2:B for the cost of Z plus the cost of replacing A with B, or Z + (0 or 1 depending on whether A = B).
</ul>
<p>If you understand the above logic, then you understand this really neat algorithm.  It&#8217;s a quintessential example of dynamic programming.  The solution is built up by solving simpler problems.  You start with the trivial case of converting to and from the empty string, and then you build up the solution for the prefixes until you have the complete solution.</p>
<p>In the grid&#8217;s initial configuration there is only one location for which we know all three costs and that is row s1, column u1.  That&#8217;s the only space for which all three neighboring values (above, left, and above-left) are populated.  After we fill in this one, there are two more spaces available to us.  Those are (t2, u1) and (s1, r2).  Ordinarily, though, the spaces are populated line by line.</p>
<h2>A Simple Example</h2>
<p>Let&#8217;s do a quick example by hand.  Then we&#8217;ll take a stab at implementing it in code.  What&#8217;s the string distance from &#8220;hat&#8221; to &#8220;tape&#8221;?  First, our empty grid:</p>
<pre class="brush: python;">
    t a p e
  0 1 2 3 4
h 1
a 2
t 3
</pre>
<p>The first space is row h, column t.  The letters are different so our choices are 1 + 1 (above), 1 + 1 (left), or 0 + 1 (above-left).  0 + 1 is the smallest value, so the first space gets populated with 1.  The next space has choices 2 + 1 (above), 1 + 1 (left), or 1 + 1 (above-left).  1 + 1 is the lowest, so we fill in the second space with 2.  Once we finish the row, we have this:</p>
<pre class="brush: python;">
    t a p e
  0 1 2 3 4
h 1 1 2 3 4
a 2
t 3
</pre>
<p>The next space is row a, column t.  Our choices are 1 + 1 (above), 2 + 1 (left), or 1 + 1 (above-left).  1 + 1 is the smallest value, so the space gets populated with 2.  The next space has choices 2 + 1 (above), 2 + 1 (left), or 1 + 0 (above-left).  Why 1 + 0?  Because the above-left value is 1 and both letters for this space are &#8220;a&#8221; so we can replace &#8220;a&#8221; with &#8220;a&#8221; for free.  Go ahead and finish the whole grid.  This is the result:</p>
<pre class="brush: python;">
    t a p e
  0 1 2 3 4
h 1 1 2 3 4
a 2 2 1 2 3
t 3 2 2 2 3
</pre>
<p>The strings &#8220;hat&#8221; and &#8220;tape&#8221; have a distance of 3.</p>
<h2>Some Code, Finally</h2>
<p>As fascinating as Levenshtein distance is, and as much more as there is to say on the topic, the time has come to write some code.  Here&#8217;s a Scala implementation that is very close to the pencil-and-paper approach that we just performed.</p>
<pre class="brush: python;">
import scala.Math.min
import scala.Math.max

object StringDistance {
  def stringDistance(s1: String, s2: String): Int = {
    def minimum(i1: Int, i2: Int, i3: Int) = min(min(i1, i2), i3)

    val dist = new Array[Array[Int]](s1.length + 1, s2.length + 1)

    for (idx &#60;- 0 to s1.length) dist(idx)(0) = idx
    for (jdx &#60;- 0 to s2.length) dist(0)(jdx) = jdx

    for (idx &#60;- 1 to s1.length; jdx &#60;- 1 to s2.length)
      dist(idx)(jdx) = minimum (
        dist(idx-1)(jdx  ) + 1,
        dist(idx  )(jdx-1) + 1,
        dist(idx-1)(jdx-1) + (if (s1(idx-1) == s2(jdx-1)) 0 else 1)
      )

    dist(s1.length)(s2.length)
  }
</pre>
<p>Do you see what I mean when I say it&#8217;s close to the pencil-and-paper approach?  We actually construct a two-dimensional Array to represent the grid we drew earlier.  It&#8217;s a very literal implementation.</p>
<p>To explain the code briefly, we declare a singleton StringDistance having a single method called stringDistance.  Within this method we declare a 3-argument minimum method. (I wonder why there&#8217;s no &#8220;def min(params: Int*): Int&#8221; defined in scala.Math.)  Then we create an array called &#8220;dist&#8221; and populate the top row and leftmost column in lines 8-11.  The for loop on line 13 cycles through each array position from left to right then top to bottom, and populates them according to the Levenshtein logic. Finally, once the grid is filled in we return the number in the bottom right position.</p>
<p>The job&#8217;s not done yet, of course.  We haven&#8217;t written our unit tests.  Here&#8217;s the test I wrote:</p>
<pre class="brush: python;">
import org.scalatest._

class StringDistanceSuite extends FunSuite with PrivateMethodTester {

  test(&#34;stringDistance should work on empty strings&#34;) {
    assert( StringDistance.stringDistance(   &#34;&#34;,    &#34;&#34;) == 0 )
    assert( StringDistance.stringDistance(  &#34;a&#34;,    &#34;&#34;) == 1 )
    assert( StringDistance.stringDistance(   &#34;&#34;,   &#34;a&#34;) == 1 )
    assert( StringDistance.stringDistance(&#34;abc&#34;,    &#34;&#34;) == 3 )
    assert( StringDistance.stringDistance(   &#34;&#34;, &#34;abc&#34;) == 3 )
  }

  test(&#34;stringDistance should work equal strings&#34;) {
    assert( StringDistance.stringDistance(   &#34;&#34;,    &#34;&#34;) == 0 )
    assert( StringDistance.stringDistance(  &#34;a&#34;,   &#34;a&#34;) == 0 )
    assert( StringDistance.stringDistance(&#34;abc&#34;, &#34;abc&#34;) == 0 )
  }

  test(&#34;stringDistance should work where only inserts are needed&#34;) {
    assert( StringDistance.stringDistance(   &#34;&#34;,   &#34;a&#34;) == 1 )
    assert( StringDistance.stringDistance(  &#34;a&#34;,  &#34;ab&#34;) == 1 )
    assert( StringDistance.stringDistance(  &#34;b&#34;,  &#34;ab&#34;) == 1 )
    assert( StringDistance.stringDistance( &#34;ac&#34;, &#34;abc&#34;) == 1 )
    assert( StringDistance.stringDistance(&#34;abcdefg&#34;, &#34;xabxcdxxefxgx&#34;) == 6 )
  }

  test(&#34;stringDistance should work where only deletes are needed&#34;) {
    assert( StringDistance.stringDistance(  &#34;a&#34;,    &#34;&#34;) == 1 )
    assert( StringDistance.stringDistance( &#34;ab&#34;,   &#34;a&#34;) == 1 )
    assert( StringDistance.stringDistance( &#34;ab&#34;,   &#34;b&#34;) == 1 )
    assert( StringDistance.stringDistance(&#34;abc&#34;,  &#34;ac&#34;) == 1 )
    assert( StringDistance.stringDistance(&#34;xabxcdxxefxgx&#34;, &#34;abcdefg&#34;) == 6 )
  }

  test(&#34;stringDistance should work where only substitutions are needed&#34;) {
    assert( StringDistance.stringDistance(  &#34;a&#34;,   &#34;b&#34;) == 1 )
    assert( StringDistance.stringDistance( &#34;ab&#34;,  &#34;ac&#34;) == 1 )
    assert( StringDistance.stringDistance( &#34;ac&#34;,  &#34;bc&#34;) == 1 )
    assert( StringDistance.stringDistance(&#34;abc&#34;, &#34;axc&#34;) == 1 )
    assert( StringDistance.stringDistance(&#34;xabxcdxxefxgx&#34;, &#34;1ab2cd34ef5g6&#34;) == 6 )
  }

  test(&#34;stringDistance should work many operations are needed&#34;) {
    assert( StringDistance.stringDistance(&#34;example&#34;, &#34;samples&#34;) == 3 )
    assert( StringDistance.stringDistance(&#34;sturgeon&#34;, &#34;urgently&#34;) == 6 )
    assert( StringDistance.stringDistance(&#34;levenshtein&#34;, &#34;frankenstein&#34;) == 6 )
    assert( StringDistance.stringDistance(&#34;distance&#34;, &#34;difference&#34;) == 5 )
    assert( StringDistance.stringDistance(&#34;java was neat&#34;, &#34;scala is great&#34;) == 7 )
  }

}
</pre>
<p>It tests several special cases as well as the general case.  All we have to do is compile our StringDistance object and the StringDistanceSuite unit test, fire up the scala interpreter and run the test:</p>
<pre class="brush: python;">
scala&#62; (new StringDistanceSuite).execute()
Test Starting - StringDistanceSuite: recursiveStringDistance should work on empty strings
Test Succeeded - StringDistanceSuite: recursiveStringDistance should work on empty strings
Test Starting - StringDistanceSuite: recursiveStringDistance should work on equal strings
Test Succeeded - StringDistanceSuite: recursiveStringDistance should work on equal strings
Test Starting - StringDistanceSuite: recursiveStringDistance should work where only inserts are needed
Test Succeeded - StringDistanceSuite: recursiveStringDistance should work where only inserts are needed
Test Starting - StringDistanceSuite: recursiveStringDistance should work where only deletes are needed
Test Succeeded - StringDistanceSuite: recursiveStringDistance should work where only deletes are needed
Test Starting - StringDistanceSuite: recursiveStringDistance should work where only substitutions are needed
Test Succeeded - StringDistanceSuite: recursiveStringDistance should work where only substitutions are needed
Test Starting - StringDistanceSuite: stringDistance should work many operations are needed
Test Succeeded - StringDistanceSuite: stringDistance should work many operations are needed

scala&#62;
</pre>
<h2>Refactoring: Reduced Memory Usage</h2>
<p>The code passes all the tests, so let&#8217;s take things a step further.  One shortcoming of our implementation is that it can require a lot of memory.  That array has to be of size (n+1)*(m+1) where n and m are the lengths of the two strings we&#8217;re comparing.  If you want to apply the method to strings that are a few hundred characters long (or longer) then you&#8217;re starting to talk about some serious memory requirements.  How can we reduce the amount of memory required?  Can you think of a way?</p>
<p>Once we complete one row of the grid, we use it again as an input when we compute the next row.  But after that we&#8217;re done with it.  Why leave it to clutter the heap?  Let&#8217;s tweak our implementation slightly.  Try rewriting the method using only two rows.  Fill the first row with the initial 0, 1, 2, etc.  Then use one to compute the other over and over.  Think about how you would implement this, then have a look at my solution below.</p>
<pre class="brush: python;">
  def stringDistance(s1: String, s2: String): Int = {
    def minimum(i1: Int, i2: Int, i3: Int) = min(min(i1, i2), i3)

    var dist = ( new Array[Int](s1.length + 1),
                 new Array[Int](s1.length + 1) )

    for (idx &#60;- 0 to s1.length) dist._2(idx) = idx

    for (jdx &#60;- 1 to s2.length) {
      val (newDist, oldDist) = dist
      newDist(0) = jdx
      for (idx &#60;- 1 to s1.length) {
        newDist(idx) = minimum (
          oldDist(idx) + 1,
          newDist(idx-1) + 1,
          oldDist(idx-1) + (if (s1(idx-1) == s2(jdx-1)) 0 else 1)
        )
      }
      dist = dist.swap
    }

    dist._2(s1.length)
  }
</pre>
<p>This one uses a Pair (also called a Tuple2) containing two one-dimensional arrays, instead of a 2*(n+1) array.  Pair happens to have the very handy &#8220;swap&#8221; method which we can use to trade out the rows when we&#8217;ve finished one and are ready to compute the next.</p>
<p>This is where our unit tests really show their worth. No need to wonder whether this new code really does work.  We just recompile, run the tests again, and we can see that the code still gives us the expected results.</p>
<h2>Refactoring: Recursion, Kind Of</h2>
<p>What are some other ways we could write this code?  Can it be improved?  I thought I would try to replace the iteration in the previous implementations with recursion.  Here&#8217;s what that code looks like:</p>
<pre class="brush: python;">
  def stringDistance(s1: String, s2: String): Int = {
    def newCost(ins: Int, del: Int, subst: Int, c1: Char, c2:Char) =
      Math.min( Math.min( ins+1, del+1 ), subst + (if (c1 == c2) 0 else 1) )

    def getNewCosts(s1: List[Char], c2: Char, delVal: Int, prev: List[Int] ): List[Int] = (s1, prev) match {
      case (c1 :: _ , substVal :: insVal :: _) =&#62;
        delVal :: getNewCosts(s1.tail, c2, newCost(insVal, delVal, substVal, c1, c2), prev.tail)
      case _ =&#62; List(delVal)
    }

    def sd(s1: List[Char], s2: List[Char], prev: List[Int]): Int = s2 match {
      case Nil =&#62; prev.last
      case _ =&#62; sd( s1, s2.tail, getNewCosts(s1, s2.head, prev.head+1, prev) )
    }

    (s1, s2) match {
      case (`s2`, `s1`) =&#62; 0
      case (_, &#34;&#34;) &#124; (&#34;&#34;, _) =&#62; max(s1.length, s2.length)
      case _ =&#62; sd(s1.toList, s2.toList, (0 to s1.length).toList)
    }
  }
</pre>
<p>It&#8217;s a pretty naïve implementation, actually.  It just replaces the the repetition of the two for loops with the repetition of the recursion of the two methods sd and getNewCosts.  The sd method is even tail-recursive, allowing scala to optimize it.  It does the same basic thing as the for loop version, though.  It recurses through the characters of a row in the getNewCosts method, and it recurses through the rows of the grid in the sd method.</p>
<p>It looks more complicated than the previous implementations.  It&#8217;s harder to read.  But it passes our unit tests, so we can be pretty sure it&#8217;s correct.</p>
<h2>Refactoring: List Methods</h2>
<p>After the last implementation, I thought it looked a little sloppy.  I wondered whether I could improve the situation by using some of the many useful methods built into scala&#8217;s List class.  Here is the comparatively brief code that resulted:</p>
<pre class="brush: python;">
  def stringDistance(s1: String, s2: String): Int = {
    def sd(s1: List[Char], s2: List[Char], costs: List[Int]): Int = s2 match {
      case Nil =&#62; costs.last
      case c2 :: tail =&#62; sd( s1, tail,
          (List(costs.head+1) /: costs.zip(costs.tail).zip(s1))((a,b) =&#62; b match {
            case ((rep,ins), chr) =&#62; Math.min( Math.min( ins+1, a.head+1 ), rep + (if (chr==c2) 0 else 1) ) :: a
          }).reverse
        )
    }
    sd(s1.toList, s2.toList, (0 to s1.length).toList)
  }
</pre>
<p>Like I say, it&#8217;s brief.  Those List methods give you a lot of mileage.  </p>
<h2>Refactoring: Real Recursion</h2>
<p>The more I looked at my previous attempt at a recursive solution, the more I realized how hare-brained it was.  It wasn&#8217;t <i>real</i> recursion.  It was just iteration using the stack.  So I went back to the drawing board.  If I want to know the final answer, the value in the bottom right position, how do I get it?  I apply my three rules to the above, left, and above-left positions.  How do I get those positions?  Apply the rules again.  That&#8217;s real recursion.  Here&#8217;s my first stab at it:</p>
<pre class="brush: python;">
  def stringDistance(s1: String, s2: String): Int = {
    def min(a:Int, b:Int, c:Int) = Math.min( Math.min( a, b ), c)
    def sd(s1: List[Char], s2: List[Char]): Int = (s1, s2) match {
      case (_, Nil) =&#62; s1.length
      case (Nil, _) =&#62; s2.length
      case (c1::t1, c2::t2)  =&#62; min( sd(t1,s2) + 1, sd(s1,t2) + 1,
                                     sd(t1,t2) + (if (c1==c2) 0 else 1) )
    }
    sd( s1.toList, s2.toList )
  }
</pre>
<p>Now, THAT is a nice looking recursive function.  That&#8217;s more like it.  See the pattern match block?  If we try to convert from any string to the empty string or from the empty to a non-empty string then we just use the string length.  You see?  That takes care of the positions along the top and left of the grid.  All the others are determined in the last case.  That last case just applies our three rules.  That is so short and simple.  It&#8217;s a thing of beauty.</p>
<p>The only problem?  It doesn&#8217;t work.</p>
<p>It&#8217;s technically correct.  It will return correct answers &#8230; eventually.  Or, rather, I think it will.  I can&#8217;t be sure because it&#8217;s too slow to complete my unit tests! For anything but very short inputs (4 or 5 characters), the function takes a long time to return.  Why?  Let&#8217;s look at how many recursive calls are made for some inputs.</p>
<p>If we pass use strings &#8220;a&#8221; and &#8220;b&#8221; we pass by the &#8220;(_, Nil)&#8221; and &#8220;(Nil, _)&#8221; cases in the first call to function sd, because both our strings (Lists, actually) are non-empty.  This results in three more calls to sd.  Each of these three calls includes an empty List of characters, so there is no more recursion.  That&#8217;s a total of four calls to sd for strings &#8220;a&#8221; and &#8220;b&#8221;.</p>
<p>What about &#8220;ab&#8221; and &#8220;xy&#8221;?  Think about it for a moment?  Step through the function in your head.  How many calls to sd will there be for &#8220;ab&#8221; and &#8220;xy&#8221;?</p>
<p>Have you done it?  I count 19.  What about &#8220;abc&#8221; and &#8220;xyz&#8221;?  I&#8217;ll save you the trouble.  It&#8217;s 94.  For length 4 strings it&#8217;s 481.  For length 5 it&#8217;s 2524.  Length 6 is 13,483.  Then 73 thousand, then 400 thousand, then 2 million and so forth.  Why so many calls?  Each position in the grid is computed using all the positions to the left and all the positions above the current position.  So a position in the top left will be computed and recomputed many times.</p>
<p>There is a way to get around this, of course.  You probably already have some ideas.  We&#8217;re going to do something called memoization.  When you memoize a function, you make it remember results that it computed previously without having to actually recompute them.  I&#8217;ll do that by caching results in a map.  The map&#8217;s key is a Pair of List[Char]s, the inputs to my inner function sd, and its data is an Int, the return type of sd.  I will modify sd to first check the map to see if the result for the current parameters has already been cached.  If so, we simply return it.  If not, we compute the value, cache it, and return it.</p>
<pre class="brush: python;">
  def stringDistance(s1: String, s2: String): Int = {
    val memo = scala.collection.mutable.Map[(List[Char],List[Char]),Int]()
    def min(a:Int, b:Int, c:Int) = Math.min( Math.min( a, b ), c)
    def sd(s1: List[Char], s2: List[Char]): Int = {
      if (memo.contains((s1,s2)) == false)
        memo((s1,s2)) = (s1, s2) match {
          case (_, Nil) =&#62; s1.length
          case (Nil, _) =&#62; s2.length
          case (c1::t1, c2::t2)  =&#62; min( sd(t1,s2) + 1, sd(s1,t2) + 1,
                                         sd(t1,t2) + (if (c1==c2) 0 else 1) )
        }
      memo((s1,s2))
    }

    sd( s1.toList, s2.toList )
  }
}
</pre>
<p>There.  That uglies up my function somewhat, but at least it&#8217;s usable now.  And it passes my unit tests, so I&#8217;m reasonably assured that it&#8217;s right.</p>
<p>Memoization only works if you expect the same result for each identical function call.  If your function takes input from stdin, for example, you can&#8217;t memoize that.  Or if it has a random component.  Or if, for any other reason, its return value is not always the same for the same inputs.  You can memoize functions in different ways.  There&#8217;s a post on <a href="http://michid.wordpress.com/2009/02/23/function_mem/">Michid&#8217;s Weblog</a> about a more general solution, a memoizing class which wraps existing functions to give you a memoized version.  </p>
<h2>PHEW!</h2>
<p>Ok, I&#8217;ve tried to keep my rambling to a minimum in this post but it&#8217;s still a doozy.  The things I wanted to get across are:</p>
<ul>
<li>The usefulness of Levenshtein distance in solving a variety of problems.
<li>How to understand the Levenshtein distance algorithm and why it works.
<li>How to use unit tests to improve your code while maintaining some assurance that the new code still has the correct behavior.
<li>Some of the different ways of implementing Levenshtein.
</ul>
<p>In the end, I think I like the second implementation (the one that switches out the two rows) and the last implementation the best.  The second one seems to have good performance.  I did some informal performance tests and it has a good mix of performance and simplicity.  The last one, the memoized recursive one, appeals to me because it is in a more functional style and still has respectable performance.</p>
<p>
<p style="text-align:right;font-family:Times;">Don&#8217;t forget to <a href="http://oldfashionedsoftware.com/feed/rss"><img src="http://oldfashionedsoftware.com/files/2008/08/rssbutton.png"> subscribe to my RSS feed</a>, or <a href="http://twitter.com/mmofsoftware"><img src="http://oldfashionedsoftware.com/files/2009/08/twitter.png"> follow this blog on Twitter</a>.<br />Copyright © 2009 Matthew Jason Malone</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Alan Davies + String = Happiness]]></title>
<link>http://rebeccagovehumphries.wordpress.com/2009/11/17/alan-davies-string-happiness/</link>
<pubDate>Tue, 17 Nov 2009 22:33:27 +0000</pubDate>
<dc:creator>whiterabbitstudio</dc:creator>
<guid>http://rebeccagovehumphries.wordpress.com/2009/11/17/alan-davies-string-happiness/</guid>
<description><![CDATA[There was a really interesting programme that was on tonight on Channel 2 discussing the science beh]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://rebeccagovehumphries.wordpress.com/files/2009/11/alan-davies.jpg" target="_blank"><img class="size-full wp-image-708 alignnone" title="Alan Davies" src="http://rebeccagovehumphries.wordpress.com/files/2009/11/alan-davies.jpg" alt="" width="500" height="277" /></a></p>
<p>There was a really interesting programme that was on tonight on Channel 2 discussing the science behind the question <a href="http://bbc.co.uk/i/p1fpc/" target="_blank">How long is a piece of string?</a></p>
<p>I definitely shall be having a second viewing as there are quite complex ideas and also, I was distracted by butternut squash and sweet potato soup. I feel Alan Davies deserves your full attention, he did play Jonathan Creek afterall&#8230;(I have the box set and cannot wait for the new episode at Easter!!!).</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Code 015: XSL 1.0 string replace]]></title>
<link>http://sadgfasdhkajsdbhf.wordpress.com/2009/11/17/code-015/</link>
<pubDate>Tue, 17 Nov 2009 07:58:40 +0000</pubDate>
<dc:creator>sadgfasdhkajsdbhf</dc:creator>
<guid>http://sadgfasdhkajsdbhf.wordpress.com/2009/11/17/code-015/</guid>
<description><![CDATA[&lt;xsl:variable name="variable"&gt; &lt;xsl:call-template name="replace-string"&gt; &lt;xsl:with-pa]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><pre>&#60;xsl:variable name="variable"&#62;
 &#60;xsl:call-template name="replace-string"&#62;
 &#60;xsl:with-param name="text" select="..."/&#62;
 &#60;xsl:with-param name="replace" select="..."/&#62;
 &#60;xsl:with-param name="with" select="..."/&#62;
 &#60;/xsl:call-template&#62;
&#60;/xsl:variable&#62;
&#60;!--------------------------------------------------------&#62;
&#60;xsl:template name="replace-string"&#62;
 &#60;xsl:param name="text"/&#62;
 &#60;xsl:param name="replace"/&#62;
 &#60;xsl:param name="with"/&#62;
 &#60;xsl:choose&#62;
  &#60;xsl:when test="contains($text,$replace)"&#62;
   &#60;xsl:value-of select="substring-before($text,$replace)"/&#62;
   &#60;xsl:value-of select="$with"/&#62;
   &#60;xsl:call-template name="replace-string"&#62;
    &#60;xsl:with-param name="text"
     select="substring-after($text,$replace)"/&#62;
    &#60;xsl:with-param name="replace" select="$replace"/&#62;
    &#60;xsl:with-param name="with" select="$with"/&#62;
   &#60;/xsl:call-template&#62;
  &#60;/xsl:when&#62;
  &#60;xsl:otherwise&#62;
   &#60;xsl:value-of select="$text"/&#62;
  &#60;/xsl:otherwise&#62;
 &#60;/xsl:choose&#62;
&#60;/xsl:template&#62;</pre>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[The Unseen]]></title>
<link>http://artbybilge.wordpress.com/2009/11/22/theunseen/</link>
<pubDate>Sun, 22 Nov 2009 11:47:57 +0000</pubDate>
<dc:creator>mirafried</dc:creator>
<guid>http://artbybilge.wordpress.com/2009/11/22/theunseen/</guid>
<description><![CDATA[mixed media, 17 ½ x 11 ¼ inches, undated]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><div id="attachment_13" class="wp-caption alignnone" style="width: 325px"><a href="http://artbybilge.wordpress.com/files/2009/11/friedlander_bilge_the_unseen.jpg"><img class="size-full wp-image-13" title="The Unseen" src="http://artbybilge.wordpress.com/files/2009/11/friedlander_bilge_the_unseen.jpg" alt="Bilge Friedlander, The Unseen," width="315" height="474" /></a><p class="wp-caption-text">mixed media, 17 ½ x 11 ¼ inches, undated</p></div>
</div>]]></content:encoded>
</item>

</channel>
</rss>
