【问题标题】:How to remake one array into two smaller via C++?如何通过 C++ 将一个数组重新制作成两个更小的数组?
【发布时间】:2021-01-25 19:19:47
【问题描述】:

我需要从一个 10 元素数组中创建两个 5 元素数组。我做了这样的代码

#include <iostream>
using namespace std;

int main() {
    const int size1 = 10, size2 = 5;

    int array[size1]{ 1,3,6,2,82,10,6,34,2,5 }, arb[size2]{}, arc[size2]{};

    for (size_t i = 0; i < 5; i++)
    {
        arb[i] = array[i];
    }
    for (size_t i = 5; i < 9; i++) {
        
        for (size_t e = 0; e < 4; e++)
        {
            arc[e] = array[i];
        }
        
    }

    for (size_t i = 0; i < 5; i++)
    {
        cout << arb[i] << "\t";
    }
    cout << endl;

    for (size_t i = 0; i < 5; i++)
    {
        cout << arc[i] << "\t";
    }
}

但第二个数组给出“2 2 2 2 0”。我不知道如何解决这个问题。

【问题讨论】:

  • 只是一个提示:对于这么简单的事情,你真的需要循环嵌套吗?
  • 为什么要使用嵌套循环?对于外循环的每次迭代,外循环运行9 - 5 = 4 次,内循环运行4 - 0 = 4 次。所以它会运行 16 次。
  • 看起来您尝试使用嵌套循环来解释第二个数组的偏移量。您可以简单地使用类似于第一个循环的内容,但要包含到array 的偏移量。示例:arc[i] = array[i+5];。尽管如此,最好还是用成对的指针生成范围。
  • 想知道你为什么定义size2 = 5;并在这里使用它arb[size2]{}但不要在这里使用它for (size_t i = 0; i &lt; 5; i++)。最好写for (size_t i = 0; i &lt; size2; i++),其他循环也一样。

标签: c++ arrays algorithm copy


【解决方案1】:

除非您有特定的原因,这些 必须 是数组(这非常罕见,至少在我的经验中是这样),否则我会使用 std::vectors。这使得用较大的“数组”的正确部分初始化较小的“数组”变得微不足道:

std::vector<int> array { 1,3,6,2,82,10,6,34,2,5 };
std::vector<int> arb { array.begin(), array.begin() + size2};
std::vector<int> arc { array.begin() + size2, array.end() };

这也很容易(例如)将主数组分成两半,而不管它的确切大小:

std::vector<int> array { 1,3,6,2,82,10,6,34,2,5, 12, 17, 92, 101, -3 };
auto half = array.size() / 2;
std::vector<int> arb { array.begin(), array.begin() + half};
std::vector<int> arc { array.begin() + half, array.end() };

[就目前而言,如果主数组有奇数个元素,这将使后半部分更大,但如果这不是您想要的,您可以更改 half 的计算以适合您的需要。]

【讨论】:

  • 我个人尽量避免使用带有初始化列表构造函数的类型的非初始化列表构造的花括号。很容易养成这种习惯并意外地构造了一个包含两个对象的列表,而不是使用您想要的构造函数。例如std::vector&lt;int&gt; v{2, 3}; 而不是std::vector&lt;int&gt;(2, 3);
  • @FrançoisAndrieux:很公平(尽管对于迭代器来说幸运的是,即使是大括号也能做正确的事情)。
【解决方案2】:

这些嵌套循环

for (size_t i = 5; i < 9; i++) {
    
    for (size_t e = 0; e < 4; e++)
    {
        arc[e] = array[i];
    }
    
}

没有意义。此外,还使用了未知的幻数94。事实上,除了最后一个元素之外,数组arc 的所有元素都设置为元素array[8] 的值,即在外循环的最后一次迭代中使用的数组array 的元素的值。

程序可以如下所示

#include <iostream>

int main() 
{
    const size_t size1 = 10, size2 = 5;

    int array[size1]{ 1,3,6,2,82,10,6,34,2,5 }, arb[size2]{}, arc[size2]{};

    for ( size_t i = 0; i < size2; i++ )
    {
        arb[i] = array[i];
    }
    
    for ( size_t i = 0; i < size2; i++ )
    {
        arc[i] = array[i + size2];
    }
    
    for ( const auto &item : arb )
    {
        std::cout << item << ' ';
    }
    
    std::cout << '\n';
    
    for ( const auto &item : arc )
    {
        std::cout << item << ' ';
    }
    
    std::cout << '\n';
    
    return 0;
}

