代码之家  ›  专栏  ›  技术社区  ›  jkeys

你能在C++中嵌入循环(彼此)吗?

  •  2
  • jkeys  · 技术社区  · 15 年前

    我正在研究合并排序函数。我已经完成了分类-我正在尝试完成合并部分。假设我正在学习C++,对指针有粗略的了解,并且不理解STD的所有规则::vector::迭代器(或STD::vector的,对于这件事)。

    假设num是从大小为“int ar[num]”的数组中复制(std::copy)值的原始std::vector的大小。假设farray的值为(0到(num/2)),sarray的值为((num/2)到num)。

    int num = original.size();
    std::vector<int> final(num);
    
    for (std::vector<int>::iterator it = farray.begin(); it != farray.end(); ++it) {
         for (std::vector<int>::iterator iter = sarray.begin(); iter != sarray.end(); ++iter) {
             if (*it > *iter) final.push_back(*it);
              else
                   final.push_back(*iter);
         }
    }
    

    这段代码编译后,我最新的稳定版本dev-c++不会抛出任何警告或错误。我不知道这是否有效,我仍然需要尝试并计算出期末考试的所有值。我只想知道这是常见的,容易出错,还是风格不好。如果是的话,你会怎么做

    6 回复  |  直到 15 年前
        1
  •  7
  •   Smashery    15 年前

    这是有效的…但是一个for循环可能不是你想要的。当您使用两个for循环时,每次外部循环时,您的内部循环都会返回到开始。因此,如果向量包含:

    farray: 10 9 8 4 3
    sarray: 7 6 4 3 1
    

    然后,最终数组将包含如下内容:

    10 10 10 10 10 9 9 9 9 9 8 8 8 8 8 7 6 4 4 4 7 6 4 3 3
    

    因为您正在测试每个组合,并将较大的组合添加到最终列表中。更好的解决方案可能是为每个列表记住一个迭代器,并且只使用一个循环。与其循环遍历一个列表,不如一起遍历这两个列表——如果sarray有更大的数字,那么增加sarray迭代器,并将其与旧的farray迭代器进行比较。当sarray和farray都是空的时候,停止你的循环。

    vector<int> fiter = farray.begin();
    vector<int> siter = sarray.begin();
    vector<int> final;
    
    // Let's traverse both farray and sarray.
    // We'll want to stop this loop once we've traversed both lists.
    while (fiter != farray.end() && siter != sarray.end())
    {
        if (fiter == farray.end())
        {
            // we must have gone right through farray - 
            // so use the value from sarray, and go to the next one
            final.push_back(*siter);
            siter++;
        }
        else if (siter == sarray.end())
        {
            // we must have gone right through sarray - 
            // so use the value from farray, and go to the next one
            final.push_back(*fiter);
            fiter++;
        }
        else if (*siter > *fiter)
        {
            // siter is the bigger of the two - add it to the final list, and
            // go to the next sarray entry
            final.push_back(*siter);
            siter++;
        }
        else // *fiter >= *siter
        {
            // fiter is the bigger of the two - add it to the final list, and
            // go to the next farray entry
            final.push_back(*fiter);
            fiter++;
        }
    }
    

    我没有测试过-如果这是做作业的话,那么 拜托 试着去理解我所做的,你自己去写,而不是复制+粘贴。

        2
  •  2
  •   Simeon Pilgrim    15 年前

    除了合并排序算法之外,使用迭代器嵌套的for循环与使用两个变量嵌套的for循环一样有效。 J .

        3
  •  1
  •   Community Sam Holder    7 年前

    只要不重用循环变量,就可以嵌套任何类型的循环(for,while,do while)。如果您尝试这样做,它将编译,但可能会在运行时失败。尽管技术上允许在现代C和C++中为嵌套循环变量使用相同的名称,但这是混淆的并且应该避免。

    除了前面提到的循环变量重用的问题之外,它与单个循环差不多不容易出错。

    了解更多关于 limits 嵌套循环的。

        4
  •  1
  •   Electrons_Ahoy    15 年前

    循环嵌套是一种完全合法的方法。例如,这是穿过二维数组的经典“老派”方法——一个循环沿Y轴向下,另一个循环沿X轴向下。

    现在,有了这些孩子以及他们的for-each循环、迭代器和映射函数,就可以证明 “更好” 方法(为了更好的定义)但是嵌套循环工作得很好。使用C++或指针不会改变这一点。

        5
  •  0
  •   John Dibling    15 年前

    是的,你可以这样做。是的,它经常容易出错。事实上,编写循环本身就容易出错,这是使用STL中的算法的一个参数,就像对每个算法、复制和转换一样。

        6
  •  0
  •   Peter    15 年前

    是的,您可以将循环或其他语句嵌套到您想要的几乎任何深度(在原因中;有一些限制,如另一个答案中所述,但它们远高于您应该需要的深度)。