vector<int>& mergesort(vector<int> &a) {
if (a.size() == 1) return a;
int middle = a.size() / 2;
vector<int>::const_iterator first = a.begin();
vector<int>::const_iterator mid = a.begin() + (middle - 1);
vector<int>::const_iterator last = a.end();
vector<int> ll(first, mid);
vector<int> rr(mid, last);
vector<int> l = mergesort(ll);
vector<int> r = mergesort(rr);
vector<int> result;
result.reserve(a.size());
int dp = 0, lp = 0, rp = 0;
while (dp < a.size()) {
if (lp == l.size()) {
result[dp] = (r[rp]);
rp++;
} else if (rp == r.size()) {
result[dp] = (l[lp]);
lp++;
} else if (l[lp] < r[rp]) {
result[dp] = (l[lp]);
lp++;
} else {
result[dp] = (r[rp]);
rp++;
}
dp++;
}
a = result;
return a;
}
它正确编译但在执行时,我得到了:
此应用程序已请求 运行时以不寻常的方式结束它。
这是一个奇怪的错误。
代码是否存在根本错误?
答案 0 :(得分:7)
此result.reserve(a.size())
只会影响矢量的 容量 ,而不会影响 尺寸 。 (向量的容量告诉向量可以增长到哪个大小,而无需重新分配和复制所有成员。基本上它只用于优化目的。)您无法访问保留之后result
中的所有成员,因为没有任何成员。使用result.push_back(...)
代替result[dp] = ...
或result.resize(a.size())
代替result.reserve(a.size())
。
我认为前者可能更有效。
答案 1 :(得分:5)
一个问题是使用reserve()
(使用resize()
或使用push_back()
追加项目而不是访问索引)。
if (a.size() == 1) return a;
int middle = a.size() / 2;
vector<int>::const_iterator first = a.begin();
vector<int>::const_iterator mid = a.begin() + (middle - 1);
vector<int>::const_iterator last = a.end();
vector<int> ll(first, mid);
vector<int> rr(mid, last);
这可能是另一个问题。如果大小为2,则ll
最终将成为空向量,并且此函数似乎不会处理此问题。似乎没有太多理由从中间减去1。
您可能还在远远超出需要复制内容:您不应该需要l
和r
向量(因为它们只是ll
的副本和rr
),同样我认为您不需要result
向量,因为您可以将合并后的结果直接写回a
。
答案 2 :(得分:1)
reserve()不会更改向量中的内容量。你已经创建了一个空向量,为它保留了一定的大小,然后用v [i] = x;这不是向量的有效使用,因为向量中仍然没有任何第i个元素。
改为使用resize()。
答案 3 :(得分:0)
错误消息非常不清楚,因为当异常未处理时,它是VC ++的标准消息。你可以在main中添加一个try-catch-clock来获取异常和一个更有意义的错误:
int main() {
try {
// do main stuff here
}
catch ( std::exception & e ) {
std::cout << e.what() << std::endl;
}
}
这是针对命令行的。如果您的应用程序没有,请使用消息框或将错误写入日志文件。
关于代码中的问题,所有其他答案似乎都是正确的。