<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Hashfunktion für Strings]]></title><description><![CDATA[<p>Hallo ersteinmal,</p>
<p>nach stundenlanger Recherche im Internet und dem Verwerfen einiger eigener Ideen würde ich Euch gerne um Rat fragen (das Problem dürfte eigentlich nicht so schwer sein).<br />
Für die Vorlesung &quot;Algorithmen und Datenstrukturen&quot; sollen wir ein kleines Wörterbuch schreiben, welches über eine Hashtable realisiert werden soll.<br />
Für das Hashen sollen wir die Divisionsrestmethode nutzen ( k % m ). So weit so gut. In der Aufgabe wird verlangt, dass wir dafür den String (das entsprechende Wort aus dem Wörterbuch) möglichst geschickt (und hier liegt mein Problem <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /> ) in einen Integer umwandeln sollen, den wir dann hashen können.<br />
Meine erste Idee war durch einfaches shiften die ASCII-Werte in einen Integer zu verwandeln, das geht ja aber leider nur bis fünf Zeichen gut..<br />
Als negativ-Beispiel ist die einfache Addition der ASCII-Werte genannt.</p>
<p>Mein bisheriger Ansatz ist:</p>
<pre><code>int LinHTable::hash(string hashString)
{
const int MAX_TABLESIZE = 29;
int hashNumber=0;
int intChar;
for(int i=0; i!=hashString.size(); i++)
{
	hashNumber = ((hashNumber &lt;&lt; 8) + hashString[i])%MAX_TABLESIZE ;
}
return hashNumber;
}
</code></pre>
<p>Nur leider kann ich auch nicht viel dazu sagen, warum ich das so mache... wir sollen unseren algorithmus aber leider begründen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /><br />
deswegen kann ich auch nicht einfach irgendwelche kryptischen Hashverfahren nehmen, die ich im Internet finde djb etc.</p>
<p>Kann mir vielleicht jemand von Euch etwas helfen?</p>
<p>Vielen Dank im Voraus und viele Grüße aus London</p>
<p>Christian</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/195296/hashfunktion-für-strings</link><generator>RSS for Node</generator><lastBuildDate>Tue, 30 Jun 2026 06:40:19 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/195296.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 16 Oct 2007 10:59:01 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Hashfunktion für Strings on Tue, 16 Oct 2007 10:59:01 GMT]]></title><description><![CDATA[<p>Hallo ersteinmal,</p>
<p>nach stundenlanger Recherche im Internet und dem Verwerfen einiger eigener Ideen würde ich Euch gerne um Rat fragen (das Problem dürfte eigentlich nicht so schwer sein).<br />
Für die Vorlesung &quot;Algorithmen und Datenstrukturen&quot; sollen wir ein kleines Wörterbuch schreiben, welches über eine Hashtable realisiert werden soll.<br />
Für das Hashen sollen wir die Divisionsrestmethode nutzen ( k % m ). So weit so gut. In der Aufgabe wird verlangt, dass wir dafür den String (das entsprechende Wort aus dem Wörterbuch) möglichst geschickt (und hier liegt mein Problem <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /> ) in einen Integer umwandeln sollen, den wir dann hashen können.<br />
Meine erste Idee war durch einfaches shiften die ASCII-Werte in einen Integer zu verwandeln, das geht ja aber leider nur bis fünf Zeichen gut..<br />
Als negativ-Beispiel ist die einfache Addition der ASCII-Werte genannt.</p>
<p>Mein bisheriger Ansatz ist:</p>
<pre><code>int LinHTable::hash(string hashString)
{
const int MAX_TABLESIZE = 29;
int hashNumber=0;
int intChar;
for(int i=0; i!=hashString.size(); i++)
{
	hashNumber = ((hashNumber &lt;&lt; 8) + hashString[i])%MAX_TABLESIZE ;
}
return hashNumber;
}
</code></pre>
<p>Nur leider kann ich auch nicht viel dazu sagen, warum ich das so mache... wir sollen unseren algorithmus aber leider begründen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /><br />
deswegen kann ich auch nicht einfach irgendwelche kryptischen Hashverfahren nehmen, die ich im Internet finde djb etc.</p>
<p>Kann mir vielleicht jemand von Euch etwas helfen?</p>
<p>Vielen Dank im Voraus und viele Grüße aus London</p>
<p>Christian</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1386256</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1386256</guid><dc:creator><![CDATA[Chris052]]></dc:creator><pubDate>Tue, 16 Oct 2007 10:59:01 GMT</pubDate></item><item><title><![CDATA[Reply to Hashfunktion für Strings on Wed, 17 Oct 2007 12:00:24 GMT]]></title><description><![CDATA[<p>Hat denn keiner von Euch eine Idee?</p>
<p>Viele Grüße</p>
<p>Christian</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387128</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387128</guid><dc:creator><![CDATA[Chris052]]></dc:creator><pubDate>Wed, 17 Oct 2007 12:00:24 GMT</pubDate></item><item><title><![CDATA[Reply to Hashfunktion für Strings on Wed, 17 Oct 2007 12:06:38 GMT]]></title><description><![CDATA[<p>Wo hast du denn diese Formel her? Sie wird dir ja vermutlich nicht im Traum durch den Kopf geschwirrt sein - oder etwa doch?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387131</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387131</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Wed, 17 Oct 2007 12:06:38 GMT</pubDate></item><item><title><![CDATA[Reply to Hashfunktion für Strings on Wed, 17 Oct 2007 12:14:46 GMT]]></title><description><![CDATA[<p>Java hasht Strings so:</p>
<blockquote>
<p>Returns a hash code for this string. The hash code for a String object is computed as</p>
<p>s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]</p>
<p>using int arithmetic, where s[i] is the ith character of the string, n is the length of the string, and ^ indicates exponentiation. (The hash value of the empty string is zero.)</p>
</blockquote>
<p>(vielleicht hilfts ja)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387137</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387137</guid><dc:creator><![CDATA[byto]]></dc:creator><pubDate>Wed, 17 Oct 2007 12:14:46 GMT</pubDate></item><item><title><![CDATA[Reply to Hashfunktion für Strings on Wed, 17 Oct 2007 12:47:19 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/10318">@CSTOLL</a>:<br />
so halbwegs ;). Hab halt das mitm shiften so gemacht wie ichs mir vorgestellt habe und habe um die Zahlen nicht zu groß werden zu lassen einfach jedes mal modulo gerechnet, da ich das ja am ende sowieso machen muss.<br />
Bin nur nicht so davon überzeugt, dass das so sinnvoll und die beste methode ist <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/13585">@BYTO</a>:<br />
Das schaut schon ziemlich interessant aus.. Danke! Weisst du/jemand zufälligerweise, warum das so gemacht wird? Bzw. warum die Zahlen gerade mit 31 multipliziert werden?</p>
<p>Viele Grüße</p>
<p>Chris</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387168</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387168</guid><dc:creator><![CDATA[Chris052]]></dc:creator><pubDate>Wed, 17 Oct 2007 12:47:19 GMT</pubDate></item><item><title><![CDATA[Reply to Hashfunktion für Strings on Wed, 17 Oct 2007 12:57:27 GMT]]></title><description><![CDATA[<p>Chris052 schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/10318">@CSTOLL</a>:<br />
so halbwegs ;). Hab halt das mitm shiften so gemacht wie ichs mir vorgestellt habe und habe um die Zahlen nicht zu groß werden zu lassen einfach jedes mal modulo gerechnet, da ich das ja am ende sowieso machen muss.<br />
Bin nur nicht so davon überzeugt, dass das so sinnvoll und die beste methode ist <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
</blockquote>
<p>Das shift ist auch nur eine andere Möglichkeit, mit Zweierpotenzen zu multipilzieren - und wenn du noch dazunimmst, daß (a+b)%m == ((a%m)+(b%m))%m gilt, hast du prinzipiell etwas ähnliches wie den von byto genannten Code - nur mit 256 als Faktor.</p>
<p>(das Problem dabei ist, daß der Faktor und die Tabellengröße möglichst teilerfremd sein sollten - sonst passiert der von dir beobachtete Effekt, daß die höherwertigen Zeichen bei der Modulo-Bildung komplett rausgeschnitten werden. Bei dir ist die Tabellengröße entsprechend &quot;krumm&quot;, bei der Java-Lösung der verwendete Faktor)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387178</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387178</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Wed, 17 Oct 2007 12:57:27 GMT</pubDate></item><item><title><![CDATA[Reply to Hashfunktion für Strings on Wed, 17 Oct 2007 12:59:30 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">unsigned classic_string_hash (const char *str)
{
   unsigned res, tmp;
   const char *p;
   res = 0;
   for (p = str; *p; p++)
   {
      tmp = res &amp; 0xf0000000;
      /* unsigned 32-bit */
      res &lt;&lt;= 4;
      res += *p;
      if (tmp)
         res ^= tmp &gt;&gt; 28;
   }
   return res;
}
</code></pre>
<p>Die stammt aus dem Dragonbook. Wenn also gefragt wird &quot;warum diese Funktion&quot; dann sagst du einfach &quot;die stammt aus dem Dragonbook&quot;. Vielleicht ist dort auch erklaert, warum die halbwegs gut ist; Es gibt sicher bessere Funktionen, aber die ist recht brauchbar und auch relativ uebersichtlich/verstaendlich. Aehnelt im Grundansatz auch dem, was du eh schon vorhattest.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387185</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387185</guid><dc:creator><![CDATA[Blue-Tiger]]></dc:creator><pubDate>Wed, 17 Oct 2007 12:59:30 GMT</pubDate></item><item><title><![CDATA[Reply to Hashfunktion für Strings on Wed, 17 Oct 2007 15:37:20 GMT]]></title><description><![CDATA[<p>Zeichne dir einfach mal auf was mit den Bits genau passiert und benutz ein paar typische Daten. Dann fällt dir vielleicht eine Begründung oder ein gutes Verfahren ein.</p>
<pre><code class="language-cpp">h=(h+(h&lt;&lt;5))^buf[i]
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1387307</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387307</guid><dc:creator><![CDATA[rüdiger]]></dc:creator><pubDate>Wed, 17 Oct 2007 15:37:20 GMT</pubDate></item><item><title><![CDATA[Reply to Hashfunktion für Strings on Sat, 20 Oct 2007 13:40:16 GMT]]></title><description><![CDATA[<p>Hey, nochmal vielen Dank für die vielen Antworten.</p>
<p>Rüdigers Lösung finde ich bisher am besten/verständlichsten. Nur leider komme ich auch mit viel Nachdenken nicht auf eine perfekte erklärung, vielleicht könnt ihr mir ja noch ein bisschen auf die sprünge helfen</p>
<blockquote>
<p>h=(h+(h&lt;&lt;5))^buf[i]</p>
</blockquote>
<p>So ähnlich wäre mein letzer Ansatz auch gewesen:</p>
<pre><code class="language-cpp">h=(h&lt;&lt;2)^buf[i]
</code></pre>
<p>Das hätte ich so erklärt:<br />
Man shiftet, um eine möglichst breite Abdeckung im 16bit Zahlenbereich zu erreichen und die Wahrscheinlichtkeit zu verringern die gleichen hashzahlen zu erzeugen.<br />
XOR bietet sich eher an als +, da die Zahl nicht einfach immer größer wird, sondern sich bitweise ohne überhang individuell verändert.<br />
Das Problem hierbei war jedoch noch, dass man ab einer länge von 8 Zeichen, keinen Einfluss der ersten Zeichen mehr auf den Hashwert hatte, da man diese durch das shiften immer aus dem Zahlenbereich &quot;herausträgt&quot;.</p>
<p>Mit Rüdigers Lösung ist dies nicht der Fall (habs n mir mal für ein paar Fälle aufgemalt), da man nicht nur shiftet, sondern auch noch das bisherige ergebnis auf die ersten bits einfluß nehmen lässt. PERFEKT!<br />
Nur 2 Fragen kann ich so nicht ganz beantworten:<br />
1. warum addiert man h und (h&lt;&lt;5), wäre es da nicht auch besser einfach XOR zu nutzen und folgendes zu implementieren:</p>
<pre><code class="language-cpp">h=(h^(h&lt;&lt;5))^buf[i]
</code></pre>
<p>Ist das nicht vielleicht noch besser?<br />
2. warum shiftet man gerade 5 bit? Ist es besser eine ungerade Zahl zu shiften?</p>
<p>Viele Grüße</p>
<p>Chris</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1388982</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1388982</guid><dc:creator><![CDATA[Chris052]]></dc:creator><pubDate>Sat, 20 Oct 2007 13:40:16 GMT</pubDate></item></channel></rss>