0

Ich habe den folgenden Code, der die Stirling-Zahl der zweiten Art für ein gegebenes n und k,Warum wird dieser Code segregiert?

#include <cstdint> 
#include <map> 

#include <boost/multiprecision/cpp_int.hpp> 

namespace mp = boost::multiprecision; 


mp::cpp_int stirlingS2(unsigned n, unsigned k) 
{ 
    if (n == 0 && k == 0) { 
     return 1; 
    } 

    if (n == 0 || k == 0) { 
     return 0; 
    } 

    static auto memo = std::map<std::pair<unsigned, unsigned>, mp::cpp_int>(); 
    auto nKPair = std::pair<unsigned, unsigned>(n, k); 

    if (memo.count(nKPair) > 0) { 
     return memo[nKPair]; 
    } 

    auto val = k * stirlingS2(n - 1, k) + stirlingS2(n - 1, k - 1); 

    memo[nKPair] = val; 

    return val; 
} 

Leider, wenn dieser Code ausgeführt wird, ist es Segfaults berechnet. Es scheint für die ersten 87795-Werte, die in memo eingefügt wurden, gut zu laufen, stürzt dann aber kurz darauf ab. Insbesondere tritt der Segfault bei map::count in der Zeile if (memo.count(nKPair) > 0) { auf. Ich dachte, vielleicht war dies eine Frage der memo aus Größe ausgeführt, so dass ich addierten folgende Einschränkung der Zuordnung zu memo,

if (memo.size() < memo.max_size()) { 
    memo[nKPair] = val; 
} 

Aber das half nicht. Ich habe auch bemerkt, dass der 87795-Wert nicht anzeigt, wann dieser abstürzt. Mit einigen kleineren Modifikationen, die Änderung der ersten if-Anweisung,

if (n <= k) { 
    return 1; 
} 

ändert diesen Wert 66453.

Weiß jemand, was hier vor sich geht?

+0

Wo möchten Sie etwas in Memo einfügen? –

+0

Bist du sicher, dass der segfault in der 'memo.count' Zeile ist und nicht damit zu tun hat, dass der Stack durch eine tiefe Rekursion durchgebrannt wird, weil er nicht richtig memoisiert wurde? – oldrinb

+0

@DavidThomas, fügt 'operator []' kein neues Element für einen Schlüssel ein, wenn der Schlüssel noch nicht existiert? –

Antwort

0

Ok, also nach Stunden der Verwirrung, habe ich dies auf ein Problem mit Expression Templates reduziert. Ich verstehe wirklich nicht vollständig, warum, aber es ist alles mit diesen kleinen auto in der Linie

auto val = k * stirlingS2(n - 1, k) + stirlingS2(n - 1, k - 1) 

Grundsätzlich zu tun hatte, zu ändern, dass auto-mp::cpp_int und plötzlich, ohne segfault.

Verwandte Themen