程序输出是

1 3 6 2 82 
10 6 34 2 5 

或者您可以使用标准算法std::copystd::copy_n 来代替循环。例如

#include <iostream>
#include <algorithm>
#include <iterator>
#include <algorithm>

int main() 
{
    const size_t size1 = 10, size2 = 5;

    int array[size1]{ 1,3,6,2,82,10,6,34,2,5 }, arb[size2]{}, arc[size2]{};

    std::copy_n( std::begin( array ), size2, std::begin( arb ) );
    std::copy_n( std::next( std::begin( array ), size2 ), size2, std::begin( arc ) );
    
    for ( const auto &item : arb )
    {
        std::cout << item << ' ';
    }
    
    std::cout << '\n';
    
    for ( const auto &item : arc )
    {
        std::cout << item << ' ';
    }
    
    std::cout << '\n';
    
    return 0;
}

程序输出同上图。

1 3 6 2 82 
10 6 34 2 5 

【讨论】:

  • 非常感谢!
【解决方案3】:

你在第二次循环中犯了错误,第二次迭代,这样在这个循环之后你只设置了新数组中的最后一个元素......

以下是正确版本的代码:

#include <iostream>

int main() {
  const int size1 = 10, size2 = 5;

  int array[size1]{ 1, 3, 6, 2, 82, 10, 6, 34, 2, 5 };
  int arb[size2]{};
  int arc[size2]{};

  for (size_t i = 0; i < 5; i++) {
    arb[i] = array[i];
  }
  for (size_t i = 5; i < 10; i++) {
    arc[i-5] = array[i];
  }

  for (size_t i = 0; i < 5; i++) {
    std::cout << arb[i] << "\t";
  }
  std::cout << std::endl;

  for (size_t i = 0; i < 5; i++) {
    std::cout << arc[i] << "\t";
  }
}

我还建议使用 std::copy 的代码更简单的版本:

#include <iostream>

int main() {
  const int size1 = 10, size2 = 5;

  int array[size1]{ 1, 3, 6, 2, 82, 10, 6, 34, 2, 5 };
  int arb[size2]{};
  int arc[size2]{};

  std::copy(&array[0], &array[5], arb);
  std::copy(&array[5], &array[10], arc);

  for (size_t i = 0; i < 5; i++) {
    std::cout << arb[i] << "\t";
  }
  std::cout << std::endl;

  for (size_t i = 0; i < 5; i++) {
    std::cout << arc[i] << "\t";
  }
}

【讨论】:

    【解决方案4】:

    让我们试试肮脏的变体,O(1)

    警告如果数组在 arb 或 arc 之前超出范围,这将在你面前爆炸

    int main() {
        const int size1 = 10, size2 = 5;
    
        int array[size1]{ 1,3,6,2,82,10,6,34,2,5 };
        int *arb = array, *arc = &array[size2];
    
        for (size_t i = 0; i < size2; i++) {
            cout << arb[i] << "\t";
        }
        cout << endl;
    
        for (size_t i = 0; i < size2; i++) {
            cout << arc[i] << "\t";
        }
    }
    

    【讨论】:

      【解决方案5】:

      问题出在嵌套的for 循环中

      for (size_t i = 5; i < 10; i++)
      { 
          //essentially what you're doing in this loop is that for each element 5, 6, 7, 8, 9 
          // for the first loop you are assigning for instance arc[0] till arc[3] to be all equal to array[5]
          // so whats happening is n=by the time you reach arc
          // take care you are assigning only 4 elements
      
          for (size_t e = 0; e < 4; e++)          // size here 
          {
              arc[e] = array[i];
          }
      
      }
      

      另一种方法是这样做:

      for (size_t i = 0; i < size2; i++)
      {
          arc[i] = array[i+5];
      }
      

      【讨论】:

        【解决方案6】:

        使用memcpy 复制一个普通的旧值类型数组。

        memcpy(arb, array, size2);
        memcpy(arc, array+size2, size2);
        

        这两个语句都替换了您的两个 for 循环。

        memcpy 函数可通过在源文件顶部声明 #include &lt;string.h&gt; 来使用。

        【讨论】:

        • 或者更好,恕我直言,std::copy from algorithm。
        猜你喜欢
        • 1970-01-01
        • 2020-07-20
        • 2012-09-29
        • 1970-01-01
        • 2021-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-08
        相关资源
        最近更新 更多