幼稚的矢量交换仅部分工作

Naive vector swapping only partially working

本文关键字:仅部 工作 交换      更新时间:2023-10-16

i有一个配对的向量<string,int>pairedv包含数据测量名称和索引。大小至少在测试数据中,大约是780次测量,大约一半水,另一个液体一半。因为我希望该程序中的文件输出尽可能用用户友好,所以我试图将输出预设为两个部分,一个水部分和"其他"部分。

在下面代码的最后一个循环中,我有一个bool vector掩码,适用于其相应的测量名称不包含"水"或任何常见变体时。如果bool[i]返回True,它会增加以后使用的计数器,否则会找到下一个"水"测量值,并切换两个元素的值。


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

如果我两次运行最后一个循环,它确实在"非水"测量之前对水测量进行了分类。但是,这绝对是一个最佳的解决方案。我该怎么做才能分类?

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