毫无疑问,你们中的一些人已经看过我最近发布的帖子,所有内容都涉及同一个程序。我一直遇到问题。重申一下:仍在学习,不是很先进,不太理解指针,没有上课,根本不理解 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);
                }
            }
        }

我重写了合并排序函数的合并部分,以便......好吧,让它工作。我实际上对这段代码有几个疑问:

  1. 如果 for 循环可能在下一次传递时更改它们,那么与 std::vector::iterators it && iter 比较我的最后两个 if 语句是否是一种好的形式?
  2. iter 和 iter 的值会在该循环的最后一次传递中发生变化并搞砸我的代码吗?将我的最后一个 if 语句放在 *it 和 *iter 比较之前吗?
  3. end() 成员函数是否引用调用它的函数的最后一个值?看起来它可能会以某种方式延伸过去。

编辑:我将在明天回复所有回复,所以如果您想了解更多信息,请稍后回来查看。已经过了午夜了。晚安。

有帮助吗?

解决方案

1.可以比较与 for 循环条件来自同一容器的迭代器,但是只有当您在 for 循环语句的增量部分或 for 循环本身的主体中移动一个或其他迭代器时,这才有意义。在这个 for 循环中你比较 iter 反对 sarray.end() 但 for 循环永远不会改变 iter. 。这意味着要么不会出现迭代,要么 for 循环永远不会终止。另外,您可能想使用 != 并不是 < 用于比较。 ==!= 适用于所有迭代器, < 没有。

            for (int i = 0; iter != sarray.end(); i++) {
                final.push_back(*iter);
            }

作为 iter 从你想要循环开始的地方开始,你可能想要这样的东西:

            for (; iter != sarray.end(); ++iter) {
                final.push_back(*iter);
            }

由于您仍在学习(尽管不是我们所有人!),通过这样的算法可能会很有启发,但您应该意识到 std::merge 这可能会做你想要的。

std::merge( farray.begin(), farray.end(), sarray.begin(), sarray.end(), std::back_inserter( final ) );

(你需要 #include <iterator><algorithm>.)

2.我没有看到在外部 for 循环中增加 iter 或 it 会使后面的 for 循环中的逻辑失效,即 1 中的点。在旁边。

3 . end() 指向容器末尾的一个,因此您可以使用它进行循环终止检查,但您不应该尝试取消引用“==“ 到 ”.end()".

其他提示

我没有检查你的算法的实现,我只是参考你的三个问题:

  1. 迭代器很像指向容器值的指针。这与在 for 循环中使用 size_t i 然后使用 ++i 完全相同。您觉得将 farray[i] 与 sarray[i] 进行比较有问题吗?可能不会,所以没关系。
  2. 我在这里看到您在代码中所做的事情是,您只是读取 *it 和 *iter 的值,您实际上并没有更改它们,因此它们不会更改。
  3. end()指向一个无效的地方。它并不指向最后一个值,而是指向“它之后”。如果你愿意的话,它就像“NULL”,因此如果(iter == sarray.end())为真,如果你写*iter,你会崩溃,因为你不能取消引用等于end()的迭代器。

一些一般建议:您需要考虑变量名称。将迭代器称为“it”和“iter”有时会让您感到困惑。其实仔细一看,已经有了。如果“farray”和“sarray”是有意义的名称,那么“fiter”和“siter”又如何呢?

另外,想一想合并排序在做什么。最后两个块只是为了“耗尽”哪个迭代器还剩下一些东西。所以他们不需要在第一个循环中。

我可能会把它写成(伪代码):

while not (list1.empty and list2.empty):
    if list1.empty:
        result.push(list2.pop)
    else if list2.empty:
        result.push(list1.pop)
    else if list1.top > list2.top:
        result.push(list2.pop)
    else:
        result.push(list1.pop)

或者用有点生锈的货物崇拜的 C++:

std::vector<int>::iterator fiter = farray.begin();
std::vector<int>::iterator siter = sarray.begin();

while (fiter != farray.end() || siter != sarray.end()) {
    if (fiter == farray.end())      final.push_back(*siter++);
    else if (siter == sarray.end()) final.push_back(*fiter++);
    else if (*fiter > *siter)       final.push_back(*siter++);
    else                            final.push_back(*siter++);
}

您需要考虑一些事情。

首先,如果您要合并两个范围,最好使用 标准::合并 功能而不是滚动你自己的。

您的代码有点难以阅读,因为您使用不同的缩进样式以及花括号的位置。选择一种风格并坚持下去。

for 循环的第一部分似乎是合并的正确实现:

for (;it != farray.end() && iter != sarray.end();) {
    if (*it > *iter) {
        final.push_back(*it);
        it++;
    }    
    else
    {
        final.push_back(*iter);
        iter++;
    }

...这应该是完成工作所需的全部内容。

循环的第二部分有几个问题:

   for (;it != farray.end() && iter != sarray.end();) {
         :   :
            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);
                }
            }
        }

一方面,编写 for() 条件语句使得两者 ititer 不得指向 end() 他们各自的集合,否则循环结束。所以 it 永远不能指向 sarray.end(), iter 永远不能指向 farray.end(), ,并且两者都不是 if 声明永远可以火。它们都是死(无法访问)代码。

但即使它们不是死代码,它们也有错误。条件式中的 for(...) 当迭代器指向集合末尾时,循环会中断,但该迭代器永远不会移动,因此会出现无限循环。

又是这两个 for(...)s 是不需要的死代码,因为迭代器永远无法指向向量的末尾。

一条简单的评论:为什么不使用 while (condition) 代替 for(; !condition; ).

后者的构造不规范且难以理解!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top