2012-03-06 38 views
8

Trong ngôn ngữ lập trình C#, làm cách nào để truyền một hàng của mảng đa chiều? Ví dụ: giả sử tôi có các thông tin sau:C# hàng của mảng đa chiều

int[,] foo; 
foo = new int[6,4]; 
int[] least; 
least = new int[6]; 

for(int i = 0; i < 6; i++) 
{ 
    least[i] = FindLeast(ref foo[i]);  //How do I pass the ith row of foo??? 
} 

Ngoài ra, bất kỳ ai cũng có thể giải thích cho tôi về lợi ích của mảng hình chữ nhật và răng cưa trong C#? Điều này có xảy ra với các ngôn ngữ lập trình phổ biến khác không? (Java?) Cảm ơn tất cả sự giúp đỡ!

Trả lời

8

Bạn không thể vượt qua một hàng của một mảng hình chữ nhật, bạn phải sử dụng một mảng lởm chởm (một mảng của mảng):

int[][] foo = new int[6][]; 

for(int i = 0; i < 6; i++) 
    foo[i] = new int[4]; 

int[] least = new int[6]; 

for(int i = 0; i < 6; i++) 
    least[i] = FindLeast(foo[i]); 

EDIT
Nếu bạn cảm thấy quá khó chịu để sử dụng một mảng lởm chởm và rất cần một hình chữ nhật, một thủ thuật đơn giản sẽ giúp bạn tiết kiệm:

int FindLeast(int[,] rectangularArray, int row) 
+0

Tôi có thể chuyển một mảng hình chữ nhật sang một hàm chấp nhận các mảng có răng cưa không? – CodeKingPlusPlus

+1

@CodeKingPlusPlus: Không, bạn không thể – BlackBear

+0

Vì vậy, về cơ bản đây không phải là một giải pháp :) –

4

Bạn không, với số rectangular array như thế. Đó là một vật thể duy nhất.

Thay vào đó, bạn cần phải sử dụng một jagged array, như thế này:

// Note: new int[6][4] will not compile 
int[][] foo = new int[6][]; 
for (int i = 0; i < foo.Length; i++) { 
    foo[i] = new int[4]; 
} 

Sau đó bạn có thể vượt qua mỗi "tiểu" -array:

int[] least = new int[foo.Length]; 
for(int i = 0; i < 6; i++) 
{ 
    least[i] = FindLeast(foo[i]); 
} 

Lưu ý rằng không cần để vượt qua foo[i] bằng cách tham chiếu và bạn cũng nên gán giá trị biến cục bộ tại điểm khai báo, khi có thể. (Nó làm cho mã của bạn nhỏ gọn hơn và đơn giản hơn để hiểu.)


Nếu bạn không chắc chắn về điều này, bạn có thể muốn đọc bài viết của tôi trên parameter passing in C#.

+0

Bạn đã đánh đập tôi bằng giây! : P – BlackBear

+0

Tôi có thể chuyển mảng hình chữ nhật thành mảng có răng cưa không? – CodeKingPlusPlus

+1

Điều này, với tôi, có vẻ như một giải pháp không. Điều gì có thể được thực hiện trong trường hợp của một mảng hình chữ nhật? –

-1

cập nhật: Như Jon Skeet đúng khi chỉ ra, điều này không p rovide một tham chiếu vào hàng, nhưng thay vì tạo một bản sao mới. Nếu mã của bạn cần phải thay đổi một hàng, phương pháp này không hoạt động. Tôi đã đổi tên phương thức để làm rõ điều này.

Cập nhật 2: Nếu bạn muốn có thể chỉnh sửa trường và có thay đổi xảy ra với mảng mẹ, bạn có thể sử dụng trình bao bọc mà tôi cung cấp trong this library I maed. Hàng kết quả foo.Row(i) không phải là một mảng, mà thay vào đó thực hiện IList, vì vậy nếu bạn cần để chuyển một mảng thì đây không phải là giải pháp.


Phương pháp mở rộng này sẽ cho phép bạn truy vấn mảng đa chiều cho các hàng. Cần lưu ý rằng điều này là nặng tính toán (không hiệu quả) và nếu thì có thể bạn nên sử dụng một mảng răng cưa cho những tình huống này. Tuy nhiên, nếu bạn thấy mình trong một tình huống mà bạn không thể sử dụng một mảng răng cưa, điều này có thể hữu ích.

public static T[] CopyRow<T>(this T[,] arr, int row) 
{ 
    if (row > arr.GetLength(0)) 
     throw new ArgumentOutOfRangeException("No such row in array.", "row"); 

    var result = new T[arr.GetLength(1)]; 
    for (int i = 0; i < result.Length; i++) 
    { 
     result[i] = arr[row, i]; 
    } 
    return result; 
} 

Mã của bạn bây giờ có thể được viết lại:

int[,] foo; 
foo = new int[6,4]; 
int[] least; 
least = new int[6]; 

for(int i = 0; i < 6; i++) 
{ 
    least[i] = FindLeast(ref foo.CopyRow(i)); 
} 
+0

Đó là sao chép nội dung mảng mặc dù, mà không làm điều tương tự. Cụ thể, nếu 'FindLeast' * sửa đổi * mảng, thì sửa đổi đó sẽ không hiển thị trong kết quả. Ngoài ra, kết quả của 'foo.Row (i)' không được phân loại là một biến, do đó mã sẽ không biên dịch. Bạn chỉ đơn giản là * không thể * đối xử với một mảng hình chữ nhật như thể nó là một mảng lởm chởm - các mảng không hoạt động như thế. –

+0

Tôi không hiểu bình luận của bạn về việc biên dịch. Mã chạy và biên dịch. –

+0

Bạn hoàn toàn đúng! Điều này không đi qua một tham chiếu đến một hàng (mà không thể được thực hiện). Giả sử rằng 'FindLeast' không sửa đổi hàng, điều này sẽ hoạt động. Tôi sẽ đổi tên phương thức, mặc dù :) –