简体   繁体   English

3种向量的高效排序算法

[英]Efficient sorting algorithm for 3 vectors

I have 3 vectors, category description and price I have written this piece of code to put the vectors organised by category into a file called menuFile : 我有3个向量, category descriptionprice我编写了这段代码, menuFile category组织的向量放入一个名为menuFile的文件中:

for(int x = 0; x < _category.size(); x++){
    if(_category[x].compare("Starter") == 0){
        menuFile << _category[x] << ":" << _description[x] << ":" << _price[x] << endl;
    }
}

for(int x = 0; x < _category.size(); x++){
    if(_category[x].compare("Main") == 0){
        menuFile << _category[x] << ":" << _description[x] << ":" << _price[x] << endl;
    }
}

for(int x = 0; x < _category.size(); x++){
    if(_category[x].compare("Pudding") == 0){
        menuFile << _category[x] << ":" << _description[x] << ":" << _price[x] << endl;
    }
}

for(int x = 0; x < _category.size(); x++){
    if(_category[x].compare("Drink") == 0){
        menuFile << _category[x] << ":" << _description[x] << ":" << _price[x] << endl;
    }
}      

But this does not seem like a very efficient method. 但这似乎不是一种非常有效的方法。 Is the a better way to do this? 是更好的方法吗?

I believe you should create a struct to handle the three types of data and then make a vector for it. 我相信您应该创建一个结构来处理这三种类型的数据,然后为其创建向量。

for example: 例如:

struct Menu {
    string category;
    string description;
    int price;
};

then i would recommend you to implement a comparator to decide on how to sort the data. 那么我建议您实施一个比较器,以决定如何对数据进行排序。 Let's say sort by the price (You can decide on how to implement the overloaded operator of course). 假设按价格排序(您当然可以决定如何实现重载运算符)。

struct Menu {
    string category;
    string description;
    int price;
    bool operator < (const Menu& rhs) const {
        return (this->price < rhs.price);
    }
};

then just make a vector for this struct and sort it. 然后只需为此结构制作一个矢量并将其排序。

vector<Menu> menu;
// do something, insert data
sort(menu.begin(),menu.end());

Then output accordingly. 然后相应地输出。

for(int x = 0; x < menu.size(); x++){
    menuFile << menu[x].category << ":" << menu[x].description << ":" << menu[x].price << endl;
}  

I don't know what your container types are, so I'm going to assume std::string . 我不知道您的容器类型是什么,所以我假设std::string The simplest thing might be to just make a separate vector of tuple s: 最简单的事情可能是只制作一个tuple s的单独vector

using StrTuple = std::tuple<std::string*, std::string*, std::string*>;
std::vector<StrTuple> combined;
for (size_t i = 0; i < _category.size(); ++i) {
    combined.emplace_back(&_category[i], &_description[i], &_price[i]);
}

And then sort that one by category: 然后按类别对那个排序:

std::sort(std::begin(combined), std::end(combined),
          [](const StrTuple& lhs, const StruTuple& rhs) {
              return *std::get<0>(lhs) < *std::get<0>(rhs);
          });

And then just stream it in order: 然后按顺序流式传输它:

for (auto& t : combined) {
    menuFile << *std::get<0>(t) << ":" << *std::get<1>(t) << ":" << *std::get<2>(t) << std::endl;
}

The same could be achieved with a separate type instead, something like: 可以使用单独的类型来实现相同的目的,例如:

struct CombinedValues {
    std::string *category, *description, *price;
};

I do not think there is a much more efficient algorithm to do that. 我认为没有比这更有效的算法了。 You may think so because you do 4 loop with the same thing. 您可能会这样想,因为您对同一件事进行了4次循环。 But you are still doing O(n) efficiency. 但是您仍在执行O(n)效率。 Adding a sort operation like some proposition above would add a step running at O(n*log(n)) efficiency, which is way worse. 添加类似于上述命题的排序操作将增加以O(n * log(n))效率运行的步骤,这更糟。

You still need the 4 loops, so the only thing we can try to optimize is the testing, that is replacing the string compare() operation in each loop by something faster. 您仍然需要4个循环,因此我们唯一可以尝试优化的是测试,即以更快的速度替换每个循环中的字符串compare()操作。 Something possible would be to replace the string test by an integer test, meaning pre-computing a category number in a new vector (ie a value 0 if category=="Starter", 1 if "Main", etc and a value different from 0..3 if not any of the interesting category (if that is possible) 有可能将字符串测试替换为整数测试,这意味着预先计算新向量中的类别编号(即,如果category ==“ Starter”,则值为0;如果“ Main”,则为1;以此类推。 0..3,如果没有任何有趣的类别(如果可能)

That would mean an initial loop to compute this category, which can be made more efficient (using an average of 2 string comparison). 这将意味着将有一个初始循环来计算该类别,从而可以提高效率(使用2个字符串比较的平均值)。 Or even less using a hash map of the category string. 甚至更少使用类别字符串的哈希映射。

So in the loops, we just do an integer comparison instead of a string comparison for each element. 因此,在循环中,我们只对每个元素执行整数比较而不是字符串比较。 However, we add the time to compute the category number in the first loop. 但是,我们在第一个循环中添加了时间来计算类别编号。 It is not obvious at first glance which will be faster: 4 loops and 4*n string comparisons or 4 loops, 2*n string comparisons and 4*n integer comparisons. 乍看起来并不明显,它会更快:4个循环和4 * n个字符串比较或4个循环,2 * n个字符串比较和4 * n个整数比较。 That may be faster, if comparing strings are much more costly than comparing integers. 如果比较字符串比比较整数要昂贵得多,那可能会更快。

For this kind of stuff, only way to know is to measure actual execution time. 对于这类东西,唯一了解的方法是测量实际执行时间。 Obviously, all this is time consuming, so only to be done if this is really necessary (ie your profiler tells you that this part needs to be optimized) 显然,所有这些都是费时的,因此只有在确实有必要时才执行此操作(即您的探查器告诉您该部分需要优化)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM