[英]Smallest number in array quirk
我試圖解決CodeWars上的一個問題,我發現數組中的數字最小。 這是我目前的代碼:
public class SmallestIntegerFinder {
public int findSmallestInt(int[] args){
int smallest = args[0];
for(int i=1; i < args.length; ++i){
if(args[i] < args[0]){
smallest = args[i];
}
}
return smallest;
}
}
為什么這不起作用? 但是,當我在if語句[0]改變參數傳遞給變量最小它的工作原理。 這兩者有什么區別? 他們都指向args [0]不是嗎?
public class SmallestIntegerFinder {
public int findSmallestInt(int[] args){
int smallest = args[0];
for(int i=1; i < args.length; ++i){
if(args[i] < smallest){
smallest = args[i];
}
}
return smallest;
}
}
我正在使用的測試數組是:{78,56,232,12,11,43}
因為args[0]
是數組中的第一個元素,而smallest
元素是從第一個元素開始的; 它更新為下一個最小值(考慮3,1,2; 2小於3但1小於2)。 您也可以使用Math.min(int, int)
類的
public int findSmallestInt(int[] args) {
int smallest = args[0];
for (int i = 1; i < args.length; ++i) {
smallest = Math.min(smallest, args[i]);
}
return smallest;
}
最小的被賦值為args [0]中的值,它不是指向該內存位置的指針。 改變最小值不會改變args [0]。 因此,在循環中,您總是與args [0]進行比較,而不是到目前為止看到的最低值。
這是不一樣的,
在第一種情況下,您將最小值設為args [i],但再次與args [0]進行比較。 因此,比較的基礎值永遠不會更新。
在第二種情況下,您的基本值將更新為當前最小值,並且您正在與之進行比較,因此您將獲得總體最小值。
使用java-8 。
public static int findSmallestInt(int[] args){
return IntStream.of(args)
.min()
.getAsInt();
}
要么
public static int findSmallestInt(int[] args){
return IntStream.of(args)
.min()
.orElseThrow(IllegalArgumentException::new);
}
其他答案已經向您解釋了為什么您的代碼(不)正常工作:在比較args[i] < args[0]
,您總是與數組的第一個值進行比較。
一句話:如果您使用的是Java 8,那么有一個更易讀的解決方案:
import java.util.stream.IntStream;
public class Test {
public static void main(String[] args) {
int[] array = {78,56,232,12,11,43};
int min = IntStream.of(array).min().getAsInt();
System.out.println("Minimum: "+min);
}
}
你正在做的是將args[0]
的內容復制到smallest
。 arg[0]
和smallest
的內存位置不同。
在第一個代碼塊中,如果第i
個值小於第0
個,則更新smallest
的內容。 更新smallest
只會更新該變量中的值, 而不會更新為args[0]
在第二個代碼塊你都比較和更新, smallest
與值從args[i]
你需要了解當你寫一些像int smallest
東西時會發生什么。 這為該變量分配了一部分新內存。 運行代碼int smallest = 1
將使1
smallest
。
如果你有兩個不同的變量,你將有兩個不同的內存位置,即使你寫smallest = largest
。 所有這一切都是將內容從largest
復制到smallest
。
當您復制對象而不是基本類型時,這可能會造成混淆。
顯然,在原語的情況下,值(例如1
)從一個變量復制到另一個變量。 你最終會得到smallest = 1
和largest = 1
。
說到物體,它有點不同。 在Object smallest = new Object()
的情況下, smallest
不包含Object
,而是包含Object
在內存中的位置。 如果你現在做largest = smallest
你將復制位置,而不是實際對象。
如果你對此感興趣,你可以從我最喜歡的答案之一閱讀更多關於它的信息: Java是“傳遞參考”還是“傳遞價值”?
這是因為做了smallest = args[i];
您正在更新smallest
變量中的smallest
而不是args[0]
。
在第一個解決方案中,您將使用args[0]
比較數組中的每個值,但如果發現任何第i
個元素的值較小,則更新smallest
變量而不是args[0]
。
如果您希望第一個代碼段工作,則應更新args[0]
。
以下是更正后的代碼段:
public class SmallestIntegerFinder {
public int findSmallestInt(int[] args) {
int smallest = args[0];
for(int i=1; i < args.length; ++i) {
if(args[i] < args[0]){
args[0] = args[i];
}
}
return args[0];
}
}
問題是你正在與args [0]進行比較。 你應該與較小的比較,這樣,如果有小於小的東西,它將是新的更小:)
這應該工作:
public static int findSmallestInt(int[] args) {
int smallest = args[0];
for (int i = 1; i < args.length; ++i) {
if (args[i] < smallest ) {
smallest = args[i];
}
}
return smallest;
}
其他答案告訴你為什么第一部分代碼不起作用並提供了很多替代方案,但允許我准確地分解代碼中斷的位置。 我覺得這有助於避免類似的錯誤。
這是您的原始代碼:
public class SmallestIntegerFinder {
public int findSmallestInt(int[] args){
int smallest = args[0];
for(int i=1; i < args.length; ++i){
if(args[i] < args[0]){
smallest = args[i];
}
}
return smallest;
}
}
這是你的意見: {78,56,232,12,11,43}
您的原始代碼在某個點上完美無缺,但最終比較args[i] < args[0]
會導致代碼中斷。
當你的代碼在數組中循環時, smallest
包含正確的值, 11
。 但是由於11
不是數組中的最后一個元素,因此代碼會對43
一次比較。 由於您的比較總是使用args[0] = 56
,因此您的代碼會檢查43
是否小於56
,並且因為它是43
,所以用43
覆蓋smallest
,導致您得到錯誤的值。
將比較更改為args[i] < smallest
可以避免此問題,因為循環的最后一次迭代現在將檢查43
是否小於11
。 因為它不是,你的函數返回正確的值, 11
。
有一個更簡單的解決方案:
final List<Integer> myList = Arrays.asList(78,56,232,12,11,43);
int smallest = myList.stream()
.sorted()
.findFirst()
.get();
System.out.println("Smallest number is "+smallest);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.