毫无疑问,有些人看过我最近的帖子,都是关于同一个节目的 . 我一直遇到问题 . 重申:仍然学习,不是非常先进,不了解指针,不上课,根本不理解OOP概念等 . 这段代码只是将两个排序后的矢量,farray和sarray合并为一个单独的排序向量 . 至少,我希望它能做到这一点 . 告诉我:
//int num is to find the size of the original vector and
//build up farray and sarray; not used in the merge process
int num = original.size()
std::vector<int> final;
std::vector<int>::iterator it = farray.begin();
std::vector<int>::iterator iter = sarray.begin();
//farray.size() == (0 thru (num / 2))
//sarray.size() == ((num / 2) thru num)
for (;it != farray.end() && iter != sarray.end();) {
if (*it > *iter) {
final.push_back(*it);
it++;
}
else
{
final.push_back(*iter);
iter++;
}
if (it == farray.end()) {
for (int i = 0; iter < sarray.end(); i++) {
final.push_back(*iter);
}
}
if (iter == sarray.end()) {
for (int i = 0; it < farray.end(); i++) {
final.push_back(*iter);
}
}
}
我重写了我的合并排序函数的合并部分,以便......好吧,让它工作 . 我实际上有几个关于此代码的问题:
-
与std :: vector :: iterators进行比较是不是很好的形式?如果for循环可能在下一次传递中改变它们的话,我的最后两个if语句是&& iter吗?
-
iter的值是否会在此循环的最后一遍中改变并搞砸我的代码?在* it和* iter比较之前将我的最后一个if语句放在哪里?
-
end()成员函数是否引用调用它的最后一个值?它似乎可能以某种方式延伸过去 .
编辑:明天我会回复所有的回复,所以如果你想听到更多,请回来查看 . 已经过了午夜 . 晚安 .
5 回答
1 . 将来自同一容器的迭代器与for循环条件进行比较是很好的,但只有在for循环语句或for循环本身的增量部分中移动一个或其他迭代器时才有意义 . 在这个for循环中,你将
iter
与sarray.end()
进行比较,但for循环永远不会改变iter
. 这意味着要么没有迭代,要么for循环永远不会终止 . 此外,您可能希望使用!=
而不是<
进行比较 .==
和!=
适用于所有迭代器,<
没有 .当
iter
从你想要循环开始的地方开始时,你可能需要这样的东西:正如你们所做的那样!),通过这样的算法可能是有益的,但是你应该知道
std::merge
可能会做你想要的 .(你需要
#include <iterator>
和<algorithm>
. )2 . 我没有看到增加iter或者它在外部for循环中使后面的for循环中的逻辑无效,在1.旁边的点 .
3 .
end()
指向容器末尾的一个,因此您可以将其用于循环终止检查,但不应尝试取消引用“==
" to ".end()
”的迭代器 .我没有检查你的算法的实现,我将只提到你的三个问题:
迭代器非常类似于指向容器值的指针 . 's exactly like using size_t i and then ++i in the for loop. would you feel it'将farray [i]与sarray [i]进行比较有问题吗?可能不是,所以没关系 .
我在你的代码中看到你做的是,你只是阅读* it和* iter的值,你不要改变 .
end()指向无效的地方 . 如果你愿意的话,它不会像_1851077那样,因此如果(iter == sarray.end())为真,如果你要编写* iter会崩溃,因为你不能取消引用等于end()的迭代器 .
一些一般性建议:您需要考虑变量名称 . 调用你的迭代器'it'和'iter'会让你在某个时候感到困惑 . 实际上,如果仔细观察,它已经有了 . 如果'farray'和'sarray'是有意义的名字,那么'fiter'和'siter'怎么样?
另外,请考虑合并排序的作用 . 最后两个块只是为了“消耗”任何迭代器留下的东西 . 所以他们不需要在第一个循环中 .
我可能会把它写成(伪代码):
或者在有点生锈的货物C中:
你有几点要考虑的事情 .
首先,如果你要合并两个范围,那么使用std::merge函数而不是滚动自己的函数要好得多 .
您的代码有点难以阅读,因为您使用不同的缩进样式以及花括号的位置 . 选择一种风格并坚持下去 .
for循环的第一部分似乎是合并的正确实现:
......这应该是完成工作所需要的一切 .
循环的第二部分有几个问题:
首先,写入for()条件,以便
it
和iter
都不能指向它们各自集合的end()
,否则循环结束 . 所以it
永远不能指向sarray.end()
,iter
可以永远不要指向farray.end()
,并且if
声明都不能发射 . 它们都是死的(无法访问)代码 .但即使它们不是死代码,它们也有错误 . 当迭代器指向集合的末尾时,
for(...)
中的条件会中断循环,但是这个迭代器永远不会被移动,所以你有一个无限循环 .同样,这两个
for(...)
都是不可用的死代码,因为迭代器永远不会指向向量的末尾 .一个简单的评论:为什么不使用
while (condition)
而不是for(; !condition; )
.后一种结构是非标准的,难以理解!