/ / BigDecimals सूची की एक विशिष्ट मूल्य से तुलना करें और निकटतम मान लौटाएं - java, java-stream, bigdecimal

BigDecimals सूची की तुलना किसी विशिष्ट मान से करें और निकटतम मूल्य - जावा, जावा-स्ट्रीम, bigdecimal लौटें

मेरे पास बिग डेसीमल वैल्यू की सूची है और ए भीविशिष्ट इनपुट भी एक BigDecimal। मैं सूची में मूल्यों के खिलाफ विशिष्ट इनपुट की तुलना करना चाहता हूं और उस मूल्य का चयन करता हूं जो विशिष्ट इनपुट के सबसे करीब है। कोई सुझाव कृपया?

    private static BigDecimal getWageMultiplier(List<BigDecimal> values, BigDecimal valueAmount) {

values.sort(BigDecimal::compareTo);

int index = values.indexOf(valueAmount);

// Check for an exact match and if not get the index of the previous value
if (index == -1) {

// start with the highest index, in case there is no higher value than the previous
index = values.size() - 1;

for (int i = 0; i < values.size(); i++) {
//work out the value from the List<BigDecimal> values that is closest to BigDecimal valueAmount
}
}

int finalIndex = (index);

return finalIndex != -1 ? values.get(finalIndex) : BigDecimal.ZERO;
}

उत्तर:

उत्तर № 1 के लिए 6

आप सूची में दिए गए मूल्य और दिए गए मूल्य के बीच पूर्ण अंतर की तुलना करके इसे प्राप्त कर सकते हैं:

public static BigDecimal findClosest(List<BigDecimal> list, BigDecimal value) {
return list.stream()
.min(Comparator.comparing(a -> value.subtract(a).abs()))
.orElseThrow(() -> new IllegalArgumentException("Empty collection"));
}

जवाब के लिए 0 № 2

हम सूची और उपयोग पर पुनरावृत्ति करके ऐसा कर सकते हैंBigDecimal फ़ंक्शंस जैसे घटाना और abs (निरपेक्ष मूल्य)। निम्नलिखित समाधान O (N) लेता है। नोट: यह समाधान जावा 8 का उपयोग नहीं कर रहा है। निश्चित रूप से हम इसे जावा 8 का उपयोग करके हल कर सकते हैं।

private static BigDecimal getWageMultiplier(List<BigDecimal> values, BigDecimal valueAmount) {

BigDecimal minDifference = values.get(0).subtract(valueAmount).abs();
int index = 0;

for(int i = 1; i < values.size(); i++) {

BigDecimal difference = values.get(i).subtract(valueAmount).abs();

if(difference.compareTo(minDifference) < 0) {
minDifference = difference;
index = i;
}
}

return values.get(index);
}

जवाब के लिए 0 № 3

यहां लंबी सूचियों के लिए एक तेज़ समाधान है, जो आकार को आधे हिस्से में विभाजित करता है:

int getMinDist (List<Integer> values, int target) {
if (values.size () == 1) return values.get (0);
int mid = values.size ()/ 2;
int left= Math.max (0, mid -1);
int v0 = values.get (left);
int v1 = values.get (mid);
// println (left + " " + mid + " | " + v0 + " " + v1);
int av0 = Math.abs (target - v0);
int av1 = Math.abs (v1 - target);
return (av0 <= av1) ? getMinDist (values.subList (0, left+1), target) : getMinDist (values.subList (mid, values.size ()), target);
}

List<Integer> vals = Arrays.asList (1, 3, 5, 9, 17, 18, 19)

-> getMinDist (vals, 16)
2 3 | 5 9
1 2 | 17 18
0 1 | 9 17
|  Expression value is: 17
|    assigned to temporary variable $86 of type int

-> getMinDist (vals, 4)
2 3 | 5 9
0 1 | 1 3
0 1 | 3 5
|  Expression value is: 3
|    assigned to temporary variable $87 of type int

अपने मामले के लिए BigDecimal के साथ int बदलें एक एक्सर्साइज़ के रूप में छोड़ दिया गया है।

सूची को विभाजित करने के बजाय, निचले, ऊपरी के लिए अनुक्रमणिका, 0 से शुरू करके और सूची से शुरू करें। आकार () - 1 शुरुआत में, और भी बेहतर हो सकता है।