Forum: Compiler & IDEs C++ mehrere Int Variablen mit einander vergleichen


von agneu (Gast)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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.

von Christian B. (casandro)


Lesenswert?

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.

von Daniel A. (daniel-a)


Lesenswert?

1
// ungetestet
2
#include <stddef.h>
3
#include <stdbool.h>
4
#include <stdio.h>
5
6
int main(){
7
  int nums[] = {1,2,3,4,5,6,7,8,9,0};
8
  size_t num_count = sizeof(nums)/sizeof(*nums);
9
  size_t i,j;
10
  bool unique=true;
11
  for( i=0; i < num_count; i++ )
12
    for( j=i+1; j < num_count; j++ )
13
      if( nums[j] == nums[i] ){
14
        unique = false;
15
        break;
16
      }
17
  if( unique ){
18
    printf("every number is unique\n");
19
  }else{
20
    printf("not every number is unique\n");
21
  }
22
  return 0;
23
}

von Hans (Gast)


Lesenswert?

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 ...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

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 )
25
{
26
    return contains_duplicates( values.begin(), values.end() );
27
}
28
29
int main()
30
{
31
    assert( !contains_duplicates( std::initializer_list< int >{} ) );
32
    assert( !contains_duplicates( { 2 } ) );
33
    assert( !contains_duplicates( { 2, 3, 1 } ) );
34
    assert( contains_duplicates( { 2, 2, 0 } ) );
35
    assert( contains_duplicates( { 2, 0, 2 } ) );
36
37
    const int i1 = 1, i2 = 2, i3 = 3, i4 = 4, i5 = 5, i6 = 6, i7 = 7;
38
39
    assert( !contains_duplicates( { i1, i2, i3, i4, i5, i6, i7 } ) );
40
}

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

von g457 (Gast)


Lesenswert?

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

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Torsten R. schrieb:
>     if ( begin == end )
>         return false;


Das ist überflüssig, da es schon der Schleifenbedingung weiter unten 
entspricht.

von apr (Gast)


Lesenswert?

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!

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

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.

von Sven B. (scummos)


Lesenswert?

std::unordered_set items = {1, 2, 3, 4, 3, 4, 6}?

von B. S. (bestucki)


Lesenswert?

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.

von g457 (Gast)


Lesenswert?

>> 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 [..]
2
            ^^^^^^^^^^^

Nix für ungut.

[0] http://en.cppreference.com/w/cpp/algorithm/unique

von B. S. (bestucki)


Lesenswert?

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.

von Sven B. (scummos)


Lesenswert?

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

von Tom (Gast)


Lesenswert?

Wenn std::minmax_element nicht völlig blöd gebaut ist, sollte das O(n) 
sein. Geht natürlich nur bei mit < vergleichbaren Datentypen.
1
#include <algorithm>
2
#include <iostream>
3
#include <vector>
4
5
int main()
6
{
7
    std::vector<int> A{1,1,2,1,1};
8
    std::vector<int> B{1,1,1,1,1};
9
10
    auto mima = std::minmax_element(A.begin(), A.end());
11
    bool all_equal = (*mima.first == *mima.second);
12
13
    auto mima2 = std::minmax_element(B.begin(), B.end());
14
    bool all_equal2 = (*mima2.first == *mima2.second);
15
16
    
17
    std::cout << "A: " << all_equal << "\tB: " << all_equal2 << "\n";
18
19
20
}

von Tom (Gast)


Lesenswert?

Argh, es sollen alle ungleich sein. Problem nicht verstanden, setzen, 
5-.

von Arc N. (arc)


Lesenswert?

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...

: Bearbeitet durch User
von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

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.

von Fabian D. (fabian_d)


Lesenswert?

std::sort in Kombination mit std::adjacent_find wäre auch noch möglich.
1
std::vector<int> v{0, 1, 2, 3, 40, 40, 41, 41, 5};
2
auto it = std::adjacent_find(v.begin(), v.end());
3
if (it == v.end())
4
    // no equal elements found

von Heinz L. (ducttape)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.