【问题标题】:Sort One Vector Based on the Elements of Another Vector With no Class or Struct根据另一个没有类或结构的向量的元素对一个向量进行排序
【发布时间】:2017-10-03 00:09:56
【问题描述】:
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;

const int max_applications_num = 1000;

vector<string> vector_authors;
vector<string> vector_titles;
vector<string> vector_venue;
vector<int> vector_year;
vector<string> vector_presentation;

void Tokenize(string line, vector<string> &tokens, string delimiters = "\t ") {
    string token = "";
    string OneCharString = " ";
    for (int i = 0; i < line.size(); i++)
        if (find(delimiters.begin(), delimiters.end(), line[i]) !=
            delimiters.end()) // line[i] is one of the delimiter characters
        {
            if (token != "")
                tokens.push_back(token);
            token = "";
        } else {
            OneCharString[0] = line[i];
            token += OneCharString;
        }

    if (token != "")
        tokens.push_back(token);
}

void SaveApplication(const vector<string> &tokens) {

    string authors = tokens[1];
    string title = tokens[2];
    string venue = tokens[3];
    int year = atoi(tokens[4].c_str());
    string presentation = tokens[5];

    vector_authors.push_back(authors);
    vector_titles.push_back(title);
    vector_venue.push_back(venue);
    vector_year.push_back(year);
    vector_presentation.push_back(presentation);

    // cout << "in save" << endl;
}

void remove_application(int pos) {

    vector_authors.erase(vector_authors.begin() + pos);
    vector_titles.erase(vector_titles.begin() + pos);
    vector_venue.erase(vector_venue.begin() + pos);
    vector_year.erase(vector_year.begin() + pos);
    vector_presentation.erase(vector_presentation.begin() + pos);

    // cout << "in remove" << endl;
}

void sort() {
    for (int j = 0; j <= vector_year.size() - 1; j++) {

        int temp1 = vector_year.at(j);
        int i = j - 1;
        while (i > -1 and vector_year.at(i) > temp1) {
            vector_year.at(i + 1) = vector_year.at(i);
            i = i - 1;
        }
        vector_year.at(i + 1) = temp1;
    }

    for (int j = 0; j <= vector_authors.size() - 1; j++) {
        string temp2 = vector_authors.at(j);
        int i = j - 1;
        while (i > -1 and vector_authors.at(i) > temp2) {
            vector_authors.at(i + 1) = vector_authors.at(i);
            i = i - 1;
        }
        vector_authors.at(i + 1) = temp2;
    }

    for (int j = 0; j <= vector_titles.size() - 1; j++) {
        string temp3 = vector_titles.at(j);
        int i = j - 1;
        while (i > -1 and vector_titles.at(i) > temp3) {
            vector_titles.at(i + 1) = vector_titles.at(i);
            i = i - 1;
        }
        vector_titles.at(i + 1) = temp3;
    }
    for (int j = 0; j <= vector_venue.size() - 1; j++) {
        string temp4 = vector_venue.at(j);
        int i = j - 1;
        while (i > -1 and vector_venue.at(i) > temp4) {
            vector_venue.at(i + 1) = vector_venue.at(i);
            i = i - 1;
        }
        vector_venue.at(i + 1) = temp4;
    }
    for (int j = 0; j <= vector_presentation.size() - 1; j++) {
        string temp5 = vector_presentation.at(j);
        int i = j - 1;
        while (i > -1 and vector_presentation.at(i) > temp5) {
            vector_presentation.at(i + 1) = vector_presentation.at(i);
            i = i - 1;
        }
        vector_presentation.at(i + 1) = temp5;
    }

    // cout << "in sort" << endl;
}

void print() {

    for (int i = 0; i < vector_authors.size(); i++) {
        cout << vector_authors.at(i) << "\t" << vector_titles.at(i) << "\t"
             << "\t" << vector_venue.at(i) << "\t" << vector_year.at(i) << "\t" << vector_presentation.at(i) << endl;
    }
    cout << "\n" << endl;
}

