<?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[Überlappende Intervalle]]></title><description><![CDATA[<p>Guten Abend,</p>
<p>ich habe eine Frage, wie man ein Problem algorithmisch elegant in C++ lösen könnte.</p>
<p>Ich habe N Intervalle, die alle einen Start und Endwert sowie Namen haben (Anfangs immer nur einen), also sowas:</p>
<pre><code>struct Interval {
    double start, end;
    vector&lt;string&gt; names;
};
</code></pre>
<p>Sagen wir ich habe beispielweise diese 3 Intervalle:</p>
<pre><code>Interval A(0, 100, &quot;A&quot;); // Intervall A geht von 0 bis 100
Interval B(80, 200, &quot;B&quot;);
Interval A(150, 300, &quot;C&quot;);
</code></pre>
<p>Ich will nun alle Intervalle so vereinigen, dass ich in jedem neuen Intervall weiß, welche Intervalle aktiv sind.<br />
Das Ergebnis aus den oberen 3 Intervallen wäre hier:<br />
1. Interval: (0, 80, &quot;A&quot;) // Von 0 bis 80 gibt es nur Intervall A<br />
2. Interval: (80, 100, &quot;A&quot;, &quot;B&quot;) // Von 80 bis 100 ist Intervall A und B (überlappen sich)<br />
3. Interval: (100, 150, &quot;B&quot;)<br />
4. Interval: (150, 200, &quot;B&quot;, &quot;C&quot;)<br />
5. Interval: (200, 300, &quot;C&quot;)</p>
<p>Wie könnte man das schön lösen? Gibts da evtl. was in std::algorithm oder boost?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/328434/überlappende-intervalle</link><generator>RSS for Node</generator><lastBuildDate>Tue, 07 Jul 2026 17:18:33 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/328434.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 09 Oct 2014 18:54:33 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Überlappende Intervalle on Thu, 09 Oct 2014 18:54:33 GMT]]></title><description><![CDATA[<p>Guten Abend,</p>
<p>ich habe eine Frage, wie man ein Problem algorithmisch elegant in C++ lösen könnte.</p>
<p>Ich habe N Intervalle, die alle einen Start und Endwert sowie Namen haben (Anfangs immer nur einen), also sowas:</p>
<pre><code>struct Interval {
    double start, end;
    vector&lt;string&gt; names;
};
</code></pre>
<p>Sagen wir ich habe beispielweise diese 3 Intervalle:</p>
<pre><code>Interval A(0, 100, &quot;A&quot;); // Intervall A geht von 0 bis 100
Interval B(80, 200, &quot;B&quot;);
Interval A(150, 300, &quot;C&quot;);
</code></pre>
<p>Ich will nun alle Intervalle so vereinigen, dass ich in jedem neuen Intervall weiß, welche Intervalle aktiv sind.<br />
Das Ergebnis aus den oberen 3 Intervallen wäre hier:<br />
1. Interval: (0, 80, &quot;A&quot;) // Von 0 bis 80 gibt es nur Intervall A<br />
2. Interval: (80, 100, &quot;A&quot;, &quot;B&quot;) // Von 80 bis 100 ist Intervall A und B (überlappen sich)<br />
3. Interval: (100, 150, &quot;B&quot;)<br />
4. Interval: (150, 200, &quot;B&quot;, &quot;C&quot;)<br />
5. Interval: (200, 300, &quot;C&quot;)</p>
<p>Wie könnte man das schön lösen? Gibts da evtl. was in std::algorithm oder boost?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2421515</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2421515</guid><dc:creator><![CDATA[algor]]></dc:creator><pubDate>Thu, 09 Oct 2014 18:54:33 GMT</pubDate></item><item><title><![CDATA[Reply to Überlappende Intervalle on Thu, 09 Oct 2014 19:01:24 GMT]]></title><description><![CDATA[<p>Du machst eine Liste von &quot;Events&quot; (um 0 füge &quot;A&quot; ein; um 100 entferne &quot;A&quot;; um 80 füge &quot;B&quot; ein, etc.) und sortierst diese nach der Zeit. In einem set merkst du dir, welche Intervalle aktiv sind. Dann gehst du durch alle Events und updatest das set. Wenn du bei jeder Änderung der Zeit eine Kopie des Sets speicherst, hast du dein Endresultat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2421517</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2421517</guid><dc:creator><![CDATA[zweizeiler]]></dc:creator><pubDate>Thu, 09 Oct 2014 19:01:24 GMT</pubDate></item><item><title><![CDATA[Reply to Überlappende Intervalle on Thu, 09 Oct 2014 21:31:08 GMT]]></title><description><![CDATA[<p>zweizeiler schrieb:</p>
<blockquote>
<p>Du machst eine Liste von &quot;Events&quot; (um 0 füge &quot;A&quot; ein; um 100 entferne &quot;A&quot;; um 80 füge &quot;B&quot; ein, etc.) und sortierst diese nach der Zeit. In einem set merkst du dir, welche Intervalle aktiv sind. Dann gehst du durch alle Events und updatest das set. Wenn du bei jeder Änderung der Zeit eine Kopie des Sets speicherst, hast du dein Endresultat.</p>
</blockquote>
<p>Gute Idee,</p>
<p>ich setze das mal um:</p>
<pre><code>#include &lt;algorithm&gt;
#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;vector&gt;
#include &lt;string&gt;
#include &lt;set&gt;
#include &lt;functional&gt;
#include &lt;tuple&gt;

struct Interval 
{
    template&lt; typename C &gt;
    Interval( double s, double e, const C&amp; c )
        : start(s)
        , end_(e)
        , names( begin(c), end(c) )
    {}
    Interval( double s, double e, std::string&amp;&amp; name )
        : start(s)
        , end_(e)
        , names( 1, name )
    {}
    template&lt; typename E, typename Traits &gt; friend
        std::basic_ostream&lt; E, Traits &gt;&amp; operator&lt;&lt;( std::basic_ostream&lt; E, Traits &gt;&amp; out, const Interval&amp; i )
    {
        out &lt;&lt; &quot;[&quot; &lt;&lt; i.start &lt;&lt; &quot;..&quot; &lt;&lt; i.end_ &lt;&lt; &quot;] &quot;;
        copy( begin(i.names), end(i.names), std::ostream_iterator&lt; std::string &gt;( out, &quot; &quot; ) );
        return out;
    }
    double start, end_;
    std::vector&lt; std::string &gt; names;
};

using Event = std::tuple&lt; double, std::function&lt; void( std::set&lt; std::string &gt;&amp; ) &gt; &gt;;

Event begin( const Interval&amp; i )
{
    return std::make_pair( i.start, 
        [i]( std::set&lt; std::string &gt;&amp; s ) {  s.insert( i.names.front() ); } );
}
Event end( const Interval&amp; i )
{
    return std::make_pair( i.end_, 
        [i]( std::set&lt; std::string &gt;&amp; s ) { s.erase( i.names.front() ); } );
}

int main()
{
    using namespace std;
    vector&lt; Interval &gt; intervalle = {
        Interval( 0., 100., std::string(&quot;A&quot;) ),
        Interval( 80., 200., std::string(&quot;B&quot;) ),
        Interval( 150., 300., std::string(&quot;C&quot;) )
    };
    vector&lt; Event &gt; events;   // .. eine Liste von &quot;Events&quot; ..
    for( auto i: intervalle )
    {
        events.push_back( begin(i) );   // um 0 füge &quot;A&quot; ein; 
        events.push_back( end(i) );     // um 100 entferne &quot;A&quot;;
    }
    // .. und sortierst diese nach der Zeit ..
    sort( begin(events), end(events), []( const Event&amp; e1, const Event&amp; e2 )-&gt;bool { return get&lt;0&gt;(e1) &lt; get&lt;0&gt;(e2); } );

    if( !events.empty() )
    {
        set&lt; string &gt; buffer;   // In einem set merkst du dir, welche Intervalle aktiv sind.
        auto prev = begin(events);
        for( auto next = prev; ++next != end(events); prev = next ) // Dann gehst du durch alle Events ..
        {
            get&lt;1&gt;(*prev)( buffer ); // .. und updatest das set. Wenn du bei jeder Änderung der Zeit ..
            cout &lt;&lt; Interval( get&lt;0&gt;(*prev), get&lt;0&gt;(*next), buffer ) &lt;&lt; endl; // .. eine Kopie speicherst, hast du dein Endresultat
        }
    }
    return 0;
}
</code></pre>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2421538</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2421538</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Thu, 09 Oct 2014 21:31:08 GMT</pubDate></item><item><title><![CDATA[Reply to Überlappende Intervalle on Thu, 09 Oct 2014 21:44:17 GMT]]></title><description><![CDATA[<p>Werner Salomon schrieb:</p>
<blockquote>
<p>Gute Idee, ich setze das mal um:</p>
</blockquote>
<p>Wow, das ist wirklich sehr wortgetreu umgesetzt. Das einzige, was fehlt, ist</p>
<blockquote>
<p>Wenn du bei jeder Änderung der Zeit ..</p>
</blockquote>
<p>Füge in intervalle noch &quot; <code>Interval( 0., 80., std::string(&quot;D&quot;) ), Interval( 0., 80., std::string(&quot;E&quot;) ),</code> &quot; ein und man erhält so Stellen wie &quot;[0..0] A\n[0..0] A D&quot; und &quot;[80..80] A B D E\n[80..80] A B E&quot;, was vermutlich unerwünscht ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2421539</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2421539</guid><dc:creator><![CDATA[zweizeiler]]></dc:creator><pubDate>Thu, 09 Oct 2014 21:44:17 GMT</pubDate></item><item><title><![CDATA[Reply to Überlappende Intervalle on Fri, 10 Oct 2014 14:08:22 GMT]]></title><description><![CDATA[<p>algor schrieb:</p>
<blockquote>
<p>Wie könnte man das schön lösen? Gibts da evtl. was in std::algorithm oder boost?</p>
</blockquote>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;set&gt;
#include &lt;string&gt;
#include &lt;utility&gt;

#include &lt;boost/icl/interval_map.hpp&gt;

int main(){
  using namespace std;
  using namespace boost::icl;

  using names = set&lt;string&gt;;

  interval_map&lt;int, names&gt; m;
  m+=make_pair(interval&lt;int&gt;::right_open(0,100), names{&quot;A&quot;});
  m+=make_pair(interval&lt;int&gt;::right_open(80,200), names{&quot;B&quot;});
  m+=make_pair(interval&lt;int&gt;::right_open(150,300), names{&quot;C&quot;});

  for(const auto&amp; it : m)
    cout &lt;&lt; it.first &lt;&lt; &quot; : &quot; &lt;&lt; it.second &lt;&lt; '\n';
}
/*
[0,80) : {A }
[80,100) : {A B }
[100,150) : {B }
[150,200) : {B C }
[200,300) : {C }
*/
</code></pre>
<p>Boost.Icl kannte ich auch nicht.<br />
Schadet aber sicher nicht, die Bibliothek hier mal zu erwähnen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2421631</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2421631</guid><dc:creator><![CDATA[Furble Wurble]]></dc:creator><pubDate>Fri, 10 Oct 2014 14:08:22 GMT</pubDate></item></channel></rss>