2012-09-02 79 views
1

我有一個3d陣列double[,,] numbers = new double[x,y,z];現在如果想象3D陣列看起來像一個有數字的立方體,我需要找到所有三個切片中每個切片的最小和最大值方向。3D陣列切片中最小和最大的值

通過簡單循環就可以輕鬆完成,但C#有任何函數來查找切片中最小且最大的值?

解釋它遠一點,也許這種「不真實」的代碼將有助於:

int i; 

double[] xmin = new double[x]; 
double[] xmax = new double[x]; 
double[] ymin = new double[y]; 
double[] ymax = new double[y]; 
double[] zmin = new double[z]; 
double[] zmax = new double[z]; 

for(i = 0; i < x; i++) 
{ 
    MinOf(numbers[i, y, z]) = xmin[i]; 
    MaxOf(numbers[i, y, z]) = xmax[i]; 
} 

for(i = 0; i < y; i++) 
{ 
    MinOf(numbers[x, i, z]) = ymin[i]; 
    MaxOf(numbers[x, i, z]) = ymax[i]; 
} 

for(i = 0; i < z; i++) 
{ 
    MinOf(numbers[x, y, i]) = zmin[i]; 
    MaxOf(numbers[x, y, i]) = zmax[i]; 
} 

希望有人能幫助我與。 乾杯,菲爾13131

+1

OT:只是在每個循環中聲明'i'。 –

+1

C#根本不支持'切片'。所以你必須在這裏循環。 –

回答

2

您可以製作枚舉切片的方法。這是一個維,你需要另外兩個,但我認爲你可以管理:

public static IEnumerable<T> SliceX<T>(T[,,] data, int x) { 
    for (int y = 0; y < data.GetLength(1); y++) { 
    for (int z = 0; z < data.GetLength(2); z++) { 
     yield return data[x, y, z]; 
    } 
    } 
} 

然後,你可以使用MinMax方法,但當然會是遍歷數據兩次:

double min = SliceX(numbers, x).Min(); 
double max = SliceX(numbers, x).Max(); 

您可以在一個迭代都得到最小和最大擴展方法:

public static class IEnumerableExtensions { 

    public static void GetMinMax<T>(this IEnumerable<T> data, out T min, out T max) where T : IComparable<T> { 
    bool first = true; 
    min = max = default(T); 
    foreach (T value in data) { 
     if (first) { 
     min = max = value; 
     first = false; 
     } else { 
     if (value.CompareTo(min) < 0) min = value; 
     if (value.CompareTo(max) > 0) max = value; 
     } 
    } 
    } 

} 

用法:

double min, max; 
SliceX(numbers, 0).GetMinMax(out min, out max); 
+0

謝謝你,我已經做了類似的事情,但我想知道如果C#已經有這樣的方法。畢竟他們可能會更有效率,也會通過該方法減少我的代碼。 – phil13131

+0

@ phil13131:不,沒有什麼內置的切片數組。 – Guffa

+0

好的,謝謝,我剛剛試過你的方法和上面的那個,接受另一個,因爲它更快。但我學到了一些關於IEnumerable的東西,感謝你=) – phil13131

2

你在找這樣的嗎?

double[, ,] numbers = new double[2, 2, 2]; 

numbers[0, 0, 0] = 0; 
numbers[0, 0, 1] = 1; 
numbers[0, 1, 0] = 2; 
numbers[0, 1, 1] = 3; 
numbers[1, 0, 0] = 4; 
numbers[1, 0, 1] = 5; 
numbers[1, 1, 0] = 6; 
numbers[1, 1, 1] = 7; 

double[] xmax = new double[numbers.GetLength(0)]; 
double[] ymax = new double[numbers.GetLength(1)]; 
double[] zmax = new double[numbers.GetLength(2)]; 

for (int x = 0; x < xmax.Length; x++) xmax[x] = int.MinValue; 
for (int y = 0; y < ymax.Length; y++) ymax[y] = int.MinValue; 
for (int z = 0; z < zmax.Length; z++) zmax[z] = int.MinValue; 

for (int x = 0; x < xmax.Length; x++) 
    for (int y = 0; y < ymax.Length; y++) 
     for (int z = 0; z < zmax.Length; z++) 
     { 
      xmax[x] = Math.Max(xmax[x], numbers[x, y, z]); 
      ymax[y] = Math.Max(ymax[y], numbers[x, y, z]); 
      zmax[z] = Math.Max(zmax[z], numbers[x, y, z]); 
     } 

// xmax == { 3, 7 } 
// ymax == { 5, 7 } 
// zmax == { 6, 7 } 
+0

它看起來完全像我需要的東西,非常感謝你!我不知道類Enumerate,但我會讀它。 輸出正是我所期望的。你能解釋一下輸入'x:i'等等的含義嗎?我從來沒有見過。 – phil13131

+0

你的代碼突然改變了,你的舊方法消失了,你取而代之。我看到你簡單地循環它,你的舊回答發生了什麼? – phil13131

+0

基於Enumerable的解決方案很好,但是這更簡單,更高效。 – dtb