void ExecuteCommands(const char *fname) {
    ifstream inf;
    inf.open(fname);

    string line;
    while (getline(inf, line).good()) {
        vector<string> tokens;
        Tokenize(line, tokens, "\t ");
        if (tokens.size() == 0)
            continue;

        if (tokens[0].compare("save_application") == 0)
            SaveApplication(tokens);

        else if (tokens[0].compare("remove_application") == 0)
            remove_application(atoi(tokens[1].c_str()));

        else if (tokens[0].compare("sort") == 0)
            sort();

        else if (tokens[0].compare("print") == 0)
            print();
    }

    inf.close();
}

int main(int argc, char **argv) {
    if (argc != 2) {
        cout << "usage: executable.o command.txt\n";
        return 1;
    }

    ExecuteCommands(argv[1]);
    return 0;
}

所以,这是我在学校做的一个实验室的代码。我们应该将某些元素放入一个向量中,打印这些向量,对它们排序,再次打印它们,删除一个向量,最后一次打印它们。对于我们的排序,我们需要根据出版年份对它们进行排序。

"authors_list1" "title1" "conference1"  2016    "poster"
"authors_list3" "title3" "conference2"  2010    "oral"
"authors_list2" "title2" "journal1" 2015    "none"

所以,当我排序时,我得到了这个:

"authors_list1" "title1" "conference1"  2010    "none"
"authors_list2" "title2" "conference2"  2015    "oral"
"authors_list3" "title3" "journal1" 2016    "poster"

这是预期的输出:

"authors_list3" "title3"    "conference2"   2010    "oral"
"authors_list2" "title2"    "journal1"  2015    "none"
"authors_list1" "title1"    "conference1"   2016    "poster"

年份的顺序是正确的,但其他一切的顺序都不正确。我需要我的其他元素随着岁月的流逝而效仿。有什么办法吗?

附:对于本实验,我们不允许使用类或结构。这是我所有的代码。

【问题讨论】:

  • 与您的问题无关,但不是多个向量,您为什么不使用 结构 和单个向量来包含它?实际上可能会使排序更容易一些。
  • 我们不允许。实验室没有指定结构或类。
  • 根据你对遵守法律条文和精神的感觉有多接近,你可以使用元组。
  • 编辑您的问题以包含预期(以及实际)输出。或其他重要或相关的详细信息。
  • @J.Khelly Please read this answer。您的数据属于“笨拙”类别。您所需要的只是一个索引数组。不需要结构或类。

标签: c++ sorting vector


【解决方案1】:

你可以用

伪造一个非笨拙的数据结构
vector<vector<string> > database;

其中vector&lt;string&gt; 是一条记录。为了让它“易于管理”,我会使用一些别名、访问器函数和这个枚举:

enum { AUTHOR, TITLE, VENUE, YEAR, PRESENTATION };

代码变短了很多:

Live On Coliru

#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;

const int max_applications_num = 1000;

enum { AUTHOR, TITLE, VENUE, YEAR, PRESENTATION };

vector<vector<string> > database;

void Tokenize(string line, vector<string> &tokens, string delimiters = "\t ") {
    string token = "";
    string OneCharString = " ";
    for (size_t i = 0; i < line.size(); i++)
        if (find(delimiters.begin(), delimiters.end(), line[i]) !=
            delimiters.end()) // line[i] is one of the delimiter characters
        {
            if (token != "")
                tokens.push_back(token);
            token = "";
        } else {
            OneCharString[0] = line[i];
            token += OneCharString;
        }

    if (token != "")
        tokens.push_back(token);
}

void SaveApplication(const vector<string> &tokens) {
    database.emplace_back(tokens.begin()+1, tokens.end());
}

void remove_application(size_t pos) {
    assert(pos < database.size());
    database.erase(database.begin()+pos);
}

int year_of(vector<string> const &record) { return stoi(record[YEAR]); }
int year_of(int i) { return year_of(database.at(i)); }

void sort() {
    for (size_t j = 0; j <= database.size() - 1; j++) {

        vector<string> tmp = database.at(j);

        int tmp_year = year_of(tmp);

        int i = j - 1;
        while (i > -1 and year_of(i) > tmp_year) {
            database.at(i + 1) = database.at(i);
            i = i - 1;
        }

        database.at(i + 1) = tmp;
    }
}

