这是我的代码,用于查找数字数组中的最大数字,但我似乎无法理解如何获取前5个数字并将它们存储在数组中,然后检索它们
以下是代码:
public class Max {
public static void main (String[] args)
{
int i;
int large[]=new int[5];
int array[] = {33,55,13,46,87,42,10,34,43,56};
int max = array[0]; // Assume array[0] to be the max for time-being
//Looping n-1 times, O(n)
for( i = 1; i < array.length; i++) // Iterate through the First Index and compare with max
{
// O(1)
if( max < array[i])
{
// O(1)
max = array[i];// Change max if condition is True
large[i] = max;
}
}
for (int j = 0; j<5; j++)
{
System.out.println("Largest 5 : "+large[j]);
}
System.out.println("Largest is: "+ max);
// Time complexity being: O(n) * [O(1) + O(1)] = O(n)
}
}
我正在使用一个数组存储5个数字,但是当我运行它时,它不是我想要的。 任何人都可以帮我解决这个问题吗?
答案 0 :(得分:14)
从较大的集合中检索前n项的最佳数据结构是 min / max heap ,相关的抽象数据结构称为优先级队列。 Java有一个无限制的PriorityQueue
,它基于堆结构,但没有专门用于基本类型的版本。它可以通过添加外部逻辑用作有界队列,有关详细信息,请参阅this comment。
Apache Lucene有一个有界优先级队列的实现:
这是一个专门用于整理的简单修改:
/*
* Original work Copyright 2014 The Apache Software Foundation
* Modified work Copyright 2015 Marko Topolnik
*
* Licensed under the Apache License, Version 2.0 (the "License");
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** A PriorityQueue maintains a partial ordering of its elements such that the
* worst element can always be found in constant time. Put()'s and pop()'s
* require log(size) time.
*/
class IntPriorityQueue {
private static int NO_ELEMENT = Integer.MIN_VALUE;
private int size;
private final int maxSize;
private final int[] heap;
IntPriorityQueue(int maxSize) {
this.heap = new int[maxSize == 0 ? 2 : maxSize + 1];
this.maxSize = maxSize;
}
private static boolean betterThan(int left, int right) {
return left > right;
}
/**
* Adds an int to a PriorityQueue in log(size) time.
* It returns the object (if any) that was
* dropped off the heap because it was full. This can be
* the given parameter (in case it isn't better than the
* full heap's minimum, and couldn't be added), or another
* object that was previously the worst value in the
* heap and now has been replaced by a better one, or null
* if the queue wasn't yet full with maxSize elements.
*/
public void consider(int element) {
if (size < maxSize) {
size++;
heap[size] = element;
upHeap();
} else if (size > 0 && betterThan(element, heap[1])) {
heap[1] = element;
downHeap();
}
}
public int head() {
return size > 0 ? heap[1] : NO_ELEMENT;
}
/** Removes and returns the least element of the PriorityQueue in log(size)
time. */
public int pop() {
if (size > 0) {
int result = heap[1];
heap[1] = heap[size];
size--;
downHeap();
return result;
} else {
return NO_ELEMENT;
}
}
public int size() {
return size;
}
public void clear() {
size = 0;
}
public boolean isEmpty() {
return size == 0;
}
private void upHeap() {
int i = size;
// save bottom node
int node = heap[i];
int j = i >>> 1;
while (j > 0 && betterThan(heap[j], node)) {
// shift parents down
heap[i] = heap[j];
i = j;
j >>>= 1;
}
// install saved node
heap[i] = node;
}
private void downHeap() {
int i = 1;
// save top node
int node = heap[i];
// find worse child
int j = i << 1;
int k = j + 1;
if (k <= size && betterThan(heap[j], heap[k])) {
j = k;
}
while (j <= size && betterThan(node, heap[j])) {
// shift up child
heap[i] = heap[j];
i = j;
j = i << 1;
k = j + 1;
if (k <= size && betterThan(heap[j], heap[k])) {
j = k;
}
}
// install saved node
heap[i] = node;
}
}
您实现betterThan
的方式决定它是表现为最小还是最大堆。这就是它的用法:
public int[] maxN(int[] input, int n) {
final int[] output = new int[n];
final IntPriorityQueue q = new IntPriorityQueue(output.length);
for (int i : input) {
q.consider(i);
}
// Extract items from heap in sort order
for (int i = output.length - 1; i >= 0; i--) {
output[i] = q.pop();
}
return output;
}
这种方法的表现与用户 rakeb.void 的简单线性扫描表达了一些兴趣。这些是与输入大小相关的结果size
,总是在寻找16个顶级元素:
Benchmark (size) Mode Cnt Score Error Units
MeasureMinMax.heap 32 avgt 5 270.056 ± 37.948 ns/op
MeasureMinMax.heap 64 avgt 5 379.832 ± 44.703 ns/op
MeasureMinMax.heap 128 avgt 5 543.522 ± 52.970 ns/op
MeasureMinMax.heap 4096 avgt 5 4548.352 ± 208.768 ns/op
MeasureMinMax.linear 32 avgt 5 188.711 ± 27.085 ns/op
MeasureMinMax.linear 64 avgt 5 333.586 ± 18.955 ns/op
MeasureMinMax.linear 128 avgt 5 677.692 ± 163.470 ns/op
MeasureMinMax.linear 4096 avgt 5 18290.981 ± 5783.255 ns/op
结论:针对堆方法的常数因素非常低。盈亏平衡点大约是70-80个输入元素,从那时起,简单的方法就会急剧下降。请注意,常量因子源于按排序顺序提取项目的最终操作。如果不需要这样(即,只有 set 的最佳项目就足够了),我们可以直接检索内部heap
数组并忽略heap[0]
元素算法不使用。在这种情况下,即使对于最小的输入大小(我用32个中的4个顶部元素进行测试),这个解决方案也会像 rakib.void 那样胜出。
答案 1 :(得分:9)
请查看以下代码:
public static void main(String args[]) {
int i;
int large[] = new int[5];
int array[] = { 33, 55, 13, 46, 87, 42, 10, 34, 43, 56 };
int max = 0, index;
for (int j = 0; j < 5; j++) {
max = array[0];
index = 0;
for (i = 1; i < array.length; i++) {
if (max < array[i]) {
max = array[i];
index = i;
}
}
large[j] = max;
array[index] = Integer.MIN_VALUE;
System.out.println("Largest " + j + " : " + large[j]);
}
}
注意:如果您不想更改输入的数组,请复制它并对复制的数组执行相同的操作。
我得到以下输出:
最大0:87
最大1:56
最大2:55
最大3:46
最大4:43
答案 2 :(得分:3)
这是一个简单的解决方案,我很快就被淘汰了
public class Main {
public static void main(String args[]) {
int i;
int large[] = new int[5];
int array[] = { 33, 55, 13, 46, 87, 42, 10, 34, 43, 56 };
for (int j = 0; j < array.length; j++) {
for (i = 4; i >= 0; i--) {
if (array[j] > large[i]) {
if (i == 4) {
large[i] = array[j];
}
else{
int temp = large[i];
large[i] = array[j];
large[i+1] = temp;
}
}
}
}
for (int j = 0; j<5; j++)
{
System.out.println("Largest "+ j + ":"+ large[j]);
}
}
}
答案 3 :(得分:2)
排序,正则表达式,复杂的数据结构都很好,使编程变得简单。但是,我现在经常看到它们被滥用,没有人不得不怀疑:
即使计算机在过去几十年中变得<强>数千倍,感知性能仍然不仅不会增长,而且实际上减慢。一旦进入终端应用程序,即使在Windows 3.11或Windows 98或Gnome 1中,您也可以获得即时反馈,您通常会从您的计算机获得即时反馈。
但似乎越来越受欢迎的不仅是使用大锤来破解坚果,而且甚至是使用蒸汽锤的小麦玉米。
对于这么小的问题,你不需要friggin'排序或复杂的数据结构。不要让我调用Z̴̝̻̹̣̥͎A̞̭̞̩̠̝͢L̛̤̥͟͜G͘҉̯̯̼̺O̦͈͙̗͎͇̳̞̕͡。我不能接受它,即使我手头没有Java编译器,这里是我对C ++的看法(但也适用于Java)。
基本上,它将您的5个最大值初始化为可能的最小整数值。然后,它会浏览您的数字列表,对于每个数字,它会查找您的最大值以查看它是否有位置。
#include <vector>
#include <limits> // for integer minimum
#include <iostream> // for cout
using namespace std; // not my style, I just do so to increase readability
int main () {
// basically, an array of length 5, initialized to the minimum integer
vector<int> maxima(5, numeric_limits<int>::lowest());
// your numbers
vector<int> numbers = {33, 55, 13, 46, 87, 42, 10, 34, 43, 56};
// go through all numbers.
for(auto n : numbers) {
// find smallest in maxima.
auto smallestIndex = 0;
for (auto m=0; m!=maxima.size(); ++m) {
if (maxima[m] < maxima[smallestIndex]) {
smallestIndex = m;
}
}
// check if smallest is smaller than current number
if (maxima[smallestIndex] < n)
maxima[smallestIndex] = n;
}
cout << "maximum values:\n";
for(auto m : maxima) {
cout << " - " << m << '\n';
}
}
它是rakeb.voids'答案的类似解决方案,但将内部翻转出来并且不必修改输入数组。
仅在适当时使用蒸汽锤。学习算法和数据结构。并知道何时不使用你的功夫。否则,你就会犯下不必要地增加社会浪费并导致整体瘫痪的罪行。
(Marko的Java翻译,适用于零分配的签名)
static int[] phresnel(int[] input, int[] output) {
Arrays.fill(output, Integer.MIN_VALUE);
for (int in : input) {
int indexWithMin = 0;
for (int i = 0; i < output.length; i++) {
if (output[i] < output[indexWithMin]) {
indexWithMin = i;
}
}
if (output[indexWithMin] < in) {
output[indexWithMin] = in;
}
}
Arrays.sort(output);
return output;
}
答案 4 :(得分:1)
作为排序的替代方案,这是逻辑。你找出了代码。
保留到目前为止找到的前X值的列表(或数组)。当然会开始是空的。
对于每个新值(迭代),请检查前X列表。
如果前X列表短于X,则添加值。
如果前X列表已满,请检查新值是否大于任何值。如果是,则从顶部X列表中删除最小值并添加新值。
提示:如果排名前X列表,代码会更好。
答案 5 :(得分:1)
首先,您不能将i
常量与large
数组一起使用。 i
最多为10,而large
长度为5。
为此使用单独的变量,并在添加新值时递增。
其次,此逻辑不检索最大值,您需要完全检查数组,检索最大值并将其添加到数组中。然后你又要了。您可以编写使用large.length
作为条件的第一个循环和使用array.length
的内循环。或者,您可以使用递归。
答案 6 :(得分:1)
如果您不想排序,可以检查较低的数字及其位置并进行更换。 WORKING DEMO HERE
public static void main(String[] args) {
int array[] = {33,55,13,46,87,42,10,34,43,56};
int mArray[] = new int[5];
int j = 0;
for(int i = 0; i < array.length; i++) {
if (array[i] > lower(mArray)) {
mArray[lowerPos(mArray)] = array[i];
}
}
System.out.println(Arrays.toString(mArray));
}
public static int lower(int[] array) {
int lower = Integer.MAX_VALUE;
for (int n : array) {
if (n < lower)
lower = n;
}
return lower;
}
public static int lowerPos(int[] array) {
int lower = Integer.MAX_VALUE;
int lowerPos = 0;
for (int n = 0; n < array.length; n++) {
if (array[n] < lower) {
lowerPos = n;
lower = array[n];
}
}
return lowerPos;
}
输出:
[43, 55, 56, 46, 87]
答案 7 :(得分:1)
这是另一种方法:
public static void main(String args[]){
int i;
int largestSize = 4;
int array[] = {33,55,13,46,87,42,10,34};
// copy first 4 elemets, they can just be the highest
int large[]= Arrays.copyOf(array, largestSize);
// get the smallest value of the large array before the first start
int smallest = large[0];
int smallestIndex = 0;
for (int j = 1;j<large.length;++j) {
if (smallest > large[j]) {
smallest = large[j];
smallestIndex = j;
}
}
// First Loop start one elemnt after the copy
for(i = large.length; i < array.length; i++)
{
// get the smallest value and index of the large array
if(smallest < array[i])
{
large[smallestIndex] = array[i];
// check the next smallest value
smallest = large[0];
smallestIndex = 0;
for (int j = 1;j<large.length;++j) {
if (smallest > large[j]) {
smallest = large[j];
smallestIndex = j;
}
}
}
}
for (int j = 0; j<large.length; j++)
{
System.out.println("Largest 5 : "+large[j]);
}
System.out.println();
System.out.println("Largest is: "+ getHighest(large));
}
private static int getHighest(int[] array) {
int highest = array[0];
for (int i = 1;i<array.length;++i) {
if (highest < array[i]) {
highest = array[i];
}
}
return highest;
}
答案 8 :(得分:1)
你可以用OOp方式正确地做到这一点。这将维护一个提供值列表的n个最大值的列表。
class Largest<T extends Comparable<T>> {
// Largest so far - null if we haven't yet seen that many.
List<T> largest;
public Largest(int n) {
// Build my list.
largest = new ArrayList(n);
// Clear it.
for (int i = 0; i < n; i++) {
largest.add(i, null);
}
}
public void offer(T next) {
// Where to put it - or -1 if nowhere.
int place = -1;
// Must replace only the smallest replaceable one.
T smallest = null;
for (int i = 0; i < largest.size(); i++) {
// What's there?
T l = largest.get(i);
if (l == null) {
// Always replace null.
place = i;
break;
}
if (l.compareTo(next) < 0) {
// Only replace the smallest.
if (smallest == null || l.compareTo(smallest) < 0) {
// Remember here but keep looking in case there is a null or a smaller.
smallest = l;
place = i;
}
}
}
if (place != -1) {
// Replace it.
largest.set(place, next);
}
}
public List<T> get() {
return largest;
}
}
public void test() {
Integer array[] = {33, 55, 13, 46, 87, 42, 10, 34, 43, 56};
Largest<Integer> l = new Largest<>(5);
for (int i : array) {
l.offer(i);
}
List<Integer> largest = l.get();
Collections.sort(largest);
System.out.println(largest);
// Check it.
List<Integer> asList = Arrays.asList(array);
Collections.sort(asList);
asList = asList.subList(asList.size() - largest.size(), asList.size());
System.out.println(asList);
}
对于较大的数字,您可以使用binarySearch
来改进算法,以找到放置新项目的最佳位置,而不是盲目地走遍整个列表。这具有返回已排序列表的额外好处。
class Largest<T extends Comparable<T>> {
// Largest so far - null if we haven't yet seen that many.
List<T> largest;
// Limit.
final int n;
public Largest(int n) {
// Build my list.
largest = new ArrayList(n + 1);
this.n = n;
}
public void offer(T next) {
// Try to find it in the list.
int where = Collections.binarySearch(largest, next, Collections.reverseOrder());
// Positive means found.
if (where < 0) {
// -1 means at start.
int place = -where - 1;
// Discard anything beyond n.
if (place < n) {
// Insert here.
largest.add(place, next);
// Trim if necessary.
if (largest.size() > n) {
largest.remove(n);
}
}
}
}
public List<T> get() {
return largest;
}
}
答案 9 :(得分:1)
尝试:
public static int getMax(int max,int[] arr ){
int pos=0;
//Looping n-1 times, O(n)
for( int i = 0; i < arr.length; i++) // Iterate through the First Index and compare with max
{
// O(1)
if( max < arr[i])
{
// O(1)
max = arr[i];// Change max if condition is True
pos=i;
}
}
arr[pos]=0;
return max;
}
public static void main(String[] args) {
int large[]=new int[10];
int array[] = {33,55,13,46,87,42,10,34,43,56};
int k=0;
for(int i=0;i<array.length;i++){
large[k++]=getMax(0,array);
}
System.out.println("Largest 5 is: "+ Arrays.toString(Arrays.copyOf(large,5)));
}
输出:
Largest 5 is: [87, 56, 55, 46, 43]