【问题标题】:Navigating multidimensional array using one variable使用一个变量导航多维数组
【发布时间】:2019-12-18 03:22:50
【问题描述】:

我有一个 3D 数组,我需要使用单个 int 在该数组中找到一个 int。

我的数组:

int arrayOne[3][3] = {
    {1,2,3},
    {4,5,6},
    {7,8,9}
};

我需要能够使用单个 int 来导航数组,例如:

int i = 4;
cout << arrayOne[4];

这将打印出 5。

可以这样做还是以另一种方式做到这一点?

我开始使用 3D 数组进行编码,如果不需要,我真的不想重写所有内容。

我搜索了一下,没有找到解决办法。

【问题讨论】:

  • 为什么要把多维数组当作一维数组?
  • 你可以选择不可读的版本,没有任何干预变量,只给出一个索引,std::cout &lt;&lt; "4th element: " &lt;&lt; *(*(arrayOne + 4 % sizeof *arrayOne/sizeof **arrayOne) + 4 % sizeof *arrayOne/sizeof **arrayOne) &lt;&lt; '\n';

标签: c++ arrays


【解决方案1】:

您可以将单个 int 包裹在数组的大小周围(在选定的维度上):

arrayOne[i / 3][i % 3]  // wrapping around the size of the inner arrays

澄清这里发生了什么:

  • i = 0 =&gt; i/3 = 0, i%3 = 0
  • i = 1 =&gt; i/3 = 0, i%3 = 1
  • i = 2 =&gt; i/3 = 0, i%3 = 2
  • i = 3 =&gt; i/3 = 1, i%3 = 0
  • i = 4 =&gt; i/3 = 1, i%3 = 1
  • i = 5 =&gt; i/3 = 1, i%3 = 2
  • i = 6 =&gt; i/3 = 2, i%3 = 0
  • i = 7 =&gt; i/3 = 2, i%3 = 1
  • i = 8 =&gt; i/3 = 2, i%3 = 2

你可以看到 i 在 (i/3) 或 (i%3) 溢出之前可以取 3*3 个不同的值,这很有意义。

相反的操作是将第一个坐标乘以 3 并加上第二个:

(i/3) * 3 + (i%3) == i

知道如何在两个“索引系统”之间切换,编写一个将 2 数组转换为 1 维数组的循环对您来说是微不足道的。


我发现 (2D!) 线圈的图片在这里很有用,因为线圈是跨越 2D 区域的 1D 线:


编辑:一定要查看Andreas DM's answer

【讨论】:

    【解决方案2】:

    我需要能够使用单个 int 来导航数组,例如: int i = 4; cout &lt;&lt; arrayOne[4]; 可以这样做

    是的,它是:

    int arrayOne[3][3] {
      {1,2,3},
      {4,5,6},
      {7,8,9},
    };
    
    int* array = arrayOne[0];
    std::cout << array[4];
    

    【讨论】:

    • 虽然是迂腐的 UB。
    • @Jarod42 是吗?由于数组项必须是连续的,我看不出它是如何工作的。
    • @hugo:arrayOne[0]int (&amp;)[3],越界访问就是UB。所以array[0]array[1]array[2] 甚至array + 3 都是有效的,但array[3]array + 4 是UB。不幸的是,规则不包括这种情况。在实践中,我相信它会起作用,但我们处于 UB 世界。
    【解决方案3】:

    您使用两个 for 循环迭代一个二维数组,一个嵌套在另一个中。 事实上,您甚至不需要一个变量,您只需 cout 每次迭代的索引中的数字。 如果你想用一个索引来做,把二维数组变成一维数组。

        int arr[3][3] = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
              };
    
        int singleArr [arr.length*arr[0].length];
        int counter = 0;
    
        for (int i = 0; i < sizeof(arr)/4; i++) {
            for (int j = 0; j < sizeof(arr[0])/4; j++) {
                singleArr[counter] = arr[i][j];
                counter++;
            }
        }
        std::cout<<singleArr[4];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多