Hallo zusammen,
ich stehe gerade ein bisschen auf dem Schlauch. Ich möchte gerne 10
integer Variablen auf Ungleichheit überprüfen und mir fällt gerade nicht
ein wie ich das am besten lösen könnte ohne jede Bedingung händisch
abzuklopfen.
Hat jemand von euch vielleicht eine Idee.
Vielen lieben Dank schon mal.
agneu schrieb:> Ich möchte gerne 10 integer Variablen auf Ungleichheit überprüfen und mir> fällt gerade nicht ein wie ich das am besten lösen könnte ohne jede> Bedingung händisch abzuklopfen.
Wenn du sie unbedingt als Einzelvariablen deklarieren musst, wird dir
nichts anderes übrig bleiben.
Abhängig von der Art und Weise wie die deklariert sind könntest Du auch
auf die erste Variable einen Zeiger machen und den dann weiter zählen...
das wäre aber die C-Variante.
Willst Du echtes C++ machen, so definierst Du die Integer als Klassen
und machst einen Iterator und kannst damit das Problem sicherlich schon
in 200-500 Zeilen lösen.
Ich persönlich finde es problematisch wenn man C++ als Lehrsprache
verwendet.
Das kommt drauf an, wo die Variablen liegen. Wenn sie in einem
Standard-Container wie std::vector untergebracht sind, kannst Du einfach
die beiden Container mit "==" vergleichen.
Wenn Du nur den Teil eines Containters oder auch C-Arrays vergleichen
willst, kannst Du std::equal benutzen. Oder Du schreibst eben selber
eine Schleife ...
Wenn bei Daniels Beispiel die innere Schleife abgebrochen wird (wenn
"unique" auf false gesetzt wird), ist es sinnlos, die äußere Schleife
weiterlaufen zu lassen. Also sollte eine Überprüfung von "unique" in die
Schleifenabbruchbedingung (i < num_count) einfließen.
agneu schrieb:> Hat jemand von euch vielleicht eine Idee.
Einfachster Algorithmus wäre, du gehst mit jedem Wert durch die ganze
Liste. Das kann man optimieren, in dem man nur noch die Elemente hinter
dem betrachteten Element durchsucht, da ein Duplikat vor dem
betrachtetem Element, vorher schon aufgefallen wäre:
1
#include <algorithm>
2
#include <initializer_list>
3
#include <cassert>
4
5
template < class Iter >
6
bool contains_duplicates( Iter begin, Iter end )
7
{
8
if ( begin == end )
9
return false;
10
11
for ( ; begin != end; )
12
{
13
const auto value = *begin;
14
++begin;
15
16
if ( std::find( begin, end, value ) != end )
17
return true;
18
}
19
20
return false;
21
}
22
23
template < class T >
24
bool contains_duplicates( const std::initializer_list< T >& values )
Der Algorithmus hat eine Komplexität von O(n^2). Wenn es sehr viel mehr
Elemente sind, als 10 dann könnte man die Elemente auch vorher sortieren
(O(log n) und dann einmal durch gehen und die Nachbarn betrachten
(n*O(log n))
mfg Torsten
Warum so C-Style wenns hier ausdrücklich um C++ geht? Wie wärs mit
std::sort+std::unique, oder std::set, oder std::map (mißbräuchliche
Nutzung), jeweils zusammen mit size()?
HTH
apr schrieb:> Torsten R. schrieb:>> als 10 dann könnte man die Elemente auch vorher sortieren>> (O(log n) und>> In O(log n) sortieren? Not bad!
Oder so ähnlich ;-) Auf jeden Fall deutlich besser als n^2. Danke für
den Hinweis.
g457 schrieb:> std::sort+std::unique
Für std::unique muss der Container nicht sortiert sein. Eine Möglichkeit
wäre auch noch std::sort + std::adjacent_find.
Ohne zu wissen, wie und wo die Variablen gespeichert sind, schlage ich
vor, die Variablen in ein std::set zu packen und nach jeden Einfügen zu
prüfen, ob der Wert eingefügt wurde oder nicht (via Rückgabewert von
std::set::insert). Wurde er nicht eingefügt, ist er bereits vorhanden.
>> std::sort+std::unique>> Für std::unique muss der Container nicht sortiert sein.
Da behauptet die Doku [0] was anderes, zumindest für die hiesigen
Zwecke:
1
Removes all consecutive duplicate elements from the range [..]
g457 schrieb:> Da behauptet die Doku [0] was anderes, zumindest für die hiesigen> Zwecke:> Removes all consecutive duplicate elements from the range [..]> ^^^^^^^^^^^
Oh, das Wort hab ich überlesen. Danke für die Korrektur.
g457 schrieb:> Nix für ungut.
Kein Problem.
g457 schrieb:>>> std::sort+std::unique>>>> Für std::unique muss der Container nicht sortiert sein.
Du denkst die Standardbibliothek macht, was du erwartest? Haha, guter
Witz :D
Hashtabelle: Einfügen, Suchen: O(1) (amortisiert)
Solange einfügen bis ein Element doppelt vorkommt.
Laufzeit O(n), Worstcase O(n²) in Abhängigkeit vom Wertebereich der
Integer, der Anzahl der Werte und der Implementation.
Ob das bei nur 10 Integern schneller ist, ist allerdings nicht sicher...
Mir fiele noch ein rekursiver Ansatz ein, d.h. eine Funktion, die das
erste Element einer Liste gegen den Rest der Liste vergleicht und sich
dann selbst mit dem Rest der Liste aufruft. Effizienz ist aber etwas
anderes.
Wenn die Liste sortiert ist braucht Du logischerweise einfach nur gucken
ob hintereinanderliegende Elemente gleich sind.
Die Frage ist halt jetzt ob Du irgendeinen Mehrwert woanders erhältst
wenn Du die Elemente sortierst, bzw ob es möglich ist sie vielleicht
schon beim Anlegen sortiert anzulegen, und ob das für Dein Problem
nützlich ist. Das weißt wohl nur Du selbst.