【问题标题】:Problems with making vector function from the existing code C++从现有代码 C++ 制作向量函数的问题
【发布时间】:2019-11-05 10:20:57
【问题描述】:

我的程序有两个名字和年龄向量。它对名称向量进行排序,并以正确的顺序保持年龄向量以匹配排序后的名称向量。现在,我想从现有代码中创建一个函数,但我遇到了一些问题。

现有代码:

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

using namespace std;

int main() {
    vector<string> names      {"One", "Two", "Three", "Four", "Five"};
    vector<unsigned int> ages {    1,     2,       3,      4,      5};
    const vector<string> namesCopy = names;

    sort(begin(names), end(names));

    decltype(ages) sortedAges(ages.size());

    for(int i = 0; i < namesCopy.size(); ++i) {
        const auto iter = lower_bound(begin(names), end(names), namesCopy[i]);

        const auto pos = iter - begin(names);

        sortedAges[pos] = ages[i];
    }

    for(int i = 0 ; i < names.size() ; ++i)
        cout << setw(10) << names[i] << setw(4) << sortedAges[i] << '\n' ;
}

Output

功能:

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

using namespace std;

int test(vector<string> testNames, vector<string> testNamesCopy, vector<unsigned int> testAges, vector<unsigned int> testSortedAges) {
    for(int i = 0; i < testNamesCopy.size(); ++i) {
        const auto iter = lower_bound(begin(testNames), end(testNames), testNamesCopy[i]);

        const auto pos = iter - begin(testNames);
        return testSortedAges[pos] = testAges[i];
    }
}

int main() {
    vector<string> names      {"One", "Two", "Three", "Four", "Five"};
    vector<unsigned int> ages {    1,     2,       3,      4,      5};
    const auto namesCopy = names;

    sort(begin(names), end(names));

    decltype(ages) sortedAges(ages.size());

    for(int i = 0 ; i < names.size() ; ++i)
        cout << setw(10) << names[i] << setw(4) << test(names, namesCopy, ages, sortedAges) << '\n' ;
}

Output 2

【问题讨论】:

  • 您的两个输出图像是同一个文件。其次,函数中的 for 循环将在第一次迭代后结束,因为函数在该点返回。所以让我在这里澄清一下:return ends 函数一旦发生。它不会积累任何东西或类似的东西。
  • 除此之外,您的算法对我来说似乎很乏味。如果要将两个向量归为一个,请从类型中创建一个结构,例如 struct Entry { string name; unsigned int age; }; 和函数 bool lesser(const Entry&amp; a, const Entry&amp; b) { return a.age &lt; b.age; },然后对于 vector&lt;Entry&gt; entries,调用 std::sort(entries.begin(), entries.end(), lesser),另请参阅 stackoverflow.com/questions/1380463/…

标签: c++ function vector


【解决方案1】:

我认为您以错误的方式处理此问题。有 2 个您排序但必须保持相同顺序的向量很容易出错。相反,您应该使用一对向量。

std::vector&lt;std::pair&lt;std::string, int&gt;&gt; idendityVec;

然后您可以通过执行按名称(对的第一个元素)进行排序

std::sort(idendityVec.begin(), idendityVec.end());

如果要按年龄排序,可以声明自己的比较函数并在排序中使用: bool lesserAge(const pair<std::string,int> &a, const pair<std::string,int> &b) { return (a.second < b.second); } std::sort(idendityVec.begin(), idendityVec.end(), lesserAge); 这给了你这样的东西:

#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>

bool lesserAge(const std::pair<std::string, int> &a,
               const std::pair<std::string, int> &b)
{
  return (a.second < b.second);
}
int main()
{
  std::vector<std::pair<std::string, int>> idendityVec = {std::make_pair("three", 3), std::make_pair("four", 4), std::make_pair("two", 2), std::make_pair("one", 1)};

  for (auto v : idendityVec)
  {
    std::cout << "Name=" << v.first << ", age=" << v.second << std::endl;
  }
  // Sort by age i.e. second element
  std::sort(idendityVec.begin(), idendityVec.end(), lesserAge);
  for (auto v : idendityVec)
  {
    std::cout << "Name=" << v.first << ", age=" << v.second << std::endl;
  }
  //Sort by name i.e first element
  std::sort(idendityVec.begin(), idendityVec.end());
  for (auto v : idendityVec)
  {
    std::cout << "Name=" << v.first << ", age=" << v.second << std::endl;
  }
}

【讨论】:

    【解决方案2】:
    vector<string> names      {"One", "Two", "Three", "Four", "Five"};
    vector<unsigned int> ages {    1,     2,       3,      4,      5};
    

    namesages 似乎以这样的方式联系在一起,最好将它们组合在一个班级中。我们可以使用简单的struct,默认情况下,您可以直接访问其成员,就像您可以访问当前解决方案中的所有姓名和年龄一样。你可以从这个开始:

    struct person { // ... or animal, or thing. Give it a meaningful name.
        std::string name{};
        unsigned age{};
    };
    

    现在您可以创建一个std::vector&lt;person&gt; 而不是两个不相连的向量,这使得数据的排序和一般处理有点麻烦。

    通过以上方式,排序和打印等变得更加直接。我在示例中使用lambdas 创建了排序函数:

    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <tuple> // std::tie
    #include <iomanip>
    
    struct person {
        std::string name{};
        unsigned age{};
    };
    
    // print one "person"
    std::ostream& operator<<(std::ostream& os, const person& p) {
        return os << std::setw(10) << p.name << std::setw(4) << p.age;
    }
    
    int main() {
        // one vector with all the persons
        std::vector<person> persons{
            {"One", 1},
            {"Two", 2},
            {"Three", 3},
            {"Four", 4},
            {"Five", 5}
        };
    
        // sort on name first, age second (if names are equal) - ascending order
        std::sort(persons.begin(), persons.end(), [](const person& a, const person& b) {
            return std::tie(a.name, a.age) < std::tie(b.name, b.age);
        });
        // print the current order:
        for(const auto& p : persons) std::cout << p << "\n";
    
        std::cout << "--\n";
    
        // sort on age first, name second (if ages are equal) - ascending order
        std::sort(persons.begin(), persons.end(), [](const person& a, const person& b) {
            return std::tie(a.age, a.name) < std::tie(b.age, b.name);
        });
        // print the current order:
        for(const auto& p : persons) std::cout << p << "\n";
    }
    

    【讨论】:

      猜你喜欢
      • 2019-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-09
      • 1970-01-01
      • 1970-01-01
      • 2015-05-20
      • 1970-01-01
      相关资源
      最近更新 更多