何时使用多维数组?

3

在C#中,多维数组的概念非常酷。但我不明白什么时候使用它们。比如说,在哪种类型的应用程序中会使用这个概念。

7个回答

9

不想听起来陈词滥调,但当你有多维数据时,你需要使用多维数组。

矩阵是一个常见的例子,但它也可以很容易地成为游戏棋盘(例如国际象棋),或者作为N维迷宫或计数器的数据模型,或者其他任何东西。


5

其中一个常见的用途是矩阵。


2
作为一个附带说明,您可以使用多维数组(int[,])或交错数组(int[][])。前者可以一步初始化,但需要更大的连续内存块,并且访问速度较慢,而后者更加友好,因为子数组可以分布在地址空间中,每个子数组可以是不同的长度,并且所有单维数组(SZarrays)都在CLR中进行了特殊优化。然而,您需要使用交错数组分别初始化每个维度:
int[][] jagged = new int[5][];
for (int i=0; i<jagged.Length; i++)
{
    jagged[i] = new int[10];    // length can be different for each sub-array, if needed
}

多维数组可以一次性初始化。
int[,] mArray = new int[5,10];

我不知道C#有“多维数组”。虽然我可能永远没有使用它们的机会,但了解这一点很好。感谢您的分享。Keith。 - corlettk
你有一个点错了。多维数组的访问速度更快,因为锯齿形数组需要双重间接性和空值检查,除了边界检查。 - Phil Miller

2

假设你想编写一个国际象棋游戏,你会如何使用一维数组来表示棋盘?


1
有一个长度为64的数组:p(我不是说这很容易,但...它是可能的) - AlexDrenea
1
是的,尽管值得指出的是,在这种情况下,一维数组不太方便,但它并不会阻止你做任何事情。此外,象棋游戏往往使用位板来表示棋盘。 - Noldorin
@Umair:并不是在所有情况下都是低效的。大多数国际象棋 AI 使用一种棋盘表示的组合,其中一个常用的表示方法是2D数组。 - Noldorin
1
http://www.gamedev.net/reference/programming/features/chess2/page2.asp http://www.gamedev.net/reference/programming/features/chess2/page3.asp - Umair Ahmed
@Umair,这些链接展示了一些极端的优化。低效并不等于可以被优化。 - Pool
显示剩余3条评论

0
这段 Java 代码片段可以为你带来启示…… 它将一个文件读入到一个二维数组中。这是我的 MazeOfBolton 解决方案的一部分(在谷歌上搜索它)。
  /**
   * Reads the file into a char[rows][cols] matrix.
   * @param String filename - the name of the file to read
   * @return a two-dimensional array of chars containing file contents.
   */
  private static char[][] readMatrix(String filename) throws IOException {
    BufferedReader input = null;
    try {
      input = new BufferedReader(new FileReader(filename));
      List<String> lines = new ArrayList<String>();
      String line = null;
      while ( (line = input.readLine()) != null ) {
        lines.add(line);
      }
      int rows = lines.size();
      char[][] matrix = new char[rows][];
      for (int i=0; i<rows; i++) {
        matrix[i] = lines.get(i).toCharArray();
      }
      return matrix;
    } finally {
      if(input!=null)input.close();
    }
  }

编辑:我应该说一下为什么我使用了一个矩阵...特别是因为我必须构建一个列表来获取数组...嗯?为什么不直接使用列表呢?简短的答案是速度

访问一个数组(无论有多少维)在底层实现上是作为“索引算术”(又称指针算术)实现的,因此它不仅访问一个数组元素O(1),而且速度很快,是O(1)...比等效的arrayList.get(int index)(当你这样做几百万次时)要快得多...在(虽然是人工制造的)算法竞赛的世界中,速度就是一切。

谢谢。Keith。


0
一个二维数组的好例子是位图图像。想象一下图片中的每个像素都占据了Pixel[1024][768]数组中的一个块。所以要找出屏幕左上角的像素是什么颜色,您需要查看Pixel[0][0]
三维数组需要更多的可视化,但是一个经典的例子是用来模拟空间中的点。
我在我编写的快速且不精确的Hold'Em模拟器中使用了一个二维数组来表示preflop决策,它看起来有点像这样;
_Open = new char[][] 
{             //  2    3    4    5    6   7   8   9   T   J   Q   K   A
    new char [] {'P', 'F', 'F', 'F', 'F','F','F','F','F','F','F','P','P'}, // 2
    new char [] {'F', 'P', 'F', 'F', 'F','F','F','F','F','F','F','P','P'}, // 3 
    new char [] {'F', 'F', 'P', 'F', 'F','F','F','F','F','F','F','P','P'}, // 4
    new char [] {'F', 'F', 'F', 'P', 'F','F','F','F','F','F','F','P','P'}, // 5
    new char [] {'F', 'F', 'F', 'F', 'P','F','F','F','F','F','F','P','P'}, // 6
    new char [] {'F', 'F', 'F', 'F', 'F','P','F','F','P','F','F','P','P'}, // 7 
    new char [] {'F', 'F', 'F', 'F', 'F','F','P','P','P','P','F','P','P'}, // 8
    new char [] {'F', 'F', 'F', 'F', 'F','F','F','P','P','P','P','P','P'}, // 9
    new char [] {'F', 'F', 'F', 'F', 'F','F','F','F','P','P','P','P','P'}, // T
    new char [] {'F', 'F', 'F', 'F', 'F','F','F','F','F','P','P','P','P'}, // J
    new char [] {'F', 'F', 'F', 'F', 'F','F','F','P','P','P','P','P','P'}, // Q
    new char [] {'P', 'P', 'P', 'P', 'P','P','P','P','P','P','P','P','P'}, // K
    new char [] {'P', 'P', 'P', 'P', 'P','P','P','P','P','P','P','P','P'}  // A
};

使用0代表2,12代表Ace。因此,如果模拟器检测到Ace,King,则会检查_Open [12] [11],看到'P'(表示'push'或'all-in'),并相应地采取行动。


0

虽然我相信其他人可以提供许多不同的例子,但我与机器人一起工作,机器人执行的许多任务之一是托盘装载,将物品按行和列的形式放在托盘上。 托盘上的每个位置都是数组的2个甚至3个维度索引的集合。

locationArrayt [row,column]

我们还将它们用于多语言应用程序。 字符串数组代表不同的错误消息,第二个索引是语言。

message [errorNumber,language]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接