将2维字符串数组与std :: sort进行比较

时间:2015-11-05 14:47:58

标签: c++ c++11

我有一个字符串数组,其中包含我要排序的数字(我只想对[i] [0]进行排序):

string test[4][2];
test[0][0] = "3";
test[0][1] = "4";

test[1][0] = "1";
test[1][1] = "2";

test[2][0] = "6";
test[2][1] = "8";

test[3][0] = "5";
test[3][1] = "4";

std::sort(std::begin(test), std::end(test), NumericGreaterThan);

bool NumericGreaterThan(const string u[], const string v[])
{
    // more code ..
    return true;
}

结果应该是:

1 - 2
3 - 4
5 - 4
6 - 8

编译器说: [Error] invalid array assignment

更新

上面的例子只是一个测试案例。实际上,我的第2个数组维度比示例中的要宽。例如:

string test[4][2];
test[0][0] = "3";
test[0][1] = "Name";
test[0][2] = "Name";
test[0][3] = "5";

根据@ coincoin的解决方案我做了类似的事情:

// create tmp array with index and sorting value
int testsCount = sizeof(test) / sizeof(test[0]);    
vector< pair<string, string> > tmpTest;
for (int i = 0; i < testsCount; i++) {
    pair<string, string> aPair;
    aPair.first = std::to_string(i);
    aPair.second = test[i][3];  
    tmpTest.push_back(aPair);
}

// sort 
std::sort(std::begin(tmpTest), std::end(tmpTest), compare);

bool compare(const pair<string, string>&i, const pair<string, string>&j)
{
    return std::stoi(i.second)>std::stoi(j.second);
}

现在我有一个test的复制和排序向量,我可以使用它来遍历原始测试数组。

for (int i = 0; i < testsCount; i++) {
    cout << i+1 << ". " << test[std::stoi(tmpTest[i].first)][0] << endl;
}

我知道这不是实现这一目标的最佳方式,但它符合我的需求。

4 个答案:

答案 0 :(得分:2)

我认为你不必要地复杂化了事情(还有一些答案......)

您应该修改代码设计。

你可以简单地使用一对数组,你可以重复使用你想要的内置bool operator< (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs) ...

#include <array>
#include <algorithm>

int main() {
    std::array<std::pair<int,int>, 4> test { std::make_pair(3,4), std::make_pair(1,2), std::make_pair(6,8), std::make_pair(5,4) };
    std::sort(std::begin(test), std::end(test));
}

Live code

输出

  

(1,2)(3,4)(5,4)(6,8)

全部......

答案 1 :(得分:0)

为了对数组数组进行排序,您必须将数组分配给另一个不可能的数组。你应该使用一对数组并比较对。

答案 2 :(得分:0)

首选std::array<>通过C阵列:

auto test = std::array<std::array<std::string, 2>, 4>{{"3"s, "4"s},
                                                      {"1"s, "2"s},
                                                      {"6"s, "8"s},
                                                      {"5"s, "4"s}};

std::sort(std::begin(test), std::end(test), NumericGreaterThan);

auto NumericGreaterThan(const std::array<std::string, 2>& u, const std::array<std::string, 2>& v)
-> bool
{
    // more code ..
    return true;
}

这是未经测试的代码!

要知道,在介绍C ++习语之前,许多教科书首先教你C风格。我认为,那些做错了。

同时考虑使用Lambdas,如果这是您使用NumericGreaterThan的唯一地方:

auto test = std::array<std::array<std::string, 2>, 4>{{"3"s, "4"s},
                                                      {"1"s, "2"s},
                                                      {"6"s, "8"s},
                                                      {"5"s, "4"s}};

std::sort(std::begin(test), std::end(test),
          [](const std::array<std::string, 2>& u, const std::array<std::string, 2>& v)
          -> bool {
              // more code ..
              return true;
          });

如果您已经使用了C ++ 14,那么您可以使用通用lambdas,这使得代码更简单一点:

auto test = std::array<std::array<std::string, 2>, 4>{{"3"s, "4"s},
                                                      {"1"s, "2"s},
                                                      {"6"s, "8"s},
                                                      {"5"s, "4"s}};

std::sort(std::begin(test), std::end(test),
          [](const auto& u, const auto& v) -> bool {
              // more code ..
              return true;
          });

还请考虑在排序之前将字符串数组转换为数字。这减少了array<string> - >的数量。 int次转化非常明显:

int convertToNumber(std::array<std::string, 2>);
auto test =
    std::array<std::pair<std::array<std::string, 2>, int> 4>{{{"3"s, "4"s}, 0},
                                                             {{"1"s, "2"s}, 0},
                                                             {{"6"s, "8"s}, 0},
                                                             {{"5"s, "4"s}, 0}};

for(auto& i: test) i.second = convertToNumber(i.first);

std::sort(std::begin(test), std::end(test),
          [](const auto& u, const auto& v) -> bool {
              return u.second > v.second;
          });

答案 3 :(得分:0)

您可以将字符串的每个部分分成不同的类,然后只在sort函数中寻址最低的子类。这有点令人费解,但回答了你的问题。

请注意:此方法仅允许迭代最低的子类。我不建议将此方法用于实际应用,因为它不可扩展,并且随着您增加应用程序的维度结构而变得越来越复杂。对于每个新的维度,您将需要一个新的类(随着您的&#34;阵列变得越来越n维&#34;这变得越来越乏味)。

            #include <iostream>
            #include <string>
            #include <vector>

            using namespace std;

            class string_container_length {
            public:

                string_container_length(int &length)
                {
                    level2.resize(length);
                }

                // Level to iterated [i][0] where i is important.
                std::vector<std::string> level2;
            };

            class string_container {
            public:
                string_container(int &length, int &width)
                {
                    level1.reserve(width);

                    for (int i = 0; i < width; ++i)
                    {
                        // Creates a new string_container_length using constructor with a set length.
                        level1.push_back(string_container_length(length));
                    }
                }

                std::vector<string_container_length> level1;
            };



            int main(){

                // Will not be iterated in example.
                int length = 2;

                // Will be iterated in example
                int width = 4;

                string_container test(length,width);

                test.level1[0].level2[0] = 7;
                test.level1[0].level2[1] = 4;
                test.level1[0].level2[2] = 3;
                test.level1[0].level2[3] = 8;

                // Passes beginning and end positions to the child class.
                std::sort(std::begin(test.level1[0].level2), std::end(test.level1[0].level2));

            }

推荐:根据您的需要在另一个命名空间下编写您自己的自定义排序功能。这可以使用简单的循环,几个if语句和您现有的NumericGreaterThan()函数来完成。可以找到一个示例以及有关排序函数如何工作的教程here.