请求想法 - 如何对具有多行和 3 列的 2d 数组进行排序,维护数据行
Request ideas- How to sort a 2d array with many rows and 3 columns, maintaining data rows
我在按字符位置将 MIT Meep 控制文件扫描为令牌方面取得了进展。我现在有一个 nx3 整数数组,其中 3 列标识:
- 角色位置
- 令牌标识符
- 令牌长度
除了它们按"找到"顺序,而不是按输入顺序排列。我注意到字符位置可能会变得非常大,很容易进入数千行的 10(即数千行),而令牌标识符和令牌长度都低于 100。
我需要按字符位置按递增顺序对 nx3 数组进行排序,而不会丢失其他两列。我已经研究了一下,答案似乎是编写一些实现气泡排序或其他类似算法的代码。
是否有C++函数可以对数组第一列中的条目进行排序而不会丢失关联的行条目?我的一点测试控制文件导致生成一个看起来像这样的数组:
380 2 1
401 2 1
441 2 1
442 2 1
178 4 13
178 18 7
0 26 5
59 26 5
218 26 5
330 26 5
382 26 5
23 32 5
80 32 5
142 32 5
238 32 5
256 32 5
353 32 5
74 38 5
232 38 5
347 38 5
403 44 4
一种可能性是将行定义为结构体{a,b,c},比较"a"字段,然后使用编译器的结构赋值功能交换结构(实际上是交换行)。
typedef struct ROW {
int a, b, c;
};
struct ROW A, B;
...
if (A.a > B.a) {
struct ROW tmp = A; A = B; B = tmp;
}
这有帮助吗?
每个条目包装在具有三个字段的结构中,并定义基于第一个字段值的比较:
struct Entry {
int loc, ident, length;
Entry(int loc, int ident, int length)
: loc(loc), ident(ident), length(length)
{}
bool operator<(const Entry& other) const {
return loc < other.loc;
}
};
之后,您只需使用标准sort
功能
std::vector<Entry> data;
// ... fill the vector ...
std::sort(data.begin(), data.end());
相反,如果数组已经给出int data[][3]
因为事情更烦人,我可能会手动内联 shell-metzener 排序:
for (int m=n>>1; m>0; m>>=1) {
for (int j=0; j<n-m; j++) {
for (int i=j; i>=0 && data[i][0]>data[i+m][0]; i-=m) {
std::swap(data[i][0], data[i+m][0]);
std::swap(data[i][1], data[i+m][1]);
std::swap(data[i][2], data[i+m][2]);
}
}
}
对于一般情况来说,这是一个不错的排序算法,它只有三行代码。
typedef struct row_head
{
int char_loc;
int token_index;
};
vector<row_head> heads;
vector<int> token_id;
vector<int> token_length;
用于排序的变量头,将使用相应的索引来访问数据。例如,在上面的数据集中,前 5 个元素被认为是简单的。排序前:
{380,0} 5 1
{401,1} 8 1
{441,2} 9 1
{442 ,3} 10 2
{178 ,4} 4 1
在头部对数据进行排序后,如下所示:
{178,4}
{380,0}
{401,1}
{441,2}
{442,3}
实际令牌数据保持不变:
5 1
8 1
9 1
10 2
4 1
我花了一天时间试图建立一个结构。不幸的是,我的c ++知识 - 经验无法胜任这项任务。我无法编译任何东西。所以我走老的Fortran方式,让这段代码工作并完成我需要的东西。
代码膨胀?最有可能来自标题。运行时间?遍历整个长数据流两次以上。哦,好吧,它有效,但如果我可以使结构工作,我会改变它,或者至少做一个基准测试。
#include <algorithm> // std::sort
#include <sstream> // std::istringstream
#include <vector>
#include <iostream> // std::cout
#include <string>
#include <stdio.h> // sprintf
using namespace std;
int main() {
std::vector<std::string> data(512);
int length = 8;
size_t arat[length];
int arid[length];
int arlen[length];
int n ;
int i ;
char buffer [17];
arat[0]= 0 ; arid[0] = 1; arlen[0] = 1;
arat[1]= 418 ; arid[1] = 1; arlen[1] = 1;
arat[2]= 57 ; arid[2] = 2; arlen[2] = 1;
arat[3]= 442 ; arid[3] = 2; arlen[3] = 91;
arat[4]= 178 ; arid[4] = 1; arlen[4] = 1;
arat[5]= 178632 ; arid[5] =180; arlen[5] = 226;
arat[6]= 0 ; arid[6] =26; arlen[6] = 5;
arat[7]= 59 ; arid[7] =26; arlen[7] = 5;
cout << 'n';
i = 0;
while(i<length){
n=sprintf (buffer," %*lu %*d %*d", 6,arat[i], 3,arid[i], 3,arlen[i]);
if(n < 0) break;
cout << buffer ; data[i] = buffer; cout << data[i] <<'n'; i++;}
cout << 'n';
std::sort (data.begin(), data.begin()+8); // sort data 0 thru 7, not 8.
i = 0;
while (i < length) {cout << data[i] << 'n';i++;}
cout << 'n';
i = 0;
while (i < length) {
std::istringstream iss (data[i]);
iss >> arat[i] ; // pick off the first number
iss >> arid[i] ; // pick off the next number
iss >> arlen[i] ; // pick off the next number after that.
cout << " size_t value of arat[i] = "<< arat[i] << " int arid[i] = "<<arid[i]
<< " int arlen[i] "<< arlen[i]<<'n';
i++; }
cout << 'n';
return 0;
}
所以这不是我真正想要的答案。
- 2D数组来自文本输入,中间有空格
- 如何使用用户输入在C++中正确填充2D数组
- 如何在C++中检查2D数组中负值的输入验证
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- 如何将以逗号和空格分隔的整数读取到 2D 数组中?
- 如何在C++函数中声明静态 2D 数组?
- 如何声明一个可以在整个程序中使用的全局 2d 3d 4d .. 数组(堆版本)变量?
- 我已经阅读了很多关于 2d 数组的信息,但我在作业中使用它时遇到了麻烦
- 使用矢量将文本文件中的输入存储到 2D 数组中
- 获取 2D 数组 c++ 中的所有数字对
- 这是使用回溯的 nqueen 问题,但我使用了动态 2d 数组,我的程序编译良好,但不返回任何输出
- 如何在构造函数中使用初始值设定项设置具有相同值的 2d 数组?
- 在 Python 和 c++ 2d 数组初始化之间.这是怎麽?为什么呢?
- 如何打印 2D 字符数组C++
- 如何将数组 2d 作为参数从函数传递并返回数组 2d 此函数
- 数组 2D 多个值
- 创建数组数组 (2D),而无需在 Java 中初始化内部数组
- 如何在C++中将文本文件传输到数组2D
- 从同一类的另一个方法调用数组2D-C++
- 获取地址在数组2d中的位置