用成对的有序值填充多维数组

Fill a multidimensional array with pairs of ordered values

我必须在网站上以 4x4 矩阵展示 16 种金融产品。矩阵取代了散点图的表示,其中产品的 returns 在 X 轴中表示,风险在 Y 中表示(它们只是成对的值),因此产品在最左边的位置是次要风险和次要 return 的风险,右上角是主要风险和主要 return 的风险。 为了达到这个结果,我想到了将产品放在一个多维 4x4 数组中,但我不知道如何正确地对值对进行排序。 我尝试了一些排序方法,但没有人给我所需的结果。

这是我想要获得的示例: 采用这十六对值: (3,5)-(2,8)-(7,3)-(4,9)-(3,2)-(4,10)-(6,2)-(1,4)-(5 ,2)-(8,9)-(7,11)-(10,12)-(3,11)-(5,10)-(2,16)-(9,15)

我想按这个顺序显示在矩阵中

Y
^
|(7,3)(8,9)(10,12)(9,15)
|(5,2)(6,2)(5,10)(7,11)
|(3,2)(3,5)(4,9)(4,10)
|(1,4)(2,8)(3,11)(2,16)
|_____________________>X

除非我误解了你的问题,否则在我看来你需要对你的集合进行线性排序(一维),然后呈现它(二维)。数据存储和数据呈现之间存在区别。这是我想出的:

//Sample data to work with
var products = new List<KeyValuePair<string, int>>();
products.Add(new KeyValuePair<string, int>("A", 12));
products.Add(new KeyValuePair<string, int>("B", 23));
products.Add(new KeyValuePair<string, int>("C", 62));
products.Add(new KeyValuePair<string, int>("D", 17));
products.Add(new KeyValuePair<string, int>("E", 11));
products.Add(new KeyValuePair<string, int>("F", 75));
products.Add(new KeyValuePair<string, int>("G", 95));
products.Add(new KeyValuePair<string, int>("H", 24));
products.Add(new KeyValuePair<string, int>("I", 85));
products.Add(new KeyValuePair<string, int>("J", 41));
products.Add(new KeyValuePair<string, int>("K", 76));
products.Add(new KeyValuePair<string, int>("L", 77));
products.Add(new KeyValuePair<string, int>("M", 33));
products.Add(new KeyValuePair<string, int>("N", 81));
products.Add(new KeyValuePair<string, int>("O", 34));
products.Add(new KeyValuePair<string, int>("P", 45));

//Sort the collection
List<KeyValuePair<string, int>> ordered = products.OrderBy(x => x.Value).ToList();

//Put linear results into 2D array (4x4)
var matrix = new KeyValuePair<string, int>[4,4];
for (int i = 0; i < 4; i++)
    for (int j = 0; j < 4; j++)
        matrix[i, j] = ordered[i * 4 + j];

//Write out results
for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
        var c = ordered[i * 4 + j];
        Console.Write(c.Key + ": " + c.Value.ToString() + "    ");
    }
    Console.WriteLine();
}

输出:

E: 11    A: 12    D: 17    B: 23    
H: 24    M: 33    O: 34    J: 41    
P: 45    C: 62    F: 75    K: 76    
L: 77    N: 81    I: 85    G: 95

我正在添加另一个答案,因为第一个答案及其评论是在您添加示例之前,而那个答案已经偏离了。

你的例子很有帮助。看起来你的对中的第一个值是 Y,第二个是 X?如果是这样,那就违反了正常惯例。

看来你的排列潜规则是每列Y(左)值向上增加,X(右)值每行向右增加。重要的是,对于 Y 值,列似乎是独立的,而对于 X 值,行在其他方面是独立的。独立意味着您不关心从一个位置到另一个位置的绝对位置。与 Y 一样,您不关心第三列中的 3 是否低于第一列中的 3。

但是这些规则仍然会产生多个有效的结果集。例如,在您的示例中,(7,3) 和 (6,2) 可以互换,并且上述规则仍然适用。

如果这些潜规则是正确的,请尝试这种广泛的方法:

(1) 将列表放入矩阵,(2) 对所有列进行排序,(3) 对所有行进行排序,(4) 对列和行重复排序几次。

下面是一些代码来说明这一点。因为这只是一个 4x4 矩阵,所以效率并不重要。

public static void Main()
{
    Tuple<int,int>[] pairs = {
        Tuple.Create(3, 5),
        Tuple.Create(2, 8),
        Tuple.Create(7, 3),
        Tuple.Create(4, 9),
        Tuple.Create(3, 2),
        Tuple.Create(4, 10),
        Tuple.Create(6, 2),
        Tuple.Create(1, 4),
        Tuple.Create(5, 2),
        Tuple.Create(8, 9),
        Tuple.Create(7, 11),
        Tuple.Create(10, 12),
        Tuple.Create(3, 11),
        Tuple.Create(5, 10),
        Tuple.Create(2, 16),
        Tuple.Create(9, 15)             
    };

    var matrix = load(pairs); //Put data into a 4x4 matrix, order doesn't matter

    Console.WriteLine("Original input:");
    print(matrix);

    matrix = sort(matrix);

    Console.WriteLine("Ordered output:");
    print(matrix);
}

private static Tuple<int,int>[,] load(Tuple<int,int>[] pairs) {
    var rv = new Tuple<int, int>[4, 4];
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            rv[i, j] = pairs[i * 4 + j];
        }
    }
    return rv;
}

private static Tuple<int, int>[, ] sort(Tuple<int, int>[,] matrix) {
    var rv = matrix;
    for (int i = 0; i < 4; i++) {
        rv = orderCols(rv);
        rv = orderRows(rv);
    }
    return rv;
}

private static Tuple<int,int>[,] orderCols(Tuple<int,int>[,] matrix) {
    for (int c = 0; c < 4; c++) {
        //Convert column to 1D array, sort it, then apply it back
        Tuple<int, int>[] a = new Tuple<int, int>[4];
        for (int r = 0; r < 4; r++) a[r] = matrix[r, c];
        a = a.OrderByDescending(t => t.Item1).ToArray();
        for (int r = 0; r < 4; r++) matrix[r, c] = a[r];
    }
    return matrix;
}

private static Tuple<int,int>[,] orderRows(Tuple<int,int>[,] matrix) {
    for (int r = 0; r < 4; r++) {
        //Convert row to 1D array, sort it, then apply it back
        Tuple<int, int>[] a = new Tuple<int, int>[4];
        for (int c = 0; c < 4; c++) a[c] = matrix[r, c];
        a = a.OrderBy(t => t.Item2).ToArray();
        for (int c = 0; c < 4; c++) matrix[r, c] = a[c];
    }
    return matrix;
}

private static void print(Tuple<int, int>[,] matrix) {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++)
            Console.Write(writeTuple(matrix[i, j]));
        Console.WriteLine();
    }
    Console.WriteLine();
}

private static string writeTuple(Tuple<int, int> t) {
    var a = t.Item1.ToString().PadLeft(2, ' ');
    var b = t.Item2.ToString().PadLeft(2, ' ');
    return String.Format("({0}, {1})  ", a, b);
}

输出:

Original input:
( 3,  5)  ( 2,  8)  ( 7,  3)  ( 4,  9)  
( 3,  2)  ( 4, 10)  ( 6,  2)  ( 1,  4)  
( 5,  2)  ( 8,  9)  ( 7, 11)  (10, 12)  
( 3, 11)  ( 5, 10)  ( 2, 16)  ( 9, 15)  

Ordered output:
( 6,  2)  ( 7,  3)  ( 8,  9)  (10, 12)  
( 5,  2)  ( 4,  9)  ( 7, 11)  ( 9, 15)  
( 3,  2)  ( 3,  5)  ( 5, 10)  ( 4, 10)  
( 1,  4)  ( 2,  8)  ( 3, 11)  ( 2, 16)

如您所见,输出与您的示例输出不完全匹配,但根据您似乎想要的规则它是有效的。根据输入的顺序,输出会有所不同,因为存在多个有效结果集。如果我的任何假设有误,请告诉我。