<?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[Periods of Strings]]></title><description><![CDATA[<p>Hallo miteinander,</p>
<p>ich habe als Aufgabe in unserem Proseminar eine der Problemstellungen des ACM ICPC zu lösen, jedoch habe ich einige Denkblockaden im Moment.</p>
<p>Zunächst <a href="http://www3.in.tum.de/teaching/ss11/ACMProseminar/Proseminar_Themen/Period.pdf" rel="nofollow">hier</a> die Aufgabenstellung.</p>
<p>Den Anfang mit der Distanz zweier Strings werde ich mit der Levenshtein-Distanz machen - das ist kein Problem. Aber ich scheitere am zweiten Teil den String x in nichtleere Teilstrings aufzuteilen und alle Kombinationen dann durchzugehen und darauf die Levenshtein-Distanz zu bestimmen! Hat einer einen Tipp, wie ich das Teilproblem angehen könnte?</p>
<p>Wäre mir eine große Hilfe, wenigstens ansatzweise einen Tipp zu bekommen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_tongue"
      title=":P"
      alt="😛"
    /></p>
<p>Danke im Voraus</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/288033/periods-of-strings</link><generator>RSS for Node</generator><lastBuildDate>Thu, 20 Aug 2026 04:12:22 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/288033.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 09 Jun 2011 09:19:07 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Periods of Strings on Thu, 09 Jun 2011 09:20:09 GMT]]></title><description><![CDATA[<p>Hallo miteinander,</p>
<p>ich habe als Aufgabe in unserem Proseminar eine der Problemstellungen des ACM ICPC zu lösen, jedoch habe ich einige Denkblockaden im Moment.</p>
<p>Zunächst <a href="http://www3.in.tum.de/teaching/ss11/ACMProseminar/Proseminar_Themen/Period.pdf" rel="nofollow">hier</a> die Aufgabenstellung.</p>
<p>Den Anfang mit der Distanz zweier Strings werde ich mit der Levenshtein-Distanz machen - das ist kein Problem. Aber ich scheitere am zweiten Teil den String x in nichtleere Teilstrings aufzuteilen und alle Kombinationen dann durchzugehen und darauf die Levenshtein-Distanz zu bestimmen! Hat einer einen Tipp, wie ich das Teilproblem angehen könnte?</p>
<p>Wäre mir eine große Hilfe, wenigstens ansatzweise einen Tipp zu bekommen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_tongue"
      title=":P"
      alt="😛"
    /></p>
<p>Danke im Voraus</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2075585</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2075585</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 09 Jun 2011 09:20:09 GMT</pubDate></item><item><title><![CDATA[Reply to Periods of Strings on Thu, 09 Jun 2011 10:01:47 GMT]]></title><description><![CDATA[<p>Ich würds so angehen:</p>
<ol>
<li>
<p>Du zerlegst den String der Länge N in k substrings, wobei k von 1 bis N läuft (okay, die Randwerte 1 und N sind trivial und können evtl. rausgenommen werden...)<br />
-&gt; mach eine Schleife für k=1..N</p>
</li>
<li>
<p>Bei einer Zerlegung in n Substrings kann der erste substring eine Länge s1 von 1 bis N-(n-1) haben, (im letzten Fall hast du dann s1 = N-(n-1), s2=s3=...=sk=1)<br />
-&gt; Mach eine Schleife für s1=1..(N-(n-1)) darin entnimmst du den ersten substring und unterteilst rekurdiv den Rest des Strings in n-1 substrings<br />
-&gt; wenn n=1 ist das zerlegen fertig und du kannst deine substring-sammlung analysieren.</p>
</li>
</ol>
<p>Pseudocode:</p>
<pre><code>string S
substringarray sa
for k:=1..length(S)
  zerlege(S in k)

zerlege(str in n):
  if n = 1
    teste(sa)
    fertig
  else for s1:=1..(length(str) - (n - 1))
    sa.push_back (substring(0..s1 of str))
    zerlege((substring((s1+1)..length(str) of str) in (n-1))
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2075600</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2075600</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Thu, 09 Jun 2011 10:01:47 GMT</pubDate></item><item><title><![CDATA[Reply to Periods of Strings on Thu, 09 Jun 2011 11:38:12 GMT]]></title><description><![CDATA[<p>Da ich noch nie sowas verschachteltes gemacht habe, bräcuhte ich vllt. etwas mehr Unterstüzung. Kannst du mir sagen, ob diese Umsetzung dem Pseudocode gerecht wird oder ob ich Blödsinn mit den Pointern anstelle <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_tongue"
      title=":P"
      alt="😛"
    /></p>
<p>EDIT:</p>
<p>Code entfernt! Ich habe doch folgende Situation, oder:</p>
<p>(Da hier kein LaTeX angezeigt wird ein kleiner <a href="http://bit.ly/jvznbh" rel="nofollow">Link</a>)</p>
<p>Dabei ist &quot;klein Sigma&quot; die Substring-Funktion und das frakturierte L der Levenshtein-Algo, der die Strings y und den Teilstring akzeptiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2075630</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2075630</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 09 Jun 2011 11:38:12 GMT</pubDate></item><item><title><![CDATA[Reply to Periods of Strings on Thu, 09 Jun 2011 12:12:18 GMT]]></title><description><![CDATA[<p>Christian Ivicevic schrieb:</p>
<blockquote>
<p>EDIT:</p>
<p>Code entfernt!</p>
</blockquote>
<p>Ich hatte leider grade Meeting, sonst hätte ich dir ein bisshcen Feedback zu dem Code gegeben...</p>
<blockquote>
<p>Ich habe doch folgende Situation, oder:</p>
<p>(Da hier kein LaTeX angezeigt wird ein kleiner <a href="http://bit.ly/jvznbh" rel="nofollow">Link</a>)</p>
<p>Dabei ist &quot;klein Sigma&quot; die Substring-Funktion und das frakturierte L der Levenshtein-Algo, der die Strings y und den Teilstring akzeptiert.</p>
</blockquote>
<p>Ähm. Wie genau liefert σ aus zwei Indizes den Substring?<br />
Ist für deine Berechnung die komplette Stringzerlegung wichtig oder nur jeweils ein einzelner Substring?</p>
<p>D.h., beim String &quot;abcd&quot;, ist es da wichtig, ob der String in a|b|cd zerlegt wurde oder in ab|cd, wenn du den substring cd betrachtest?<br />
Levenshtein sagt mir grade garnichts, deshalb kann ich dir dazu nicht viel sagen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2075679</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2075679</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Thu, 09 Jun 2011 12:12:18 GMT</pubDate></item><item><title><![CDATA[Reply to Periods of Strings on Thu, 09 Jun 2011 12:21:46 GMT]]></title><description><![CDATA[<p>Levenshtein ist eh für den Sachverhalt unwichtig. Das ist nur der Algorithmus, den ich auf den String y und die Teilstrings von x anwenden muss. Dieser Teil funktioniert bei mir bisher prima <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /><br />
Allerdings habe ich noch ein Teilproblem zu lösen - wenn dies gelöst ist, kann ich ja mal meinen fertigen Code posten, weil ich bisher das etwas &quot;dirty&quot; habe und noch ein kleiner Bug drin ist.</p>
<p>Angenommen ich habe meinen String x = abababab (Beispiel von der Angabe!), dann entspricht das x = (abababab)^1 = (abab)^2 = (ab)^4. Eine einfache Rekursionsvorschrift der Form s^0 := &quot;&quot;, s^n+1 = s*s^n, wobei * für die Konkatenation steht. Wie könnte ich am galantesten diese &quot;exact period&quot;, wie sie genannt wird, überprüfen?</p>
<p>// EDIT: allein schon mit der doppelten Summe schaffe ich es <strong>alle</strong> Substrings zu extrahieren. <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="🙄"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2075688</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2075688</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 09 Jun 2011 12:21:46 GMT</pubDate></item><item><title><![CDATA[Reply to Periods of Strings on Thu, 09 Jun 2011 12:27:23 GMT]]></title><description><![CDATA[<p>Christian Ivicevic schrieb:</p>
<blockquote>
<p>Wie könnte ich am galantesten diese &quot;exact period&quot;, wie sie genannt wird, überprüfen?</p>
</blockquote>
<p>wenn exact period heißt, dass es s und i geben muss mit x=s<sup>i</sup>, dann ist das Problem noch deutlich einfacher:</p>
<p>Sei n die Länge von x.<br />
Für jeden echten Teiler t von n überprüfe:<br />
Bilde t/n Substrings s(0,t-1), ..., s(n-t,n-1) der Länge t und vergleiche sie miteinander. Wenn alle gleich sind, ist x = s(0,t-1)<sup>t</sup></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2075690</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2075690</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Thu, 09 Jun 2011 12:27:23 GMT</pubDate></item><item><title><![CDATA[Reply to Periods of Strings on Thu, 09 Jun 2011 13:05:50 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">int n = x.length();
bool isExact = false;
for(int t = 2; t &lt; n; t++) {
	if(n % t == 0) {
		string s = x.substr(0, n/t);
		for(int j = n/t; j &lt; n - n/t; j += n/t) {
			if(s != x.substr(j, n/t)) {
				isExact = false;
				break;
			} else
				isExact = true;
		}
	}
}

if(isExact) /* do something ^^ */;
</code></pre>
<p>Ich muss zugeben etwas unschön <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_tongue"
      title=":P"
      alt="😛"
    /> Aber trifft es so in etwa den Gedankengang?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2075713</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2075713</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 09 Jun 2011 13:05:50 GMT</pubDate></item><item><title><![CDATA[Reply to Periods of Strings on Thu, 09 Jun 2011 15:12:27 GMT]]></title><description><![CDATA[<p>Christian Ivicevic schrieb:</p>
<blockquote>
<p>Ich muss zugeben etwas unschön <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_tongue"
      title=":P"
      alt="😛"
    /></p>
</blockquote>
<p>Sehr tiefe Schachtelung, allerdings <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>Christian Ivicevic schrieb:</p>
<blockquote>
<p>Aber trifft es so in etwa den Gedankengang?</p>
</blockquote>
<p>Jap.</p>
<pre><code class="language-cpp">string exactPeriod(string const&amp; x)
{
  string::size_t length = x.length();
  for (unsigned k = length; k &gt; 1; --i ) //oben anfangen, da die hohen &quot;potenzen&quot; so zuerst geprueft werden
  {
    if (length % k) continue; //nicht in k substrings teilbar

    //wir teilen den string in k substrings der laenge dist
    std::size_t dist = length/k;
    //der erste: 
    char const* first = x.data();
    //letzte davon beginnt (k-1)*dist nach dem ersten
    char const* last = first + ((k-1)*dist);

    //durch alle bis auf den letzten substring iterieren...
    for(; first &lt; last; first += dist)
    { 
      //... und jeden mit seinem Nachfolger vergleichen:
      //bei Ungleichheit Abbruch der Schleife
      if (strncmp(first, first+dist, dist) != 0) break;
    }
    //falls die Schleife komplett durchlaufen wurde waren alle substrings gleich
    if (first==last) return string(first, first+dist);
  }
  return x; //x = x^1
}

//...
string period = period(x);
unsigned exponent = x.length()/perod.length();
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2075815</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2075815</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Thu, 09 Jun 2011 15:12:27 GMT</pubDate></item><item><title><![CDATA[Reply to Periods of Strings on Thu, 09 Jun 2011 17:33:01 GMT]]></title><description><![CDATA[<p>Dein <code>string::size_t</code> müsste <code>string::size_type</code> heißen! Zumindest kennt VS bei mir nur das <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="😉"
    /> Des Weiteren würde es mich interessieren, ob die string-Klasse nicht Methoden bietet, um nicht auf die Pointer-Ebene gehen zu müssen und Funktionen wie <code>strncmp</code> zu umgehen.</p>
<p>Außerdem muss ich nur prüfen, ob die exakte Periode gleich dem zweiten String ist -&gt; keine Spielerei mit Exponenten etc. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2075904</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2075904</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 09 Jun 2011 17:33:01 GMT</pubDate></item><item><title><![CDATA[Reply to Periods of Strings on Thu, 09 Jun 2011 17:36:35 GMT]]></title><description><![CDATA[<p>Christian Ivicevic schrieb:</p>
<blockquote>
<p>Dein <code>string::size_t</code> müsste <code>string::size_type</code> heißen! Zumindest kennt VS bei mir nur das <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="😉"
    /> Des Weiteren würde es mich interessieren, ob die string-Klasse nicht Methoden bietet, um nicht auf die Pointer-Ebene gehen zu müssen und Funktionen wie <code>strncmp</code> zu umgehen.</p>
</blockquote>
<p>Ja, die Klasse bietet so einiges, z.B. überladene Vergleichs-Operatoren oder auch compare().</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2075907</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2075907</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Thu, 09 Jun 2011 17:36:35 GMT</pubDate></item><item><title><![CDATA[Reply to Periods of Strings on Thu, 09 Jun 2011 18:01:51 GMT]]></title><description><![CDATA[<p>Nun habe ich mein Programm endlich fertig <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="😉"
    /> Verbessrungsvorschläge zur Optimierung etc. sind natürlich gerne gesehen!</p>
<pre><code class="language-cpp">/*
 ============================================================================
 Name        : Periods / main.cpp
 Author      : Christian Ivicevic
 Description : 42
 ============================================================================
*/

/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

#include &lt;iostream&gt;  // I/O
#include &lt;string&gt;    // std::string
#include &lt;vector&gt;    // matrix in levenshtein and input

namespace periods {
	// Returns the exact period of a given string if there is one; otherwise the
	// given string.
	std::string getExactPeriod(std::string const&amp; x);
	// Returns the edit distance between two given objets s1 and s2 over
	// an alphabet Sigma.
	template &lt;class _Ty&gt;
	unsigned int levenshtein(const _Ty&amp; s1, const _Ty&amp; s2);
}

// Main function.
int main(int argv, char **argc) {
	// vector holding all input strings.
	std::vector&lt;std::string&gt; vx, vy;
	// pointers to strings
	std::string *x, *y;
	// the minimum integer value k such that a string y is a k-approximate period
	// of string x.
	unsigned int k = INT_MAX - 1;

	/* INPUT */
	unsigned int iTestCases = -1;
	std::cin &gt;&gt; iTestCases;
	for(unsigned int temp = 0; temp &lt; iTestCases; ++temp) {
		std::string string;
		// read string y
		std::cin &gt;&gt; string;
		vy.push_back(string);
		// read string x
		std::cin &gt;&gt; string;
		vx.push_back(string);
	}
	std::cout &lt;&lt; &quot;--------------------------&quot; &lt;&lt; std::endl;

	/* LOOP */
	for(unsigned int iCurrentCase = 0; iCurrentCase &lt; iTestCases; ++iCurrentCase) {
		x = &amp;vx[iCurrentCase];
		y = &amp;vy[iCurrentCase];
		std::string::size_type length = x-&gt;length();

		// check whether we have an exact period
		// both sides can be periodic and a period of themselves!
		if(periods::getExactPeriod(y[0]) == periods::getExactPeriod(x[0]))
			k = 0;

		// approximate period
		if(k != 0) {
			// iteration
			for(unsigned int i = 0; i &lt;= length; ++i) {
				for(unsigned int j = i; j &lt; length; ++j) {
					if(j != 0) {
						// look for minimal distance
						unsigned int dist = periods::levenshtein(*y, x-&gt;substr(i, j));
						if(dist != 0 &amp;&amp; dist &lt; k)
							k = dist;
					}
				}
			}
		}

		std::cout &lt;&lt; k &lt;&lt; std::endl;
		// reset for next test case
		k = INT_MAX - 1;
	}
	/* END */
	std::cin.get();
	std::cin.get();
	return 0;
}

namespace periods {
	// Returns the exact period of a given string if there is one; otherwise the
	// given string.
	std::string getExactPeriod(std::string const&amp; x) {
		std::string::size_type length = x.length();
		// start at the end to check high powers first
		for(unsigned int k = length; k &gt; 1; --k) {
			// not splittable in k substrings
			if(length % k) continue;

			// divide string in k parts of length dist
			std::size_t dist = length / k;
			// first
			char const* first = x.data();
			// last
			char const* last = first + ((k - 1) * dist);

			// iterate over every substring except the last one!
			for(; first &lt; last; first += dist) {
				// compare with successor: break if not equal
				if(strncmp(first, first+dist, dist)) break;
			}

			// if the loop is at the end all substrings were equal
			if(first==last)
				return std::string(first, first+dist);
		}
		return x;
	}

	// Returns the edit distance between two given objets s1 and s2 over
	// an alphabet Sigma.
	template &lt;class _Ty&gt;
	unsigned int levenshtein(const _Ty&amp; s1, const _Ty&amp; s2) {
		// create matrix
		const std::size_t len1 = s1.size(), len2 = s2.size();
		std::vector&lt; std::vector&lt;unsigned int&gt; &gt; d(len1 + 1, std::vector&lt;unsigned int&gt;(len2 + 1));

		// recurrencies
		d[0][0] = 0;
		for(unsigned int i = 1; i &lt;= len1; ++i) d[i][0] = i;
		for(unsigned int i = 1; i &lt;= len2; ++i) d[0][i] = i;

		for(unsigned int i = 1; i &lt;= len1; ++i)
			for(unsigned int j = 1; j &lt;= len2; ++j)
 				d[i][j] = std::min(std::min(d[i - 1][j] + 1,d[i][j - 1] + 1), d[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : 1));

		// the result is the last pivot!
		return d[len1][len2];
	}
}

/* EOF */
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2075922</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2075922</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 09 Jun 2011 18:01:51 GMT</pubDate></item></channel></rss>