2017-06-07 4 views
0

Ich habe einen wirklich einfachen Code genau dort, die zählt, wie viel Werte Sie in Arrays benötigen.Zähler in Arrays C++

for (int i = 0; i < dm; i++) 
    { 
     if (arr[i] == c) 
     { 
      counter++; 
     } 
    }; 

Aber ich muss es ein wenig knifflig machen. Ich muss die Anzahl der gleichen Werte zählen. Stellen Sie sich vor, ich habe ein Array {4,4,4,3,3,2,2,1,1,0,0,0} und ich muss herausfinden, wie viel "Zwillinge" dort sind. Also 3,2,1 sind Zwillinge, weil sie nur einen genauen Freund haben. Ich habe so etwas wie 2 Fors und 2 Zähler versucht, aber immer noch Probleme haben. Vielen Dank. Ich hoffe du verstehst was ich mit "Zwilling" meine. x und x sind Zwillinge und y, y, y sind nicht (nur für den Fall)

+0

Ist Ihr Array immer sortiert? – Slava

+2

Machen Sie ein "Karte" -Objekt und speichern Sie die Zähler darin –

+0

@slava ja von höher zu niedriger wenn das, was Sie meinen – AlexMIEL

Antwort

0

Lösung ohne zusätzliche Array mit:

int twins_counter = 0; 
for (int i = 0; i < dm; i++) 
{ 
    int counter = 0; // counter for elements 
    for (int j = 0; j < dm; j++) 
    { 
     if (arr[i] == arr[j]) 
     { 
      if(j < i) 
      { 
       break; // we have searched twin for this element already 
      } 
      counter++; 
      if(counter > 2) 
      { 
       break; // we meet element third time, it isn't twin 
      } 
     } 
    } 

    if(counter == 2) 
    { 
      twins_counter++; 
    } 
}; 

Bei sortiert (nach oben oder unten) -Arrays eines Zyklus genügt:

int twins_counter = 0; 
int counter = 1; 

for (int i = 1; i < dm; i++) 
{ 
    if(arr[i] == arr[i-1]) 
    { 
     counter++; 
    } 
    else 
    { 
      if(counter == 2) 
      { 
       twins_counter++; 
       counter = 1; 
      } 
    } 
} 

// check last value 
if(counter == 2) 
{ 
    twins_counter++; 
} 
+0

Für sortierte Array können Sie diese Lösung noch mehr vereinfachen –

+0

Danke, aber können Sie mir einen Hinweis hinterlassen, wie ich es ändern muss, wenn ich zum Beispiel nur Elemente, die 4 mal in Array, nicht 2 mal wie Zwillinge finden müssen? – AlexMIEL

+0

@AlexMIEL Ändern Sie im Fehlerfall nur 2 zu 4. –

2

Ich würde eine Karte machen, die für jede einzelne Zahl im Array ihre Vorkommen zählt. Der Code könnte wie folgt aussehen:

#include <iostream> 
#include <map> 

int main() 
{ 
    const int numberOfElements = 12; 

    int array[numberOfElements] = { 4,4,4,3,3,2,2,1,1,0,0,0 }; 
    std::map<int,int> counts; 
    for (int i=0; i < numberOfElements; i++) { 
     counts[array[i]]++; 
    } 
    for (auto x : counts) { 
     if (x.second == 2) { 
      cout << "pair: " << x.first << endl; 
     } 
    } 
    return 0; 
} 

Wenn - aus irgendeinem Grund - der Bereich der Elemente begrenzt ist, können Sie auch eine „plain“ Array zum Zählen der Vorkommen nutzen könnten. Wenn zum Beispiel der Elemente im Bereich von 0..4 sind, könnten Sie das folgende Fragment verwenden:

const int numberOfElements = 12; 
const int elementMax = 4; 

int array[numberOfElements] = { 4,4,4,3,3,2,2,1,1,0,0,0 }; 
int counts[elementMax+1] = {}; 
for (int i=0; i<numberOfElements; i++) { 
    counts[array[i]]++; 
} 
for (int i=0; i <= elementMax; i++) { 
    if (counts[i] == 2) { 
     cout << "pair: " << i << endl; 
    } 
} 

Und wenn Ihr Array sortiert ist, als eine Lösung ohne Gegen Array könnte wie folgt aussehen:

const int numberOfElements = 12; 

int array[numberOfElements] = { 4,4,4,3,3,2,2,1,1,0,0,0 }; 
int prev = -1; 
int count = 0; 
for (int i=0; i<numberOfElements; i++) { 
    if (array[i] == prev) { 
     count++; 
    } 
    else { 
     if (count == 2) { 
      cout << "pair: " << prev << endl; 
     } 
     count=1; 
     prev = array[i]; 
    } 
} 
if (prev >= 0 && count==2) { 
    cout << "pair: " << prev << endl; 
} 
+0

Bitte vermeiden Sie die Verwendung magischer Zahlen – Slava

+0

Die Kommentare an das OP sagte das Array ist immer sortiert, so dass diese beiden sind viel zu viel Arbeit, Speicherverbrauch, etc. –

+0

@Daniel H: die ersten sind allgemeiner Lösungen, die ich gefunden habe es lohnt sich zu sagen; fügte auch eine Lösung für sortierte Arrays hinzu. –

1

Sie können das in einem Durchgang tun und binäre Suche verwenden für Effizienz:

int arr[] = { 4,4,4,3,3,2,2,1,1,0,0,0 }; 
int twins = 0; 
for(auto i = std::begin(arr); i != std::end(arr);) { 
    auto next = std::upper_bound(i, std::end(arr), *i, std::greater<int>()); 
    if(std::distance(i, next) == 2) ++twins; 
    i = next; 
}  

Live example

Falls es nicht zu viele Duplikate in dem Array std::upper_bound konnte nicht effizient sein und kann einfach ausgetauscht werden:

auto next = std::find_if(std::next(i), std::end(arr), [i](int n) { return *i != n; }); 
+0

O (n) für Ihre Lösung ist n * log n wegen der binären Suche auf jeder Schritt des Zyklus. Binäre Suche wird nicht benötigt - siehe meine Lösung. –

+0

@AlexanderUshakov Sie versuchen zu sagen, dass das vollständige Scannen von Arrays effizienter ist als die binäre Suche? Sie müssen Ihre O (n) Schätzung überdenken. Es wäre n * log n, wenn ich 'i' um 1 erhöhe und binär nach jedem Wert suche. – Slava

+0

Wenn alle Werte im Array unterschiedlich sind, ist Ihre Lösung die gleiche wie für jedes Element. Also ist O (n) davon n * log n. –