Wie würden Sie manuell auf Papier zählen? Du würdest die letzte Ziffer überprüfen. Wenn es 0 ist, setzen Sie es auf 1. Wenn es bereits 1 ist, setzen Sie es zurück auf 0 und fahren mit der nächsten Ziffer fort. Es ist also ein rekursiver Prozess.
Das folgende Programm erzeugt alle möglichen Kombinationen durch eine Sequenz mutiert:
#include <iostream>
template <typename Iter>
bool next(Iter begin, Iter end)
{
if (begin == end) // changed all digits
{ // so we are back to zero
return false; // that was the last number
}
--end;
if ((*end & 1) == 0) // even number is treated as zero
{
++*end; // increase to one
return true; // still more numbers to come
}
else // odd number is treated as one
{
--*end; // decrease to zero
return next(begin, end); // RECURSE!
}
}
int main()
{
char test[] = "0000";
do
{
std::cout << test << std::endl;
} while (next(test + 0, test + 4));
}
Das Programm mit einer beliebigen Reihenfolge jeder Art funktioniert. Wenn Sie alle möglichen Kombinationen gleichzeitig benötigen, legen Sie sie einfach in eine Sammlung, anstatt sie auszudrucken. Natürlich benötigen Sie einen anderen Elementtyp, da Sie C-Arrays nicht in einen Vektor einfügen können. Werfen wir einen Vektor von Strings verwenden:
#include <string>
#include <vector>
int main()
{
std::vector<std::string> combinations;
std::string test = "0000";
do
{
combinations.push_back(test);
} while (next(test.begin(), test.end()));
// now the vector contains all pssible combinations
}
Wenn Sie hier nicht Rekursion mögen, ist eine äquivalente iterative Lösung:
template <typename Iter>
bool next(Iter begin, Iter end)
{
while (begin != end) // we're not done yet
{
--end;
if ((*end & 1) == 0) // even number is treated as zero
{
++*end; // increase to one
return true; // still more numbers to come
}
else // odd number is treated as one
{
--*end; // decrease to zero and loop
}
}
return false; // that was the last number
}
@Fred, wenn ich eine Lisp Antwort und eine C# Antwort wissen, bin ich hinzufügen „[Lisp]“ und „[C#]“ oder sollten wir ersetzen Sie einfach alle durch „[sprachunabhängig]“? –
@Johannes: Ich würde gerne LISP und C# -Lösungen sehen :-) Ich habe das C++ - Tag hinzugefügt, weil Nils die Frage im C++ - Chat gepostet hat, also nahm ich an, dass er an einer C++ - Lösung interessiert war. Und ich habe den Haskell-Tag hinzugefügt, damit echte Haskell-Programmierer meine Haskell-Lösung verbessern konnten. – fredoverflow