如何返回具有C#中最大元素的数组?
我有多个int数组:如何返回具有C#中最大元素的数组?,c#,arrays,algorithm,linq,C#,Arrays,Algorithm,Linq,我有多个int数组: 1) [1 , 202,4 ,55] 2) [40, 7] 3) [2 , 48 ,5] 4) [40, 8 ,90] 我需要得到在所有位置都有最大数量的数组。在我的例子中,这将是数组4。说明: 数组#2、#4在第一个位置的数量最大,因此在第一次迭代后,将返回这两个数组([40,7]和[40,8,90]) 现在,在比较上一次迭代返回的数组的第二个位置之后,我们将得到数组#4,因为8>7 等等 你能建议一个有效的算法吗?与Linq合作会更好 更新 长度没有限制,但只
1) [1 , 202,4 ,55]
2) [40, 7]
3) [2 , 48 ,5]
4) [40, 8 ,90]
我需要得到在所有位置都有最大数量的数组。在我的例子中,这将是数组4。说明:
- 数组#2、#4在第一个位置的数量最大,因此在第一次迭代后,将返回这两个数组([40,7]和[40,8,90])
- 现在,在比较上一次迭代返回的数组的第二个位置之后,我们将得到数组#4,因为8>7
- 等等
但是,如果您打算使用红黑BST,我建议您首先掌握常用的BST。LINQ效率不高(例如,请参阅)。但是,它允许非常好的可读性。如果您确实需要比LINQ提供的性能更好的性能,那么您应该在不使用LINQ的情况下编写代码。然而,在知道需要优化之前,不应该进行优化 这不是专门针对性能进行的调整,而是针对您的问题的清晰易读的解决方案:
static int[] FindLargestArray(int[][] arrays)
{
for (int i = 0; arrays.Length > 1 && i < arrays.Max(x => x.Length); i++)
{
var maxVal = arrays.Where(x => i < x.Length).Max(x => x[i]);
arrays = arrays.Where(x => i < x.Length && x[i] == maxVal).ToArray();
}
return arrays[0]; //if more than one array, they're the same, so just return the first one regardless
}
static int[]FindLargestArray(int[]]数组)
{
对于(inti=0;arrays.Length>1&&ix.Length);i++)
{
var maxVal=arrays.Where(x=>ix[i]);
arrays=arrays.Where(x=>i
根据具体情况,这种方法的性能可能已经足够好了。看起来像是一个可以通过递归解决的问题
public void GetMax()
{
var matrix = new[]
{
new[] {1, 202, 4, 55},
new[] {40, 7},
new[] {2, 48, 5},
new[] {40, 8, 90}
};
var result = GetMaxRecursive(matrix).FirstOrDefault();
}
private static int[][] GetMaxRecursive(int[][] matrix, int level = 0)
{
// get max value at this level
var maxValue = matrix.Max(array => array.Length > level ? int.MinValue : array[level]);
// get all int array having max value at this level
int[][] arraysWithMaxValue = matrix
.Where(array => array.Length > level && array[level] == maxValue)
.ToArray();
return arraysWithMaxValue.Length > 1
? GetMaxRecursive(arraysWithMaxValue, ++level)
: arraysWithMaxValue;
}
我将采用传统的面向对象方法并创建一个包装器:
public class SpecialArray<T> : IComparable<SpecialArray<T>>
where T : IComparable
{
public T[] InternalArray { get; private set; }
public SpecialArray(T[] array)
{
InternalArray = array;
}
public int CompareTo(SpecialArray<T> other)
{
int minLength = Math.Min(InternalArray.Length, other.InternalArray.Length);
for ( int i = 0; i < minLength; i++ )
{
int result = InternalArray[i].CompareTo(other.InternalArray[i]);
if ( result != 0 )
return result;
}
return 0;
}
}
公共类SpecialArray:IComparable
其中T:i可比较
{
公共T[]内部数组{get;私有集;}
公共专用数组(T[]数组)
{
内部数组=数组;
}
公共int比较(特殊RAY其他)
{
int minLength=Math.Min(InternalArray.Length,other.InternalArray.Length);
对于(int i=0;i
然后您可以像这样搜索max:
var list = new[]
{
new SpecialArray<int>(new[] {1, 202, 4, 55}),
new SpecialArray<int>(new[] {40, 7}),
new SpecialArray<int>(new[] {2, 48, 5}),
new SpecialArray<int>(new[] {40, 8, 90})
};
var max = list.Max();
var list=new[]
{
新的特殊射线(新[{1,202,4,55}),
新的SpecialArray(新[]{40,7}),
新的特殊射线(新[{2,48,5}),
新的特殊射线(新[{40,8,90})
};
var max=list.max();
找到要比较的索引
排除第三个索引,因为没有可比较的内容,
i、 e.第一个阵列中只有55个:
var maxElementsCount = allArrays.GroupBy(p => p.Length)
// Find 2 at least
.Where(p => p.Count() > 1)
// Get the maximum
.OrderByDescending(p => p.Count())
.First().Key;
// 0, 1, 2
var indexes = Enumerable.Range(0, maxElementsCount);
获取切片:
var slices = indexes.Select(i =>
allArrays.Select((array, arrayNo) => new
{
ArrayNo = arrayNo,
// null if the element doesn't exist
Value = i < array.Length ? array[i] : (int?)null
}))
.ToArray();
完全没有Linq的东西:
public static List<int[]> FindTheHighestArrays(List<int[]> lst)
{
List<KeyValuePair<int[], int>> temp = new List<KeyValuePair<int[], int>>();
List<int[]> retList = lst;
lst.Sort((x, y) => x.Length.CompareTo(y.Length));
int highestLenght = lst[lst.Count - 1].Length;
for (int i = 0; i < highestLenght; i++)
{
temp.Clear();
foreach (var item in retList)
{
if (item.Length <= i)
continue;
temp.Add(new KeyValuePair<int[], int>(item, item[i]));
}
temp.Sort((x, y) => x.Value.CompareTo(y.Value));
retList.Clear();
retList.AddRange(temp.FindAll(kvp => kvp.Value == temp[temp.Count - 1].Value).ConvertAll(f => f.Key));
if (retList.Count == 1)
return retList;
}
return retList;
}
公共静态列表查找HighestArray(列表lst)
{
列表温度=新列表();
列表retList=lst;
lst.Sort((x,y)=>x.Length.CompareTo(y.Length));
int highestLenght=lst[lst.Count-1]。长度;
对于(int i=0;ikvp.Value==temp[temp.Count-1].Value.).ConvertAll(f=>f.Key));
如果(retList.Count==1)
返回列表;
}
返回列表;
}
上面的函数返回最高的int数组列表。例如,如果您尝试
1) [1,202,4,55]
2) [1,202,4,55]
函数返回两个数组,因为它们都是最高的。如果在这种情况下只需要一个数组,那么只需更改返回类型并返回列表的第一个元素即可
你可以这样称呼它:
int[] a = new int[] { -1, 31, 90 };
int[] b = new int[] { -1, 31, 89 };
int[] c = new int[] { 0, 0, 90 };
List<int[]> lst = new List<int[]>() { a, b, c };
var highestArrays = FindTheHighestArrays(lst);
int[]a=新的int[]{-1,31,90};
int[]b=新的int[]{-1,31,89};
int[]c=新的int[]{0,0,90};
List lst=新列表(){a,b,c};
var HighestArray=找到的HighestArray(lst);
a)不是一个“高效”的程序,但很容易编写一行程序。
b) 通过实现“IComparer”实现更好的方法`
公共类阵列比较程序:IComparer
{
公共整数比较(整数[]x,整数[]y)
{
对于(int i=0;iy[i])返回1;
如果(x[i]x,新的ArrayComparer())
.First();
c) 最好的
var arrays=newint[][{arr1,arr2,arr3,arr4};
var max3=数组[0];
ArrayComparer comparer=新的ArrayComparer();
for(int i=1;i0)max3=arrays[i];
}
d) 扩展“Max”的通用版本
var max4=newint[][{arr
// Get the result array no
var arrayNumber = maxValues.GroupBy(p => p.ArrayNo)
.OrderByDescending(p => p.Count())
.First().Key;
var res = allArrays[arrayNumber];
public static List<int[]> FindTheHighestArrays(List<int[]> lst)
{
List<KeyValuePair<int[], int>> temp = new List<KeyValuePair<int[], int>>();
List<int[]> retList = lst;
lst.Sort((x, y) => x.Length.CompareTo(y.Length));
int highestLenght = lst[lst.Count - 1].Length;
for (int i = 0; i < highestLenght; i++)
{
temp.Clear();
foreach (var item in retList)
{
if (item.Length <= i)
continue;
temp.Add(new KeyValuePair<int[], int>(item, item[i]));
}
temp.Sort((x, y) => x.Value.CompareTo(y.Value));
retList.Clear();
retList.AddRange(temp.FindAll(kvp => kvp.Value == temp[temp.Count - 1].Value).ConvertAll(f => f.Key));
if (retList.Count == 1)
return retList;
}
return retList;
}
int[] a = new int[] { -1, 31, 90 };
int[] b = new int[] { -1, 31, 89 };
int[] c = new int[] { 0, 0, 90 };
List<int[]> lst = new List<int[]>() { a, b, c };
var highestArrays = FindTheHighestArrays(lst);
var arr1 = new int[] { 1, 202, 4, 55 };
var arr2 = new int[] { 40, 7 };
var arr3 = new int[] { 2, 48, 5 };
var arr4 = new int[] { 40, 8, 90 };
var max = new int[][] { arr1, arr2, arr3, arr4 }
.Select(arr => new {
IArray = arr,
SArray = String.Join("",arr.Select(i => i.ToString("X8")))
})
.OrderByDescending(x => x.SArray)
.First()
.IArray;
public class ArrayComparer : IComparer<int[]>
{
public int Compare(int[] x, int[] y)
{
for(int i=0;i < Math.Min(x.Length,y.Length);i++)
{
if (x[i] > y[i]) return 1;
if (x[i] < y[i]) return -1;
}
return x.Length - y.Length;
}
}
var max2 = new int[][] { arr1, arr2, arr3, arr4 }
.OrderByDescending(x => x, new ArrayComparer())
.First();
var arrays = new int[][] { arr1, arr2, arr3, arr4 };
var max3 = arrays[0];
ArrayComparer comparer = new ArrayComparer();
for (int i = 1; i < arrays.Length; i++)
{
if(comparer.Compare(arrays[i],max3)>0) max3 = arrays[i];
}
var max4 = new int[][] { arr1, arr2, arr3, arr4 }
.Max(new SOExtensions.Comparer<int>())
.ToArray();
public static class SOExtensions
{
public static IEnumerable<T> Max<T>(this IEnumerable<IEnumerable<T>> lists, IComparer<IEnumerable<T>> comparer)
{
var max = lists.First();
foreach (var list in lists.Skip(1))
{
if (comparer.Compare(list, max) > 0) max = list;
}
return max;
}
public class Comparer<T> : IComparer<IEnumerable<T>> where T: IComparable<T>
{
public int Compare(IEnumerable<T> x, IEnumerable<T> y)
{
foreach(var ab in x.Zip(y,(a,b)=>new{a,b}))
{
var res=ab.a.CompareTo(ab.b);
if (res != 0) return res;
}
return x.Count() - y.Count();
}
}
}