用成对的有序值填充多维数组
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)
如您所见,输出与您的示例输出不完全匹配,但根据您似乎想要的规则它是有效的。根据输入的顺序,输出会有所不同,因为存在多个有效结果集。如果我的任何假设有误,请告诉我。
我必须在网站上以 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)
如您所见,输出与您的示例输出不完全匹配,但根据您似乎想要的规则它是有效的。根据输入的顺序,输出会有所不同,因为存在多个有效结果集。如果我的任何假设有误,请告诉我。