我有2个向量:元素向量和计数向量。在对Element向量进行排序时,我需要对与Element向量值对应的计数向量进行排序。我需要将Element向量附加到全局向量(Proc)及其相应的Proc_count向量,该向量逐渐增大,并重复上述排序过程。
但是,在将元素附加到Proc和Proc_count向量的末尾后,第二个排序步骤失败。我知道重新调整向量大小会使迭代器失效,但即使使用了std :: reserve,我也注意到了相同的结果。
typedef uint64_t data_t;
struct MyComparator
{
const std::vector<data_t> & value_vector;
MyComparator(const std::vector<data_t> & val_vec):
value_vector(val_vec) {}
bool operator()(int i1, int i2)
{
return value_vector[i1] < value_vector[i2];
}
};
void SortAndAggregate(std::vector<data_t>& arr, std::vector<int>& count, std::vector<int>& add)
{
sort(count.begin(), count.end(), MyComparator(arr));
sort(arr.begin(), arr.end());
printf("Sorted arr: \n");
for (std::vector<data_t>::iterator it = arr.begin() ; it != arr.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
printf("Sorted count: \n");
for (std::vector<int>::iterator it = count.begin() ; it != count.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
int aggr=0;
for(int i = 0; i < (int)(arr.size()); i++)
{
aggr = count[i];
if (arr[i] == arr[i+1]) {
do {
aggr += count[i+1];
i++;
} while(i<(int)arr.size() && (arr[i] == arr[i+1]));
}
add.push_back(aggr);
}
arr.erase( unique( arr.begin(), arr.end() ), arr.end() );
assert(arr.size() == add.size());
printf("Sorted add: \n");
for (std::vector<int>::iterator it = add.begin() ; it != add.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
std::cout << '\n';
}
int main(int argc, char *argv[])
{
int N=20;
srand(time(0));
data_t mydata[] = {14,32,71,12,45,26,80,53,33, 9};
int mycnt[] = {1, 2, 3, 4, 5, 6, 7, 8, 9,10};
std::vector<data_t> dummy_data (mydata, mydata+10);
std::vector<int> dummy_cnt (mycnt, mycnt+10);
std::vector<data_t> arr1;
std::vector<int> cnt;
std::vector<int> arr3;
std::vector<data_t> proc_buf;
std::vector<int> proc_buf_cnt;
proc_buf.reserve(20);
proc_buf_cnt.reserve(20);
proc_buf.insert(proc_buf.end(), dummy_data.begin(), dummy_data.end());
proc_buf_cnt.insert(proc_buf_cnt.end(), dummy_cnt.begin(), dummy_cnt.end());
SortAndAggregate (proc_buf, proc_buf_cnt, arr3);
proc_buf_cnt = arr3;
arr3.clear();
printf("Proc buffer before: \n");
for (std::vector<data_t>::iterator it = proc_buf.begin() ; it != proc_buf.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
printf("Proc Count buffer before: \n");
for (std::vector<int>::iterator it = proc_buf_cnt.begin() ; it != proc_buf_cnt.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
std::cout << '\n';
for (int i = 0; i < N; ++i)
{
arr1.push_back(rand() % 10);
cnt.push_back(i);
}
printf("Original array: \n");
for (int it = 0 ; it < (int)arr1.size(); ++it)
std::cout << ' ' << arr1[it];
std::cout << '\n';
printf("Original counts: \n");
for (int it = 0; it < (int)cnt.size(); ++it)
std::cout << ' ' << cnt[it];
std::cout << '\n';
std::cout << '\n';
SortAndAggregate (arr1, cnt, arr3);
proc_buf.insert(proc_buf.end(), arr1.begin(), arr1.end());
proc_buf_cnt.insert(proc_buf_cnt.end(), arr3.begin(), arr3.end());
arr3.clear();
printf("Proc buffer before: size: %d \n", (int)proc_buf.size());
for (std::vector<data_t>::iterator it = proc_buf.begin() ; it != proc_buf.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
printf("Proc Count buffer before: size: %d \n", (int)proc_buf_cnt.size());
for (std::vector<int>::iterator it = proc_buf_cnt.begin() ; it != proc_buf_cnt.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
std::cout << '\n';
SortAndAggregate (proc_buf, proc_buf_cnt, arr3);
proc_buf_cnt = arr3;
assert(proc_buf.size() == proc_buf_cnt.size());
arr1.clear();
cnt.clear();
arr3.clear();
proc_buf.clear();
proc_buf_cnt.clear();
return 0;
}
输出:
Proc buffer before:
9 12 14 26 32 33 45 53 71 80
Proc Count buffer before:
10 9 3 5 1 8 4 7 2 6
Original Element array:
4 6 6 1 7 1 0 7 3 7 8 7 5 0 9 5 6 5 1 3
original Element counts:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Sorted arr:
0 0 1 1 1 3 3 4 5 5 5 6 6 6 7 7 7 7 8 9
Sorted count:
6 13 3 18 5 19 8 0 17 15 12 1 16 2 11 9 7 4 10 14 // CORRECT sorted order
Sorted aggregate:
19 26 27 0 44 19 31 10 14
Appended Proc buffer (size: 19)
9 12 14 26 32 33 45 53 71 80 0 1 3 4 5 6 7 8 9
Appended Proc Count buffer (size: 19)
10 9 3 5 1 8 4 7 2 6 19 26 27 0 44 19 31 10 14
Sorted arr:
0 1 3 4 5 6 7 8 9 9 12 14 26 32 33 45 53 71 80
Sorted count:
10 10 19 19 14 31 0 1 2 3 4 5 6 7 8 9 26 27 44 // INCORRECT sorted order ...!!!!
Sorted aggregate:
10 10 19 19 14 31 0 1 5 4 5 6 7 8 9 26 27 44
有关第二种排序失败原因的任何线索?我错过了什么吗?
答案 0 :(得分:2)
正如另一个答案所暗示的那样,您有一个越界访问错误。
此外,你很幸运你的程序甚至已经达到了它,因为你在第一次调用SortAndAggreate
时有一个越界访问权限,因此你在你的节目中显示的输出问题基本上是无用的,因为正在调用未定义的行为。
在MyComparator
仿函数中,您正在执行此操作:
bool operator()(int i1, int i2)
{
return value_vector[i1] < value_vector[i2];
}
value_vector
是一个大小== 10的向量。但是,i1
和i2
的值最终会变为9
和10
,因此您将访问超出界限的元素。
问题的起源在main
:
int mycnt[] = {1, 2, 3, 4, 5, 6, 7, 8, 9,10};
您在填充prof_buf_cnt
时使用这些值作为索引,并且您在prof_buf_cnt
仿函数std::sort
中使用MyComparator
作为索引。
至少在这里,解决方案是使用基于0的索引。
int mycnt[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
注意:如果您使用以下内容替换MyComparator
仿函数中的该行:
return value_vector.at(i1) < value_vector.at(i2);
你会立刻看到这个问题,因为会抛出std::out_of_range
个例外。这可以保证你的程序会因错误而停止,而不是继续并给人一种正常工作的印象(唯一的问题是输出错误)。
有关不可预测的未定义行为的示例,请参阅以下两个链接:
See this example of your code using at()
See this example of your code using [ ]
请注意,上面的第二个链接显示您的代码“正常工作”,即使它不应该尽可能地完成,而第一个链接通过抛出异常来正确诊断问题。
答案 1 :(得分:1)
i
最多只能.size()-1
:
int aggr=0;
for(int i = 0; i < (int)(arr.size()); i++)
{
aggr = count[i];
if (arr[i] == arr[i+1]) {
但是你用i+1
索引数组,这超出了arr
的最后一个元素。