2017-03-10 6 views
0

Ich habe einen gepaarten Vektor <string,int>pairedv enthält Daten Messung Namen und Indizes. Die Größe, zumindest der Testdaten, beträgt ungefähr 780 Messungen, ungefähr die Hälfte Wasser, die Hälfte andere Flüssigkeit. Da ich möchte, dass die Dateiausgabe von diesem Programm so benutzerfreundlich wie möglich ist, versuche ich die Ausgabe in zwei Abschnitte vorzusortieren, einen Wasserabschnitt und einen "anderen" Abschnitt.Naive Vektor-Swapping nur teilweise funktioniert

In der letzten Schleife des Codes unten habe ich eine bool vector Maske für, wenn der entsprechende Messname nicht "Wasser" oder eine gemeinsame Variante enthält. Wenn bool[i] Wahr zurückgibt, erhöht es einen Zähler, der später verwendet werden soll, andernfalls findet es die nächste "Wasser" -Messung und schaltet die Werte für die zwei Elemente um.


#include <algorithm> 
#include <iostream> 
#include <iterator> 
#include <string> 
#include <vector> 

using namespace std; 

bool IsWater(const string &str1){ 
    if(str1.find("water")!=string::npos) 
     return (true); 
    //test file water measurements contain "*water*" only, remainder are for redundancy 
    if(str1.find("Water")!=string::npos) 
     return (true); 
    if(str1.find("WATER")!=string::npos) 
     return (true); 
    if(str1.find("H2O")!=string::npos) 
     return (true); 
    if(str1.find("h2o")!=string::npos) 
     return (true); 
    return false; 
} 



int main(int argc, char* argv[]){ 
    //pairedv is initialized with <string,int> values 
    //corresponding to measurement name, index 

    vector<bool> boolv; 
    for(int i=0;i<pairedv.size();i++){ 
     //fill bool vector with true if name contains water or variant 
     if(IsWater(pairedv[i].first)) 
      boolv.push_back(true); 
     else 
      boolv.push_back(false); 
    } 

    //initialize 'x' as counter; will be used later to split std::sort into halves 
    int x=0; 
    for(int i=0;i<boolv.size();i++){ 
     if(boolv[i]) 
      x++;   //if water, only increment x 
     else{    //if NOT water, swap with next "water" found 

      for(int i2=i+1;i2<boolv.size();i2++){ 
       if(boolv[i2]){ 

        string tempstr=pairedv[i].first; 
        int tempint=pairedv[i].second; 
        pairedv[i]=pairedv[i2]; 
        pairedv[i2]=make_pair(tempstr,tempint); 
       } 
      } 
     } 
    } 

    //... 
return 0; 
} 

Wenn ich diese letzten Schleife zweimal laufen, tut sie sortieren die Wassermessungen vor den „nicht Wasser“ Messungen. Dies ist jedoch definitiv eine suboptimale Lösung; Was kann ich tun, um in einem Durchgang zu sortieren?

+0

die Standard-Bibliothek sortieren verwenden. Sie müssen nur eine Vergleichsfunktion implementieren. –

+0

[std :: sort] (http://en.cppreference.com/w/cpp/algorithm/sort) – crashmstr

+0

@AnonMail Versuchen, das hat nicht für mich funktioniert. Es gab mir eine noch unfassbarere Ausgabe. –

Antwort

0

Sie könnten verwenden std::partition (oder std::stable_partition):

std::vector<std::pair<std::string, int>> pairedv /* = ...*/; 

auto isPairWater = [](const auto& p) { return IsWater(p.first); }; 
auto it = std::partition(pairedv.begin(), pairedv.end(), isPairWater); 

// water would be [pairedv.begin(); it[ 
// not water would be [it, pairedv.end()[ 
+0

Der eingegebene Code gibt folgenden Fehler zurück: 'Fehler: Bindung 'const std :: __ cxx11 :: basic_string ' zu Referenz vom Typ 'std :: __ cxx11 :: string & {aka std :: __ cxx11 :: basic_string &} verwirft Qualifier | ' Das Entfernen der' const' behebt dies, und es funktioniert, akzeptiert. Aber warum muss ich "const" weglassen? Liegt es am Lambda-Ausdruck? (Autodidakt, bis jetzt Lambda ist mir fremd) EDIT: Ignoriere die Kommentare auf 'const', ich sehe Ihre Bearbeitung zu meinem Code jetzt. Ist es notwendig, eine Variable zu "const", die von der Funktion sowieso nicht verändert wird? –

+0

Das Hinzufügen von 'const' ermöglicht es besser, intent zu erklären, und der Compiler erzwingt diese Prüfung. – Jarod42

Verwandte Themen