簡體   English   中英

查找集合中的最低和最高 NUMBERS

[英]Find the lowest and highest NUMBERS in a collection

我有一個List<BigDecimal>集合,其中包含(為了簡單起見) BigDecimal價格。 我想處理集合並得到:

  1. 都是最高價。
  2. 都是最低價。

說明我的意思

我最初的想法是使用后視法來解決這個問題,以確定數字是在上升還是下降趨勢中移動。 當趨勢發生變化時——確定之前的數字中哪些是“最高”或“最低”價格,然后將它們添加到尊重的List<BigDecimal> lowestPricesList<BigDecimal highestPrices collections。例如,前 3 個點是向上的-trend,但是 4 號將趨勢變為下降趨勢。 所以現在可以確定更改前數字的min/max (0,1,2) 並獲取價格。

我不完全確定這是否是一種幼稚的方法,所以我想知道 java 中是否有解決此問題的最佳方法? 也許圖書館已經可以做到這一點? (最好不要重新發明輪子)

您正在尋找局部最大值(/最小值)。

只需查看當前點是否大於(/小於)其前后的點:

  • 對於局部最大值:

     list.get(i) > list.get(i - 1) && list.get(i) > list.get(i + 1)
  • 對於局部最小值:

     list.get(i) < list.get(i - 1) && list.get(i) < list.get(i + 1)

偽代碼:

for (int i = 1; i < list.size()-1; ++i) {
  if (local maximum) {
    // Add to list of local maxima
  } else if (local minimum) {
    // Add to list of local minima
  }
}

並根據需要處理這兩個端點。

(您也可以使用 (List)Iterators 以對非隨機訪問列表更有效的方式執行此操作,例如LinkedList ;但原理是相同的)。

我決定嘗試實現這一點,盡管我確信我的實現可以改進。 這個想法就像你說的那樣,跟蹤趨勢並在趨勢發生變化時記錄局部最小值或局部最大值。 還有兩個額外的細節需要考慮:首先,最初我們沒有趨勢向上或向下,但第一個值是最小值或最大值,因此除了增加或減少之外,我們還有第三種趨勢可能性:早期; 其次,在循環結束后,我們必須添加最后一項作為最小值或最大值,具體取決於我們完成時趨勢的方向。 請注意,如果價格列表為空,它永遠不會添加 null,因為在這種情況下,趨勢永遠不會從早期發生變化。

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Map;
import java.util.List;

public class Partition {
    public static void main(String[] args) {
        List<String> values = List.of("10.99", "15.99", "19.99", "12.99", "24.99",
            "21.99", "17.99", "11.99", "22.99", "29.99", "35.99", "27.99", "20.99");
        List<BigDecimal> prices = values.stream().map(BigDecimal::new).toList();
        Map<Extrema, List<BigDecimal>> part = new Partition().partitionExtrema(prices);
        System.out.format("Minima: %s%n", part.get(Extrema.MINIMA));
        System.out.format("Maxima: %s%n", part.get(Extrema.MAXIMA));
    }

    public Map<Extrema, List<BigDecimal>> partitionExtrema(List<BigDecimal> prices) {
        Trend trend = Trend.INCHOATE; // intially we don't know if we're going up or down
        List<BigDecimal> maxima = new ArrayList<>();
        List<BigDecimal> minima = new ArrayList<>();
        BigDecimal previous = null;
        for (BigDecimal current : prices) {
            int direction = previous == null ? 0 : current.compareTo(previous);
            if (direction > 0) {
                if (trend != Trend.DECREASING) {
                    minima.add(previous); // switching from decreasing to increasing
                }
                trend = Trend.INCREASING;
            }
            if (direction < 0) {
                if (trend != Trend.INCREASING) {
                    maxima.add(previous); // switching from increasing to decreasing
                }
                trend = Trend.DECREASING;
            }
            previous = current;
        }
        if (trend == trend.INCREASING) {
            maxima.add(previous);
        } else if (trend == trend.DECREASING) {
            minima.add(previous);
        }
        return Map.of(Extrema.MINIMA, minima, Extrema.MAXIMA, maxima);
    }
}

public enum Trend {
    INCREASING,
    DECREASING,
    INCHOATE
}

public enum Extrema {
    MAXIMA,
    MINIMA
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM