我有一个二维整数数组。行和列信息(数字的位置)对我来说很重要。所以,我不想对数组(实际上是矩阵)排序。如何从这个二维数组中找到最高的5值?
这是我的密码:
for (int row = 0; row < matirx.length; row++) {
for (int col = 0; col < matirx[row].length; col++) {
if (matirx[row][col] > maxValue) {
maxValue = matirx[row][col];
}
}
}
6条答案
按热度按时间i34xakig1#
您可以使用以下方法,这将给您带来以下好处:
保持非常简单的逻辑,因为您需要最高的5个值,并且不会丢失现有数组的任何索引位置/顺序,
用这个你会有更好的表现,
干净的代码。
输出:
oalqel3c2#
无需对数组本身进行排序,就可以
sorted
此数组上的流。或者可以实现一种按降序排列的选择排序。这两个代码示例执行相同的操作—在2d数组中查找前5个最高的不同值(如果存在):另请参见:数组的选择排序
mhd8tkvw3#
对于java8流,可以使用这(一)行代码来完成。它将保持原始矩阵不变。
qojgxg4l4#
首先,我选择了一个与其他答案非常相似的streams解决方案。我不喜欢拳击和拆箱的变化,但自从
IntStream
没有一个奇特的方法可以用Comparator
开箱即用IntStream
必须转换成Stream
以便按相反的顺序对值进行排序。我不认为归还一张支票很重要int[]
数组,因为我们只对值感兴趣。如果你想让他们
int[]
相反,请看shadow.sabre使用mapToInt()
你要怎么做。虽然streams解决方案非常整洁,看起来也很干净,但我觉得问题其实只是为了得到一组最高的值,所以将它们插入到一个标准的java应用程序中
Set
对我来说很有意义。我首先将值插入到集合中,直到其中有5个元素。然后我检查新值是否高于最低值,如果是,则在插入新值时删除最低值。使用时很容易找到最低值TreeSet
因为这是一个有序的集合。诀窍是还要检查新值是否已经在集合中。如果集合中已经有5,4,3,2,1,并且新值是5,那么我不想删除最小值1,因为添加新值实际上不会向集合中添加任何新元素。还记得吗
Set
不能包含重复值:请注意,此解决方案显然从不包含相同的值,而是始终包含顶部不同的值。
通过查看集合解决方案,可以很容易地添加跟踪矩阵中的值的位置的附加功能。我创建了一个类,
Element
,以包含值及其位置。矩阵中要插入到TreeSet
创建为Element
.这个
Element
两个都需要implement Comparable
或者TreeSet
必须用Comparator
以便对元素进行排序。这个例子Element
两者都有,我只是用了static Comparator
在执行compareTo(Element that)
使之成为Comparable<Element>
. 通常情况下,您会使用getter实现带有私有字段的类来获取值,但为此,似乎有点冗长。使田地final
也确保了类是不变的,所以我对它毫无顾忌。由于比较是使用值和位置进行的,因此矩阵中的每个元素都是不同的:
如果
Element
没有执行Comparable
接口,这将是TreeSet
:TreeSet<Element> maxElement = new TreeSet<>(Element.comparator);
但是自从Element
是否实现Comparable
接口,集合实现可以在没有它的情况下初始化:注意,因为每个元素都是不同的,所以不需要同时检查新值是否还不在集合中。
使用给定的输入运行三个解决方案:
..给出:
但是性能呢。。?
这三种不同的实现让我对性能感到疑惑,所以我添加了一个方法来计时执行:
运行了三种解决方案:
…给出这个结果:
似乎这三种解决方案的性能大致相同。streams解决方案似乎稍微慢一点。这个
Set
解决方案看起来很有前景,希望使用Element
似乎要付出代价。但为了更深入地研究它,我决定在一个更大的矩阵上运行它们,我使用随机整数构建这个矩阵:使用10000 x 10000矩阵运行测试:
..给出了这个结果:
在这里,streams解决方案似乎非常慢!这个
Element
解决方案是两者的赢家Set
解决。我想是因为Element
只有在需要插入到Set
它正在做一个直线上升int
比较,而另一个Set
解决方案是每次比较值时取消装箱。不过,我没有进一步验证我的假设。我对这个线程中其他解决方案的好奇心也让我测试了这些。试验溶液为:
阿文德库马尔阿维纳什的回答
anurag jain的回答
迈克尔·查蒂斯卡齐的回答
在小型和大型阵列上运行测试:
…给出了这些结果:
似乎使用流的解决方案一点性能都不高。MichaelChatiskatzi的解决方案是迄今为止性能更好的解决方案。
所有代码
如果你想自己运行,这里有一个复制粘贴运行的完整类:
vcudknz35#
让
MAX_N = 5
.查找
count
作为matrix[][]
.创建
flattened = new int[count]
把所有的元素都填满matrix[][]
.create max=new int[max\n]以存储最大n个数字。另外,创建maxpos=newint[max\n]来存储最大数字的位置。
回路
MAX_N
在每次迭代中,假设flattened[0]
是最大的数字。如果
flattened[j] >= max[i]
,检查位置,j
已处理。如果未分配flattened[j]
至max[i]
以及j
至maxPos[i]
.演示:
输出:
rlcwz9us6#
既然这个问题又有了答案,我将发表我的评论。
我没有在同一个矩阵上迭代多次,而是填充
int[] highestNumbers
与Integer.MIN_VALUE
,在矩阵上迭代一次,并通过更新highestNumbers
然后分类。输出: