<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Algoritmica</title>
        <link>http://blogs.ugidotnet.org/angellaa/category/Algoritmica.aspx</link>
        <description>Algoritmica</description>
        <language>it-IT</language>
        <copyright>Andrea Angella</copyright>
        <generator>Subtext Version 2.6.0.0</generator>
        <item>
            <title>Algoritmi &amp;ndash; Rimuovere i duplicati da un lista</title>
            <link>http://blogs.ugidotnet.org/angellaa/archive/2010/09/07/algoritmi-ndash-rimuovere-i-duplicati-da-un-lista.aspx</link>
            <description>&lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Problema:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Considerare una semplice classe che implementa una SingleLinkedList non ordinata di interi. Realizzare un metodo per rimuovere tutti i duplicati dalla lista.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Niente&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Niente.    &lt;br /&gt;Internamente gli elementi duplicati saranno rimossi dalla lista.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Esempio:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Lista iniziale:    &lt;br /&gt;1, 1, 1, 1, 3, 4, 5, 3, 5, 1, 2, 1, 2, 3, 4 ,1 , 2, 3, 5, 1, 2, 5, 6, 7, 2, 8, 2, 9, 9&lt;/p&gt;  &lt;p&gt;Lista finale:    &lt;br /&gt;1, 3, 4, 5, 2, 6, 7, 8, 9&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;La struttura dati&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/angellaa/WindowsLiveWriter/AlgoritmiRimuovereiduplicatidaunlista_14D6D/2010-09-06_234517_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="2010-09-06_234517" border="0" alt="2010-09-06_234517" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/angellaa/WindowsLiveWriter/AlgoritmiRimuovereiduplicatidaunlista_14D6D/2010-09-06_234517_thumb.jpg" width="492" height="539" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Il mio ragionamento:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Prendo il valore dell’elemento di testa. Scorro tutti gli elementi successivi. Se uno degli elementi successivi e’ duplicato aggiorno i puntatori in modo da bypassarlo. Ripeto il procedimento per l’elemento successivo della lista e cosi’ via.&lt;/p&gt;  &lt;p&gt;La complessita’ di questo algoritmo e’ O(N^2).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;La mia soluzione:&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:754f8621-b7d8-49b6-a26a-6613c6578526" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; RemoveDuplicates()&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (head == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#2b91af"&gt;Node&lt;/span&gt; p = head;&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;while&lt;/span&gt; (p != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; value = p.Value;&lt;br /&gt; &lt;br /&gt;         &lt;span style="color:#2b91af"&gt;Node&lt;/span&gt; q = p;&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;while&lt;/span&gt; (q.Next != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (q.Next.Value == value) q.Next = q.Next.Next;&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;else&lt;/span&gt; q = q.Next;&lt;br /&gt; &lt;br /&gt;         p = p.Next;&lt;br /&gt;     }&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Una soluzione piu’ efficiente&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Se si utilizza un dizionario e’ possibile portare la complessita’ dell’algoritmo a poco piu’ di O(N)&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c57b06ea-2ca3-41b6-b10a-1fab9f1b05e1" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; RemoveDuplicates_Using_Dictionary()&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (head == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; d = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt;&amp;gt;();&lt;br /&gt;     d[head.Value] = &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#2b91af"&gt;Node&lt;/span&gt; node = head;&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;while&lt;/span&gt; (node.Next != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; value = node.Next.Value;&lt;br /&gt; &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (d.ContainsKey(value))&lt;br /&gt;         {&lt;br /&gt;             node.Next = node.Next.Next;&lt;br /&gt;         }&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;         {&lt;br /&gt;             d[value] = &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;             node = node.Next;&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org/angellaa/aggbug/99162.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Angella</dc:creator>
            <guid>http://blogs.ugidotnet.org/angellaa/archive/2010/09/07/algoritmi-ndash-rimuovere-i-duplicati-da-un-lista.aspx</guid>
            <pubDate>Tue, 07 Sep 2010 01:50:44 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/angellaa/archive/2010/09/07/algoritmi-ndash-rimuovere-i-duplicati-da-un-lista.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/angellaa/comments/commentRss/99162.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/angellaa/services/trackbacks/99162.aspx</trackback:ping>
        </item>
        <item>
            <title>Algoritmi &amp;ndash; Determinare il sottoinsieme pi&amp;ugrave; grande di intervalli mutuamente non sovrapposti</title>
            <link>http://blogs.ugidotnet.org/angellaa/archive/2010/09/05/algoritmi-ndash-determinare-il-sottoinsieme-piugrave-grande-di-intervalli-mutuamente.aspx</link>
            <description>&lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Problema:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Dato un insieme I di n intervalli [a, b] con a e b interi determinare il sottoinsieme piu’ grande di intervalli mutuamente non sovrapposti che possono essere selezionati da I.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Due vettori di n interi che rappresentano l’insieme I.&lt;/p&gt;  &lt;p&gt;a = { a0, a1, … }   &lt;br /&gt;b = { b0, b1, … }&lt;/p&gt;  &lt;p&gt;Ogni intervallo e’ identificato da un numero intero k.&lt;/p&gt;  &lt;p&gt;L’intervallo generico k e’ rappresentato dagli estremi a[k] e b[k].&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Una lista di interi ordinata (List&amp;lt;int&amp;gt;) che contiene gli identificatori degli intervalli che fanno parte del sottoinsieme di interesse.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Esempio:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Input:   &lt;br /&gt;    &lt;br /&gt;&lt;font face="Courier New"&gt;a = { 0,  7, 15, 2,  8, 15, 18, 3, 10, 12, 15, 1, 4,  8, 20 &lt;/font&gt;&lt;font face="Courier New"&gt;};     &lt;br /&gt;b = { 4, 12, 18, 6, 14, 17, 20, 9, 11, 14, 19, 5, 7, 20, 22 };&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;Output:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;{ 0, 5, 6, 8, 9, 12, 14 } oppure     &lt;br /&gt;{ 0, 2, 6, 8, 9, 12, 14 }&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Di seguito i diagrammi che rappresentano i due risultati validi (evidenziati in giallo):&lt;/p&gt;  &lt;p&gt; &lt;a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/angellaa/WindowsLiveWriter/AlgoritmiDeterminareilsottoinsiemepigran_1447/ex1_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="ex1" border="0" alt="ex1" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/angellaa/WindowsLiveWriter/AlgoritmiDeterminareilsottoinsiemepigran_1447/ex1_thumb.jpg" width="908" height="250" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/angellaa/WindowsLiveWriter/AlgoritmiDeterminareilsottoinsiemepigran_1447/ex2_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="ex2" border="0" alt="ex2" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/angellaa/WindowsLiveWriter/AlgoritmiDeterminareilsottoinsiemepigran_1447/ex2_thumb.jpg" width="908" height="257" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Il mio ragionamento:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Per ciascun intervallo determino gli intervalli che si sovrappongono. Ordino quindi gli intervalli in base al numero di sovrapposizioni. Partendo dagli intervalli con il minor numero di sovrapposizioni inizio ad aggiungerli al risultato, scartando a mano a mano gli intervalli sovrapposti.&lt;/p&gt;  &lt;p&gt;La complessita’ di questa soluzione e’ O(N^2).&lt;/p&gt;  &lt;p&gt;Non sono in grado di provare se questa soluzione e’ corretta per qualsiasi istanza del problema.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;La mia soluzione:&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:cbd2e466-421d-4b0a-a33e-9559e007e8f9" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Interval&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; ID { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff"&gt;set&lt;/span&gt;; }&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt; Overlaps { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff"&gt;set&lt;/span&gt;; }&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; IsCandidate { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff"&gt;set&lt;/span&gt;; }&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; Interval(&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; interval)&lt;br /&gt;     {&lt;br /&gt;         ID = interval;&lt;br /&gt;         Overlaps = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;         IsCandidate = &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt; GetBiggestNonOverlappedIntervalSubset(&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] a, &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] b)&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (a == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"a"&lt;/span&gt;);&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (b == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"b"&lt;/span&gt;);&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (a.Length != b.Length) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"a and b must have the same length"&lt;/span&gt;);&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; n = a.Length;&lt;br /&gt;     &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt; results = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#2b91af"&gt;Interval&lt;/span&gt;[] intervals = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Interval&lt;/span&gt;[n];&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; n; ++i) &lt;br /&gt;         intervals[i] = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Interval&lt;/span&gt;(i);&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; n; ++i)&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; j = i + 1; j &amp;lt; n; ++j)&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (a[i] &amp;lt; b[j] &amp;amp;&amp;amp; a[j] &amp;lt; b[i])&lt;br /&gt;             {&lt;br /&gt;                 intervals[i].Overlaps.Add(j);&lt;br /&gt;                 intervals[j].Overlaps.Add(i);&lt;br /&gt;             }&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#2b91af"&gt;Array&lt;/span&gt;.Sort&amp;lt;&lt;span style="color:#2b91af"&gt;Interval&lt;/span&gt;&amp;gt;(intervals, (info1, info2) =&amp;gt; info1.Overlaps.Count - info2.Overlaps.Count);&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; n; ++i)&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (intervals[i].IsCandidate)&lt;br /&gt;         {&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; newInterval = intervals[i].ID;&lt;br /&gt;             results.Add(newInterval);&lt;br /&gt; &lt;br /&gt;             &lt;span style="color:#0000ff"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; j = i + 1; j &amp;lt; n; ++j)&lt;br /&gt;                 &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (intervals[j].Overlaps.Contains(newInterval))&lt;br /&gt;                     intervals[j].IsCandidate = &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;                    &lt;br /&gt;         }&lt;br /&gt; &lt;br /&gt;     results.Sort();&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; results;&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p /&gt;  &lt;p /&gt;  &lt;p&gt;&lt;strong&gt;I miei test:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Un problema piu’ complesso come questo richiede la presenza di qualche test automatico.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c38d8961-d9a9-4520-94b2-be985b3a9fd0" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;[&lt;span style="color:#2b91af"&gt;TestMethod&lt;/span&gt;()]&lt;br /&gt; &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; GetBiggestNonOverlappedIntervalSubsetTest_DisjointedIntervals()&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] a = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] { 0, 6, 10 };&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] b = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] { 4, 8, 12 };&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; expected = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt; { 0, 1, 2 };&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt; actual = &lt;span style="color:#2b91af"&gt;Program_Accessor&lt;/span&gt;.GetBiggestNonOverlappedIntervalSubset(a, b);&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.IsTrue(actual.Count == 3);&lt;br /&gt;     &lt;span style="color:#2b91af"&gt;CollectionAssert&lt;/span&gt;.AreEquivalent(expected, actual);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; [&lt;span style="color:#2b91af"&gt;TestMethod&lt;/span&gt;()]&lt;br /&gt; &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; GetBiggestNonOverlappedIntervalSubsetTest1()&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] a = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] { 0, 7, 15, 2, 8, 15, 18, 3, 10, 12, 15, 1, 4, 8, 20 };&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] b = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] { 4, 12, 18, 6, 14, 17, 20, 9, 11, 14, 19, 5, 7, 20, 22 };&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; expected1 = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt; { 0, 5, 6, 8, 9, 12, 14 };&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; expected2 = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt; { 0, 2, 6, 8, 9, 12, 14 };&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt; actual = &lt;span style="color:#2b91af"&gt;Program_Accessor&lt;/span&gt;.GetBiggestNonOverlappedIntervalSubset(a, b);&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.IsTrue(actual.Count == 7);&lt;br /&gt;     &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.IsTrue(ListEquals(actual, expected1) || ListEquals(actual, expected2));&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; [&lt;span style="color:#2b91af"&gt;TestMethod&lt;/span&gt;()]&lt;br /&gt; &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; GetBiggestNonOverlappedIntervalSubsetTest2()&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] a = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] { 0, 1, 2, 3, 4 };&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] b = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] { 2, 3, 4, 5, 6 };&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; expected = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt; { 0, 2, 4 };&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt; actual = &lt;span style="color:#2b91af"&gt;Program_Accessor&lt;/span&gt;.GetBiggestNonOverlappedIntervalSubset(a, b);&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.IsTrue(actual.Count == 3);&lt;br /&gt;     &lt;span style="color:#2b91af"&gt;CollectionAssert&lt;/span&gt;.AreEquivalent(expected, actual);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; ListEquals(&lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt; a, &lt;span style="color:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt; b)&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (a.Count != b.Count) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; n = a.Count;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; n; ++i)&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (a[i] != b[i])&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;            &lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;  &lt;br /&gt;Voi come lo avreste implementato? Idee? &lt;/p&gt;  &lt;p&gt;Pensate che la mia soluzione sia corretta?    &lt;br /&gt;Se no, potete fornire un contro esempio che porta ad un risultato scorretto?&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/angellaa/aggbug/99155.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Angella</dc:creator>
            <guid>http://blogs.ugidotnet.org/angellaa/archive/2010/09/05/algoritmi-ndash-determinare-il-sottoinsieme-piugrave-grande-di-intervalli-mutuamente.aspx</guid>
            <pubDate>Sun, 05 Sep 2010 04:33:31 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/angellaa/archive/2010/09/05/algoritmi-ndash-determinare-il-sottoinsieme-piugrave-grande-di-intervalli-mutuamente.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/angellaa/comments/commentRss/99155.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/angellaa/services/trackbacks/99155.aspx</trackback:ping>
        </item>
        <item>
            <title>Algoritmi &amp;ndash; Dire se due parole sono anagrammi</title>
            <link>http://blogs.ugidotnet.org/angellaa/archive/2010/09/04/algoritmi-ndash-dire-se-due-parole-sono-anagrammi.aspx</link>
            <description>&lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Problema:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Date due parole (stringhe) dire se sono anagrammi.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Due stringhe che rappresentano due parole (spazi esclusi)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Un booleano&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Esempio:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Input: “nave” e “vena”    &lt;br /&gt;Output: true     &lt;br /&gt;    &lt;br /&gt;Input: “nave” e “neve”     &lt;br /&gt;Output: false&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Il mio ragionamento:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Se le due parole hanno un numero di caratteri differenti non possono essere anagrammi.&lt;/p&gt;  &lt;p&gt;Calcolo il numero di occorrenze di ciascun carattere nella prima parola.&lt;/p&gt;  &lt;p&gt;Per ogni carattere della seconda parola verifico se ce n’e’ uno corrispondente nella prima decrementando il contatore corrispondente. Se uno dei contatori e’ pari a zero prima del decremento significa che non c’e’ un numero sufficiente di caratteri e quindi ritorno false.&lt;/p&gt;  &lt;p&gt;Nota: contare se un qualche contatore e’ rimasto maggiore di zero dopo l’ultimo foreach non e’ necessario perche’ sappiamo che le due parole hanno la stessa lunghezza. Se il numero di occorrenze di una certa lettera nella prima parola e’ maggiore rispetto al numero di occorrenze nella seconda parola, allora esistera’ sempre la situazione opposta.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;La mia soluzione O(N):&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b49ab869-2bfd-405d-806e-88e0a7788acb" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; IsAnagram(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; s1, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; s2)&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s1 == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"s1"&lt;/span&gt;);&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s2 == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"s2"&lt;/span&gt;);&lt;br /&gt;     &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s1.Length != s2.Length) &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;uint&lt;/span&gt;[] counters = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;uint&lt;/span&gt;[&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.MaxValue + 1];&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;char&lt;/span&gt; c &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; s1) &lt;br /&gt;         ++counters[c];&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;char&lt;/span&gt; c &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; s2)&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt;( counters[c]-- == 0) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Mia seconda soluzione utilizzando l’idea dell’ordinamento O(N):&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8633b5e2-02fb-46c4-b08b-ce8a4b9f95a9" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;StringExtensions&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[] ToOrderedCharArray(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; s)&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"s"&lt;/span&gt;);&lt;br /&gt; &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[] chars = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[s.Length];&lt;br /&gt;         &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;uint&lt;/span&gt;[] counters = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;uint&lt;/span&gt;[&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.MaxValue + 1];&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;char&lt;/span&gt; c &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; s) ++counters[c];&lt;br /&gt; &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; p = 0;&lt;br /&gt; &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;for&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; c = 0; c &amp;lt; counters.Length; ++c)&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; counters[c]; ++i)&lt;br /&gt;                 chars[p++] = (&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;)c;&lt;br /&gt; &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; chars;&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArrayExtensions&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; IsEquivalent&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; T[] array1, T[] array2)&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (array2 == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"vc2"&lt;/span&gt;);&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (array1.Length != array2.Length) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;         &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; n = array1.Length;&lt;br /&gt; &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;for&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; n; i++)&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;if&lt;/span&gt;( !array1[i].Equals(array2[i]) )&lt;br /&gt;                 &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;     }&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p /&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4323dd8a-1806-4991-a453-49fc57938e38" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; IsAnagram_Sorting_Version(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; s1, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; s2)&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s1 == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"s1"&lt;/span&gt;);&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s2 == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"s2"&lt;/span&gt;);&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s1.Length != s2.Length) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[] vc1 = s1.ToOrderedCharArray();&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[] vc2 = s2.ToOrderedCharArray();&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; vc1.IsEquivalent(vc2);&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;   &lt;br /&gt;La leggibilita’ di questa soluzione e’ indiscutibile. &lt;/p&gt;  &lt;p&gt;La complessita’ e’ ancora O(N) anche se la performance e’ piu’ bassa rispetto alla soluzione precedente.    &lt;br /&gt;Inoltre questa soluzione richiede un uso maggiore della memoria per memorizzare gli array ordinati di caratteri.&lt;/p&gt;  &lt;p&gt;Personalmente ritengo la versione precedente preferibile.&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/angellaa/aggbug/99153.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Angella</dc:creator>
            <guid>http://blogs.ugidotnet.org/angellaa/archive/2010/09/04/algoritmi-ndash-dire-se-due-parole-sono-anagrammi.aspx</guid>
            <pubDate>Sat, 04 Sep 2010 17:48:32 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/angellaa/archive/2010/09/04/algoritmi-ndash-dire-se-due-parole-sono-anagrammi.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/angellaa/comments/commentRss/99153.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/angellaa/services/trackbacks/99153.aspx</trackback:ping>
        </item>
        <item>
            <title>Algoritmi &amp;ndash; Rimuovere i caratteri duplicati in una stringa</title>
            <link>http://blogs.ugidotnet.org/angellaa/archive/2010/09/04/algoritmi-ndash-rimuovere-i-caratteri-duplicati-in-una-stringa.aspx</link>
            <description>&lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Problema:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Rimuovere tutti i caratteri duplicati da una stringa. Gli spazi devono essere preservati.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Vincoli:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Se si utilizza C++ modificare direttamente il parametro di input senza utilizzare buffer aggiuntivi. &lt;/p&gt;  &lt;p&gt;Se si utilizza C# ritornare una nuova stringa. In quanto le stringhe sono immutabili, e’ consentito l’utilizzo del metodo ToCharArray() per attenere un buffer su cui lavorare.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Una stringa&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Una stringa&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Esempio:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Input: “Microsoft .Net Framework”&lt;/p&gt;  &lt;p&gt;Output: “Microsft .Ne Famwk”&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Il mio ragionamento:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Itero il buffer della stringa e costruisco all’inizio di esso la stringa risultato. Uno speciale indice mi indichera’ la posizione dell’ultimo elemento nella stringa risultato. Un nuovo carattere sara’ aggiunto solo dopo la verifica che non sia un duplicato, mentre uno spazio sara’ sempre aggiunto. &lt;/p&gt;  &lt;p&gt;La complessita’ dell’algoritmo e’ O(N^2) dove N e’ il numero di elementi distinti presenti nella stringa.&lt;/p&gt;  &lt;p&gt;Una soluzione piu’ efficiente consiste nell’utilizzare un vettore di booleani di appoggio per ricordarsi quali caratteri sono gia’ stati visitati. Questo evita un ciclo innestato rendendo la soluzione di complessita’ lineare. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;La mia soluzione in C++:&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:65e44bb1-fd06-4184-8506-4c483bec3973" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;void&lt;/span&gt; RemoveDuplicates(&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;* s)&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s == NULL) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; exception(&lt;span style="color:#a31515"&gt;"s cannot be null"&lt;/span&gt;);&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;char&lt;/span&gt; c;&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; i = 0;&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; end = 0;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;while&lt;/span&gt;(c = s[i])&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; duplicate = &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!isspace(c))&lt;br /&gt;         {&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;for&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; j = 0; j &amp;lt; i; ++j)&lt;br /&gt;                 &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s[j] == c)&lt;br /&gt;                 {&lt;br /&gt;                     duplicate = &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;                     &lt;span style="color:#0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;                 }&lt;br /&gt;         }&lt;br /&gt; &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!duplicate) s[end++] = c;&lt;br /&gt; &lt;br /&gt;         ++i;&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     s[end] = 0;&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;strong&gt;   &lt;p&gt;     &lt;br /&gt;La mia soluzione in C#:&lt;/p&gt; &lt;/strong&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f81a9419-a562-4a36-8d7b-55bac6684a1a" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;StringExtension&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; RemoveDuplicates(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; s)&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"s"&lt;/span&gt;);&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s.Length &amp;lt; 2) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; s;&lt;br /&gt; &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[] vc = s.ToCharArray();&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; len = s.Length;&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; end = 0;&lt;br /&gt; &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; len; ++i)&lt;br /&gt;         {&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;char&lt;/span&gt; c = vc[i];&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; duplicate = &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;             &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsWhiteSpace(c))&lt;br /&gt;                 &lt;span style="color:#0000ff"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; j = 0; j &amp;lt; end; j++)&lt;br /&gt;                     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (c == vc[j])&lt;br /&gt;                     {&lt;br /&gt;                         duplicate = &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;                         &lt;span style="color:#0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;                     }&lt;br /&gt; &lt;br /&gt;             &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!duplicate)&lt;br /&gt;                 vc[end++] = c;&lt;br /&gt;         }&lt;br /&gt; &lt;br /&gt;         &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;(vc, 0, end);&lt;br /&gt;     }&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Soluzione in C# piu’ efficiente     &lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a922f9f8-9faf-4d1b-acb5-25d6fc46fcf8" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; RemoveDuplicates(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; s)&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"s"&lt;/span&gt;);&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s.Length &amp;lt; 2) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; s;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[] vc = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[s.Length];&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt;[] visited = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt;[&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.MaxValue + 1];&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; end = 0;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;char&lt;/span&gt; c &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; s)&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!visited[c] || &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsWhiteSpace(c))&lt;br /&gt;         {&lt;br /&gt;             vc[end++] = c;&lt;br /&gt;             visited[c] = &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;(vc, 0, end);                        &lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org/angellaa/aggbug/99152.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Angella</dc:creator>
            <guid>http://blogs.ugidotnet.org/angellaa/archive/2010/09/04/algoritmi-ndash-rimuovere-i-caratteri-duplicati-in-una-stringa.aspx</guid>
            <pubDate>Sat, 04 Sep 2010 16:16:08 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/angellaa/archive/2010/09/04/algoritmi-ndash-rimuovere-i-caratteri-duplicati-in-una-stringa.aspx#feedback</comments>
            <slash:comments>39</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/angellaa/comments/commentRss/99152.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/angellaa/services/trackbacks/99152.aspx</trackback:ping>
        </item>
        <item>
            <title>Algoritmi &amp;ndash; Invertire una stringa</title>
            <link>http://blogs.ugidotnet.org/angellaa/archive/2010/09/03/algoritmi-ndash-invertire-una-stringa.aspx</link>
            <description>&lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Problema:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Data una stringa, calcolare e ritornare una nuova stringa con gli stessi caratteri ma in ordine inverso.&lt;/p&gt;  &lt;p&gt;Esempio: ABCDE   &lt;br /&gt;Risultato: EDCBA&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Una stringa.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;La stringa di input con i caratteri in ordine inverso.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Il mio ragionamento:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Costruisco un vettore di caratteri lungo quanto la stringa e lo riempio con un semplice ciclo for.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;La mia soluzione:&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c9ab124e-d05d-48fe-b4d0-1feeed09aef5" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; max-height: 400px; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Reverse(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; s)&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"s"&lt;/span&gt;);&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (s.Length &amp;lt; 2) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; s;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[] vc = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[s.Length];&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; n = s.Length - 1;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt;= n; ++i)&lt;br /&gt;         vc[i] = s[n - i];&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;String&lt;/span&gt;(vc);&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org/angellaa/aggbug/99146.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Angella</dc:creator>
            <guid>http://blogs.ugidotnet.org/angellaa/archive/2010/09/03/algoritmi-ndash-invertire-una-stringa.aspx</guid>
            <pubDate>Fri, 03 Sep 2010 01:39:58 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/angellaa/archive/2010/09/03/algoritmi-ndash-invertire-una-stringa.aspx#feedback</comments>
            <slash:comments>5</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/angellaa/comments/commentRss/99146.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/angellaa/services/trackbacks/99146.aspx</trackback:ping>
        </item>
        <item>
            <title>Algoritmi &amp;ndash; Determinare dal testo di una rivista se e&amp;rsquo; possibile creare una ransom note</title>
            <link>http://blogs.ugidotnet.org/angellaa/archive/2010/09/02/algoritmi-ndash-determinare-dal-testo-di-una-rivista-se-ersquo.aspx</link>
            <description>&lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Problema 1:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Fino ad ora non sapevo cosa fosse una &lt;a href="http://www.joshuarey.com/index.pl?Action=ShowArticle&amp;amp;ID=134"&gt;ransom note&lt;/a&gt;.     &lt;br /&gt;Praticamente si tratta di un testo realizzato utilizzando ritagli da una rivista.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/angellaa/WindowsLiveWriter/AlgoritmiDeterminaredaltestodiunarivista_14502/ransom%20note_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ransom note" border="0" alt="ransom note" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/angellaa/WindowsLiveWriter/AlgoritmiDeterminaredaltestodiunarivista_14502/ransom%20note_thumb.jpg" width="196" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Dato il testo di una ransom note e il testo della rivista, dire se e’ possibile realizzare la ransom note.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Problema 2:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Risolvere lo stesso problema ma ritagliando parole invece che singoli caratteri.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Testo della ransom note che si vuole creare (stringa).    &lt;br /&gt;Testo della rivista da cui si vuole ritagliare (stringa).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;True se e’ possibile realizzare la ransom note, False altrimenti.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Il mio ragionamento:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Scansiono due volte i testi e costruisco due vettori che conteggiano il numero di occorrenze di ciasun carattere. Fatto questo controllo che ci sia sempre un numero sufficiente di lettere per costruire la ransom note confrontando uno ad uno gli elementi corrispondenti di questi due array.&lt;/p&gt;  &lt;p&gt;Per quanto riguarda il problema 2 invece di utilizzare due vettori, utilizzo due tabelle hash. La logica e’ sostanzialmente la stessa.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Le mie soluzioni:&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a12e9f87-e622-473f-bcec-a4fb5fb6d5d6" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; IsCharacterRansomNotePossible(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; noteText, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; magazineText)&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;String&lt;/span&gt;.IsNullOrEmpty(noteText) || &lt;span style="color:#2b91af"&gt;String&lt;/span&gt;.IsNullOrEmpty(magazineText))&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"noteText and/or magazineText cannot be null or empty"&lt;/span&gt;);&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; N = &lt;span style="color:#2b91af"&gt;Char&lt;/span&gt;.MaxValue + 1;&lt;br /&gt;     &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;uint&lt;/span&gt;[] noteCount = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;uint&lt;/span&gt;[N];&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;uint&lt;/span&gt;[] magazineCount = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;uint&lt;/span&gt;[N];&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;char&lt;/span&gt; c &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; noteText) ++noteCount[c];            &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;char&lt;/span&gt; c &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; magazineText) ++magazineCount[c];&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; N; ++i)&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (noteCount[i] &amp;gt; magazineCount[i])&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;if&lt;/span&gt;(!&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsWhiteSpace((&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;)i))&lt;br /&gt;                 &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; IsWordRansomNotePossible(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; noteText, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; magazineText)&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;String&lt;/span&gt;.IsNullOrEmpty(noteText) || &lt;span style="color:#2b91af"&gt;String&lt;/span&gt;.IsNullOrEmpty(magazineText))&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"noteText and/or magazineText cannot be null or empty"&lt;/span&gt;);&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; noteCount = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; magazineCount = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; noteWords = noteText.Split();&lt;br /&gt;     &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; magazineWords = magazineText.Split();&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; s &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; noteWords)&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (noteCount.ContainsKey(s)) ++noteCount[s];&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;else&lt;/span&gt; noteCount[s] = 1;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; s &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; magazineWords)&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (magazineCount.ContainsKey(s)) ++magazineCount[s];&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;else&lt;/span&gt; magazineCount[s] = 1;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; word &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; noteCount.Keys)&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!magazineCount.ContainsKey(word) || noteCount[word] &amp;gt; magazineCount[word])&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;   &lt;br /&gt;Qualunque commento e’ ben accetto. Il codice non e’ stato testato rigorosamente.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Soluzione di Ludovico Van:&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ee8b6ac5-6d97-4d94-b57f-43779f2e85f3" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; IsCharRansomNotePossible(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; note, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; source)&lt;br /&gt; {&lt;br /&gt;     note = note == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt; ? &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.Empty : note.Trim();&lt;br /&gt;     source = source == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt; ? &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.Empty : source.Trim();&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (note.Length == 0)&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[] charCounts = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;int&lt;/span&gt;[1 + &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.MaxValue];&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;int&lt;/span&gt; charSetCount = 0;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;char&lt;/span&gt; ch &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; note)&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsWhiteSpace(ch))&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (charCounts[ch]++ == 0)&lt;br /&gt;                 ++charSetCount;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;char&lt;/span&gt; ch &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; source)&lt;br /&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (charCounts[ch] != 0)&lt;br /&gt;             &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (--charCounts[ch] == 0)&lt;br /&gt;                 &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (--charSetCount == 0)&lt;br /&gt;                     &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org/angellaa/aggbug/99139.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Angella</dc:creator>
            <guid>http://blogs.ugidotnet.org/angellaa/archive/2010/09/02/algoritmi-ndash-determinare-dal-testo-di-una-rivista-se-ersquo.aspx</guid>
            <pubDate>Thu, 02 Sep 2010 01:51:12 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/angellaa/archive/2010/09/02/algoritmi-ndash-determinare-dal-testo-di-una-rivista-se-ersquo.aspx#feedback</comments>
            <slash:comments>9</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/angellaa/comments/commentRss/99139.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/angellaa/services/trackbacks/99139.aspx</trackback:ping>
        </item>
        <item>
            <title>DSA and BCL - Unordered List Stress Test</title>
            <link>http://blogs.ugidotnet.org/angellaa/archive/2008/09/28/dsa-and-bcl---unordered-list-stress-test.aspx</link>
            <description>&lt;p&gt;Come tutti sapete &lt;a target="_blank" href="http://weblogs.asp.net/gbarnett/"&gt;Granville Barnett&lt;/a&gt; e &lt;a target="_blank" href="http://blogs.ugidotnet.org/wetblog/Default.aspx"&gt;Luca del Tongo&lt;/a&gt; stanno lavorando alla realizzazione di una libreria open-source di strutture dati e algoritmi (&lt;a target="_blank" href="http://www.codeplex.com/dsa"&gt;DSA&lt;/a&gt;) con lo scopo di arricchire le funzionalità offerte dalla libreria di base del framework 3.5 (BCL). Sono molto interessato all'evoluzione del progetto, per questo ho scaricato l'attuale release 0.6 ed ho iniziato a studiarla attentamente (segnalo anche la presenza di un &lt;a target="_blank" href="http://dotnetslackers.com/projects/Data-Structures-And-Algorithms/"&gt;eBook&lt;/a&gt; scritto dagli stessi autori per meglio comprendere gli algoritmi implementati). Sono rimasto piacevolmente colpito dalla pulizia e chiarezza del codice di implementazione e soprattutto dallo sforzo impiegato a mantenere intuitivo l'utilizzo della libreria (molti metodi e proprietà infatti hanno nomi analoghi a quelli implementati da Microsoft ma non è certo solo in questo lo sforzo). &lt;/p&gt;  &lt;p&gt;Come sottolineano gli stessi autori l'aspetto più critico quando le performance sono importanti è saper scegliere le strutture dati e gli algoritmi migliori nel particolare contesto applicativo. In questo post voglio mostrarvi i risultati che ho ottenuto dalla mia analisi delle strutture dati di tipo lista non ordinata presenti nella BCL e nella libreria DSA.&lt;/p&gt;  &lt;p&gt;Le strutture dati presenti nella BCL che ho coinvolto sono:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;List&lt;/li&gt;    &lt;li&gt;LinkedList &lt;/li&gt;    &lt;li&gt;Stack&lt;/li&gt;    &lt;li&gt;Queue&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Le strutture dati presenti nella libreria DSA che ho coinvolto sono:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;SinglyLinkedList &lt;/li&gt;    &lt;li&gt;DoublyLinkedList &lt;/li&gt;    &lt;li&gt;Deque &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Prima di mostrare i risultati ottenuti è bene sottolineare quando è opportuno scegliere il tipo di dati lista non ordinata all'interno di una applicazione. Generalmente si sceglie una lista non ordinata quando si desiderano effettuare le seguenti operazioni:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Inserimento di elementi (senza un ordinamento particolare) &lt;/li&gt;    &lt;li&gt;Rimozione di elementi &lt;/li&gt;    &lt;li&gt;Enumerazione degli elementi&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Ho voluto quindi testare la velocità di esecuzione dei seguenti metodi:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;AddLast&lt;/strong&gt;() : inserimento di un elemento in coda alla lista&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;AddFirst&lt;/strong&gt;() : inserimento di un elemento in testa alla lista&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;RemoveLast&lt;/strong&gt;() : rimozione dell'elemento in coda alla lista&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;RemoveFirst&lt;/strong&gt;() : rimozione dell'elemento in testa alla lista&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Remove&lt;/strong&gt;() : rimozione di un elemento con un certo valore&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Di seguito riporto i risultati ottenuti considerando che ogni metodo è stato eseguito 100 Mila volte:   &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/angellaa/WindowsLiveWriter/DSAvsBCLUnorderedListStressTest_C2F3/2008-09-27_224747_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="2008-09-27_224747" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/angellaa/WindowsLiveWriter/DSAvsBCLUnorderedListStressTest_C2F3/2008-09-27_224747_thumb.jpg" width="642" height="673" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Considerazioni su AddLast():&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;List&lt;/strong&gt; è sicuramente la struttura dati più veloce; Il motivo è certamente dovuto al fatto che la sua implementazione interna sfrutta un vettore a crescita dinamica; Questo vettore di appoggio viene rilocato con dimensioni doppie nel momento in cui non è più disponibile spazio al suo interno; Anche &lt;strong&gt;Stack&lt;/strong&gt; e &lt;strong&gt;Queue&lt;/strong&gt; utilizzano al loro interno un meccanismo analogo.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;SinglyLinkedList&lt;/strong&gt; e &lt;strong&gt;DoublyLinkedList&lt;/strong&gt; hanno più o meno prestazioni analoghe fra loro e sono migliori della &lt;strong&gt;LinkedList&lt;/strong&gt; del framework; E' importante precisare che la classe LinkedList del framework è implementata come una coda doppia, allo stesso modo di &lt;strong&gt;DoublyLinkedList&lt;/strong&gt;, però in ogni nodo viene memorizzato anche un riferimento alla lista. L'aggiornamento di questo valore per ogni nodo è probabilmente la causa di tale perdita di performance. Qualcuno sa perchè hanno messo questo riferimento in ogni nodo ?&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Deque&lt;/strong&gt; infine è semplicemente un Facade sulla classe &lt;strong&gt;DoublyLinkedList&lt;/strong&gt;. Mi sembra molto strano che le sue prestazioni siano leggermente migliori a &lt;strong&gt;DoublyLinkedList&lt;/strong&gt; considerando il fatto che al suo interno la classe Deque è costretta ad aggiornare il valore di un altro contatore.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Considerazioni su AddFirst():&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Sicuramente nel caso in cui si devono fare frequentemente operazioni di questo tipo la scelta migliore risiede in &lt;strong&gt;SinglyLinkedList&lt;/strong&gt;, &lt;strong&gt;DoublyLinkedList&lt;/strong&gt; o &lt;strong&gt;Deque&lt;/strong&gt;.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;LinkedList&lt;/strong&gt; del framework (per il motivo detto prima) ha prestazioni inferiori&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;List&lt;/strong&gt; è inefficiente negli inserimenti in testa (e in generale in quelli interni) proprio perchè ciascuna operazione forza uno spostamento di tutti gli elementi successivi&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Considerazioni su RemoveLast():&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;SinglyLinkedList&lt;/strong&gt; è inefficiente per costruzione. Infatti la monodirezionalità obbliga a scorrere tutta la lista per rimuovere l'ultimo elemento.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Considerazioni su RemoveFirst():&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;SinglyLinkedList&lt;/strong&gt; e &lt;strong&gt;DoublyLinkedList&lt;/strong&gt; hanno più o meno prestazioni analoghe sempre migliori della controparte LinkedList del framework.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Considerazioni su Remove():&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;List&lt;/strong&gt; per questo tipo di operazione è efficiente proprio perchè sfrutta la memorizzazione tramite array.&lt;/li&gt;    &lt;li&gt;Le altre implementazioni infatti richiedono lo scorrimento dell'intera lista ad ogni operazione.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In generale mi sento di tirare queste conclusioni:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Utilizzare &lt;strong&gt;Stack&lt;/strong&gt; quando si ha bisogno di una struttura dati di tipo LIFO&lt;/li&gt;    &lt;li&gt;Utilizzare &lt;strong&gt;Queue&lt;/strong&gt; quando si ha bisogno di una struttura dati di tipo FIFO&lt;/li&gt;    &lt;li&gt;Utilizzare &lt;strong&gt;SinglyLinkedList&lt;/strong&gt; se si preferisce una struttura dati Queue implementata tramite coda. Le prestazioni sono di poco inferiori a Queue ma in caso di grossi elementi può portare ad una maggiore efficienza in termini di memoria occupata (si consideri il costo di raddoppiare il vettore nell'implementazione di Queue). Probabilmente questa mia considerazione andrebbe in qualche modo provata, sicuramente ci sarà un motivo per cui è stata rimossa l'implementazione di Queue nelle ultime release di DSA (Forse per non creare ulteriore confusione).&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;SinglyLinkedList&lt;/strong&gt; in generale conviene usarla quando si ha necessità di scorrere gli elementi in una sola direzione.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;DoublyLinkedList&lt;/strong&gt; si deve utilizzare quando si ha necessità di scorrere gli elementi in entrambe le direzioni.&lt;/li&gt;    &lt;li&gt;A mio parere &lt;strong&gt;Deque&lt;/strong&gt; non ha molto senso di esistere perchè le funzionalità offerte sono tutte ottenibili sfruttando una DoublyLinkedList. In pratica utilizzare direttamente DoublyLinkedList dovrebbe anche essere più efficiente (anche se i dati non sembrano dimostrarlo).&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;LinkedList&lt;/strong&gt; del framework sembra uscire perdente da questa mia analisi. Bisogna capire perchè ha senso inserire il riferimento alla lista in ciasun nodo !&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;List&lt;/strong&gt; è senz'altro la soluzione migliore quando si devono inserire tanti elementi uno in coda all'altro, effettuare delle rimozioni per valore e quindi delle enumerazioni sugli elementi&lt;/li&gt; &lt;/ul&gt;&lt;img src="http://blogs.ugidotnet.org/angellaa/aggbug/94185.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Angella</dc:creator>
            <guid>http://blogs.ugidotnet.org/angellaa/archive/2008/09/28/dsa-and-bcl---unordered-list-stress-test.aspx</guid>
            <pubDate>Sun, 28 Sep 2008 01:34:58 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/angellaa/archive/2008/09/28/dsa-and-bcl---unordered-list-stress-test.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/angellaa/comments/commentRss/94185.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/angellaa/services/trackbacks/94185.aspx</trackback:ping>
        </item>
        <item>
            <title>L'importanza di realizzare algoritmi polinomiali</title>
            <link>http://blogs.ugidotnet.org/angellaa/archive/2008/07/12/limportanza-di-realizzare-algoritmi-polinomiali.aspx</link>
            <description>&lt;p&gt;Tutti noi sappiamo quanto sia importante in alcune occasioni trovare un algoritmo polinomiale per risolvere un problema (meglio ancora se lineare o logaritmico). Vorrei sottolineare con un taglio matematico quanta rilevanza può avere questa semplice constatazione.&lt;/p&gt;  &lt;p&gt;Supponiamo di avere tre algoritmi che risolvono un medesimo problema. Il primo algoritmo ha complessità esponenziale, il secondo ha complessità quadratica e il terzo è lineare. La funzione Ti(n) indica il tempo richiesto dall'algoritmo i-esimo per trovare la soluzione di un problema di dimensione n (in poche parole la complessità dell'algoritmo). Abbiamo quindi:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;T1( n ) = 2 ^ n&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;T2( n ) = n ^ 2&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;T3( n ) = n&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;Ci poniamo adesso la seguente domanda:&lt;strong&gt; quanti dati ciascuno degli algoritmi precedenti è in grado di elaborare in t unità di tempo ?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;La risposta è molto semplice e la soluzione consiste banalmente nel determinare le funzioni inverse a quelle prima elencate.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;N1 ( t ) = Log2 ( t )&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;N2 ( t ) = Sqrt( t )&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;N3 ( t ) = t&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;Supponendo di eseguire gli stessi algoritmi su una macchina k volte più veloce la risposta alla precedente domanda sarà il valore delle funzioni Ni(t) calcolate in k * t cioè:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;N1 ( k * t ) = Log2 ( k * t ) = &lt;font color="#ff0000"&gt;Log2 ( k )  +&lt;/font&gt;  Log2 ( t )&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;N2 ( k * t ) = Sqrt ( k * t ) = &lt;font color="#ff0000"&gt;Sqrt ( k )  *&lt;/font&gt;  Sqrt ( t )&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;N3 ( k * t ) = &lt;font color="#ff0000"&gt;k  * &lt;/font&gt; t&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;Da ciò risulta molto più evidente la gravità di realizzare algoritmi esponenziali. Nel caso di algoritmi polinomiali il guadagno in termini di quantità di dati trattabili nello stesso tempo è di tipo moltiplicativo. Nel caso di algoritmi esponenziali invece il guadagno è solo di tipo addittivo !!! &lt;/p&gt;  &lt;p&gt;In parole più chiare se per assurdo potessimo avere un processore 10000 volte più veloce di quelli attuali, per esempio un processore da 20 Tera Herz ( 10000 volte 2 Giga Hz ) il nostro algoritmo a parità di tempo saprebbe trattare solamente Log2( 10000 ) = 13 dati in più.&lt;strong&gt; Il guadagno in termini di scalabilità sui dati è praticamente nullo !!!&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Intel come sappiamo ha cambiato rotta nello sviluppo dei suoi processori nella direzione di integrare più core insieme permettendo di fatto un parallelismo reale di esecuzione delle istruzioni. La vera sfida come più volte ha sottolineato Raf ai Community Days 2008 sarà riuscire a scrivere software che sfrutti veramente le nuove architetture multicore. Una sfida sicuramente entusiasmante.&lt;/p&gt;  &lt;p&gt;Un problema giocattolo ma particolarmente interessante è il famoso problema della &lt;strong&gt;SOTTOSEQUENZA DI SOMMA MASSIMA&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Il problema è il seguente: &lt;u&gt;dato un vettore di numeri interi positivi e negativi determinare la sottosequenza la cui somma è massima&lt;/u&gt;. &lt;/p&gt;  &lt;p&gt;Diverse sono le possibili soluzioni a questo problema. Due soluzioni immediate ma inefficienti hanno rispettivamente complessità cubica e quadratica. Sfruttando due semplici ma interessanti proprietà è possibile rendere lineare l'algoritmo con indubbi vantaggi sulla velocità di esecuzione e soprattutto sulla scalabilità.&lt;/p&gt;  &lt;p&gt;Una semplice applicazione console che realizza e misura le velocità di questi algoritmi  la potete trovare nel mio laboratorio online: &lt;a href="http://www.angellaa.it/lab/dettagli-soluzione.aspx?id=19" target="_blank"&gt;&lt;font size="2"&gt;scarica sottosequenza di somma massima&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/angellaa/aggbug/93369.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Angella</dc:creator>
            <guid>http://blogs.ugidotnet.org/angellaa/archive/2008/07/12/limportanza-di-realizzare-algoritmi-polinomiali.aspx</guid>
            <pubDate>Sat, 12 Jul 2008 01:52:46 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/angellaa/archive/2008/07/12/limportanza-di-realizzare-algoritmi-polinomiali.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/angellaa/comments/commentRss/93369.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/angellaa/services/trackbacks/93369.aspx</trackback:ping>
        </item>
    </channel>
</rss>