我在按字符位置扫描MIT Meep控制文件到令牌方面取得了进展。我现在有一个nx3整数数组,其中3列标识:
除非他们处于“找到”顺序,而不是输入顺序。我注意到,字符位置可以变得非常大,很容易变成数千个(即数千行),而令牌标识符和令牌长度都低于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
答案 0 :(得分:1)
可能的做法是将您的行定义为结构{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;
}
这有帮助吗?
答案 1 :(得分:1)
您应该将每个条目包装在具有三个字段的结构中,并定义基于第一个字段的值的比较:
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]);
}
}
}
对于一般情况,这是一个不错的排序算法,它只是三行代码。
答案 2 :(得分:0)
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
答案 3 :(得分:0)
我花了一天时间试图建造一个结构。不幸的是,我的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;
}
所以这不是我想要的答案。