Home Articles

与C中的循环中的变化值进行比较是否是一种好的形式?

Asked
Viewed 351 times
1

毫无疑问,有些人看过我最近的帖子,都是关于同一个节目的 . 我一直遇到问题 . 重申:仍然学习,不是非常先进,不了解指针,不上课,根本不理解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 Answers

  • 3

    我没有检查你的算法的实现,我将只提到你的三个问题:

    • 迭代器非常类似于指向容器值的指针 . '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()的迭代器 .

  • 3

    你有几点要考虑的事情 .

    首先,如果你要合并两个范围,那么使用std::merge函数而不是滚动自己的函数要好得多 .

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

    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(...) 都是不可用的死代码,因为迭代器永远不会指向向量的末尾 .

  • 1

    一个简单的评论:为什么不使用 while (condition) 而不是 for(; !condition; ) .

    后一种结构是非标准的,难以理解!

  • 0

    1 . 将来自同一容器的迭代器与for循环条件进行比较是很好的,但只有在for循环语句或for循环本身的增量部分中移动一个或其他迭代器时才有意义 . 在这个for循环中,你将 itersarray.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 . 我没有看到增加iter或者它在外部for循环中使后面的for循环中的逻辑无效,在1.旁边的点 .

    3 . end() 指向容器末尾的一个,因此您可以将其用于循环终止检查,但不应尝试取消引用“ == " to " .end() ”的迭代器 .

  • 0

    一些一般性建议:您需要考虑变量名称 . 调用你的迭代器'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++);
    }
    

Related