天真的矢量交换仅部分工作

时间:2017-03-10 14:56:24

标签: c++ sorting

我有一个包含数据测量名称和索引的配对向量<string,int>pairedv。至少测试数据的大小约为780次测量,大约是一半水,另一半是其他液体。因为我希望这个程序的文件输出尽可能方便用户,我试图将输出预分为两个部分,一个水部分和另外一个&#34;部分。

在下面代码的最后一个循环中,我有一个bool vector掩码,用于表示相应的测量名称不包含&#34; water&#34;或任何常见的变体。如果bool[i]返回true,则递增计数器以便稍后使用,否则它会找到下一个&#34; water&#34;测量,并切换两个元素的值。

#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;
}

如果我将最后一次循环运行两次,它会在“水”#34之前对水的测量值进行排序。测量。但是,这绝对是次优解决方案;我可以做什么来一次排序?

1 个答案:

答案 0 :(得分:0)

您可以使用std::partition(或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()[