gpt4 book ai didi

c++ - 访问算法的 lambda 函数中的迭代器导致我出现段错误

转载 作者:行者123 更新时间:2023-12-02 09:55:33 29 4
gpt4 key购买 nike

我需要按列对表格进行排序。我的表由单个 vector 表示。

例子 :

col_name A B C

vector :1 2 3 6 5 4 7 8 9

这给了我 table :

A B C

1 6 7
2 5 8
3 4 9

在对 B 列进行排序后,我需要获得:
A B C

3 4 9
2 5 8
1 6 7

我的代码:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

int main()
{

std::vector<std::string> vec = {"1","8","1","2","3","2","3",
"5","5","2","5","6","5","6",
"9","3","3","4","8","3","9"};

std::vector<std::string> rec = {"1","1","8","2","2","3","3",
"2","5","5","5","5","6","6",
"3","9","3","4","3","8","9"};

int size = 7;
int col_idx = 1;


for(int i = 0; i<3;++i)
{
if(i==col_idx)
continue;

std::sort(vec.begin() + i*size, vec.begin() + (i+1)*size,
[col_idx, size, i](std::string& s1,std::string& s2)
{
std::cout << s1 << " "
<< s2 << " "
<< *(&s1 +(col_idx - i)*size) << " "
<< *(&s2 +(col_idx - i)*size) << " "
<< (*(&s1 +(col_idx - i)*size) < *(&s2 +(col_idx - i)*size)) << std::endl;
return *(&s1 +(col_idx - i)*size) < *(&s2 +(col_idx - i)*size);
});
}
std::sort(vec.begin() + col_idx*size, vec.begin() + (col_idx+1)*size);
}

assert(vec==res);

我有一个段错误错误:只有第一行出现在 cout 中。

最佳答案

老实说,你的方法在我看来相当复杂。它的大部分复杂性是由于您的代码中有行但它们仅隐式存在。在代码中明确内容不仅有助于提高可读性,而且使代码更容易编写。

假设您使用 std::array<std::string,3>对于行,那么您的代码可以像这样轻量级:

#include <vector>
#include <array>
#include <algorithm>
#include <iostream>

int main() {
using row_t = std::array<std::string,3>;
std::vector<row_t> vec = { {"1","8","1"},{"2","3","2"},{"3","5","5"},{"2","5","6"}};

std::sort(vec.begin(),vec.end(),[](const row_t& a, const row_t& b) { return a[2] < b[2]; });

for (const auto& row : vec) {
for (const auto& e : row) std::cout << e << " ";
std::cout << '\n';
}
}

输出:
1 8 1 
2 3 2
3 5 5
2 5 6

Ok, that's probably a good approch for this problem, and maybe it's what should I do, but I can't pass 2 months to change all the code ...



您可以在问题中更清楚地说明要求。我认为,如果您有 10k 行代码依赖于使用平面 vector 的这个特定问题,那么当不同的数据结构更合适时,那么您将面临比如何对行进行排序更大的问题。无论如何...

使用平板 std::vector通常不是一个坏主意。我从您的代码中错过的是
template <int stride>
std::string& access_at(std::vector<std::string>& vec,size_t row,size_t col) {
return vec[ row * stride + col ];
}
template <int stride>
const std::string& access_at(const std::vector<std::string>& vec,size_t row,size_t col) {
return vec[ row * stride + col ];
}

这使您可以像这样迭代表:
for (size_t i=0;i < vec.size()/3;++i) {
for (size_t j=0;j<3;++j) {
std::cout << access_at<3>(vec,i,j) << " ";
}
std::cout << '\n';
}

接下来我要厚颜无耻地盗取和修改 this answer的代码.基本思想是对索引 vector 进行排序,而不是直接对 vector 进行排序:
using index_t = std::vector<size_t>;
template <int stride>
index_t make_sorted_index(const std::vector<std::string>& values,size_t col) {
index_t index(values.size() / stride);
std::iota(index.begin(), index.end(), 0);
std::sort(index.begin(),
index.end(),
[&values,&col](size_t a, size_t b) {
return access_at<stride>(values,a,col) < access_at<stride>(values,b,col);
}
);
return index;
}

一旦你有了它,打印排序表的循环只需要一个小的修改:
for (size_t i=0;i < vec.size()/3;++i) {
for (size_t j=0;j<3;++j) {
std::cout << access_at<3>(vec,index[i],j) << " ";
}
std::cout << '\n';
}

把所有东西放在一起:
#include <vector>
#include <numeric>
#include <algorithm>
#include <iostream>

template <int stride>
std::string& access_at(std::vector<std::string>& vec,size_t row,size_t col) { return vec[ row * stride + col ]; }
template <int stride>
const std::string& access_at(const std::vector<std::string>& vec,size_t row,size_t col) { return vec[ row * stride + col ]; }

using index_t = std::vector<size_t>;
template <int stride>
index_t make_sorted_index(const std::vector<std::string>& values,size_t col) {
index_t index(values.size() / stride);
std::iota(index.begin(), index.end(), 0);
std::sort(index.begin(),
index.end(),
[&values,&col](size_t a, size_t b) { return access_at<stride>(values,a,col) < access_at<stride>(values,b,col); }
);
return index;
}


int main() {
std::vector<std::string> vec = { "1","8","1","2","3","2","3","5","5","2","5","6"};
for (size_t i=0;i < vec.size()/3;++i) {
for (size_t j=0;j<3;++j) {
std::cout << access_at<3>(vec,i,j) << " ";
}
std::cout << '\n';
}
std::cout << '\n';
auto index = make_sorted_index<3>(vec,1);
for (size_t i=0;i < vec.size()/3;++i) {
for (size_t j=0;j<3;++j) {
std::cout << access_at<3>(vec,index[i],j) << " ";
}
std::cout << '\n';
}
}

带输出:
1 8 1 
2 3 2
3 5 5
2 5 6

2 3 2
3 5 5
2 5 6
1 8 1

如果您真的需要,我将留给您实际复制 vector 以获得排序的 vector 。

PS :在上面的第一个版本中,我对列 C 进行了排序,最后一部分根据要求对 B 进行了排序。

PPS : 我还是不明白你的代码。我不明白你为什么有 std::cout在谓词中,老实说,我不知道您如何调用 sort应该达到你想要的。

关于c++ - 访问算法的 lambda 函数中的迭代器导致我出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60453780/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com