void print() {
    for (size_t i = 0; i < database.size(); i++) {
        cout 
            << database.at(i)[AUTHOR] << "\t"
            << database.at(i)[TITLE]  << "\t"
            << database.at(i)[VENUE]  << "\t"
            << database.at(i)[YEAR]   << "\t"
            << database.at(i)[PRESENTATION] 
            << endl;
    }
    cout << "\n" << endl;
}

void ExecuteCommands(const char *fname) {
    ifstream inf;
    inf.open(fname);

    string line;
    while (getline(inf, line).good()) {
        vector<string> tokens;
        Tokenize(line, tokens, "\t ");
        if (tokens.size() == 0)
            continue;

        if (tokens[0].compare("save_application") == 0)
            SaveApplication(tokens);

        else if (tokens[0].compare("remove_application") == 0)
            remove_application(atoi(tokens[1].c_str()));

        else if (tokens[0].compare("sort") == 0)
            sort();

        else if (tokens[0].compare("print") == 0)
            print();
    }

    inf.close();
}

int main(int argc, char **argv) {
    if (argc != 2) {
        cout << "usage: executable.o command.txt\n";
        return 1;
    }

    ExecuteCommands(argv[1]);
}

对于输入

save_application "authors_list1"    "title1" "conference1"  2016    "poster"
save_application "authors_list3"    "title3" "conference2"  2010    "oral"
save_application "authors_list2"    "title2" "journal1" 2015    "none"
print
sort
print
remove_application 0
print

打印

"authors_list1" "title1"    "conference1"   2016    "poster"
"authors_list3" "title3"    "conference2"   2010    "oral"
"authors_list2" "title2"    "journal1"  2015    "none"


"authors_list3" "title3"    "conference2"   2010    "oral"
"authors_list2" "title2"    "journal1"  2015    "none"
"authors_list1" "title1"    "conference1"   2016    "poster"


"authors_list2" "title2"    "journal1"  2015    "none"
"authors_list1" "title1"    "conference1"   2016    "poster"

【讨论】:

  • 为什么是vectorvector 而不是vectortupletuple 是固定大小(按模板类型)和异构的;它旨在代表这样的单个“记录”;用vector+enums 来做这件事(它不能为一个字段存储int,为另一个字段存储string,并且不能使用std::tie 之类的东西来进行简单的解包)似乎很自虐,除非你'由于某种原因,完全无法使用 C++11 或更高版本。
  • @ShadowRanger 矢量已在使用中。所以它有隐含的绿灯。如果您要使用元组,只需在此处使用结构。我只是在展示如何在不越界的情况下挑战教授施加的愚蠢限制。
  • 结构样本(也改进了标记化以尊重报价):live on Coliru /cc @ShadowRanger
  • 你编译错了。在线编译器的美妙之处在于您可以准确地看到如何编译/使用它(在这种情况下,c++11 was enough 和两个微小的调整使其成为 c++03 compatible
  • 对于我们的类,我们通常这样编译:“g++ -o file.o file.cpp”。为了运行它,我们这样做:“./file.o input.txt”。你也是这样编译的吗?
【解决方案2】:

为什么不使用并行向量,当您订购年份向量时,如果您将位置 i 与位置 j 交换,则在每个向量上执行此操作。

【讨论】:

  • 这不是一个好的解决方案。如果你有 100 个向量,你需要为一个元素编写 100 个交换。
  • @PaulMcKenzie - 这可以使用数组或指向向量的指针向量来处理。在某些时候,代码将不得不处理所有的向量。我想知道是否使用一组索引来帮助进行排序似乎会为这项任务提供太多帮助。
  • @rcgldr 我想知道是否使用索引数组来帮助进行排序似乎有太多帮助 - 我也想知道同样的事情。不想在这里写出答案——但是“答案”在这里或多或少已经在公共领域,就像许多其他家庭作业的答案一样。我希望 OP 不只是逐字复制。
  • sehe 的回答基本上就是我的建议,使用向量向量与我建议的向量指针向量。即便如此,这似乎也超出了本实验室的预期。
  • 不,实际上我们被告知我们可以使用向量的向量。只要我们没有任何类或结构,我们如何编写程序并不重要。
猜你喜欢
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 2010-12-06
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 2022-12-18
相关资源
最近更新 更多