簡體   English   中英

計算數組中的int出現次數

[英]Counting Int Occurrences in an Array

我試圖計算一個數組中整數的出現。 通過將在網上找到的一些代碼拼湊在一起,我能夠使它正常工作,但是我並不真正理解它為什么起作用。 我所擁有的是:

int[] hand = {2, 4, 3, 2, 4};
int[] numOccurence = new int[hand.length];


    for (int i = 0; i < hand.length; i++)
        numOccurence[hand[i]]++;

    for (int i = 1; i < numOccurence.length; i++)
        if (numOccurence[i] > 0)
            System.out.println("The number " + i + " occurs " + numOccurence[i] + " times.");

輸出為:數字2出現2次。 數字3出現1次。 數字4出現2次。

此代碼如何正確計算出現次數? 我不知道它是如何實現的。 先感謝您!

這只是有效,因為您很幸運。 嘗試將手形數組中的第二個元素設為5然后看看會發生什么。 這是因為當前hand索引上存在的數字被視為數組numOccurence的索引。 如果數字大於或等於numOccurence的長度, numOccurence獲得ArrayIndexOutOfBoundsException

因此,您可以更好地使用Map ,其中鍵是數字,值是計數。

像這樣的東西:

Map<Integer, Integer> numOccurence = new HashMap<Integer, Integer>();
for (int i = 0; i < hand.length; i++) {
    int cnt = 1;
    if (numOccurence.containsKey(hand[i])) {
        cnt = numOccurence.get(hand[i]);
        cnt++;
    }
    numOccurence.put(hand[i], cnt);
}

此代碼實際上不起作用。 至少它適用於作者的用例,但可能不適用於您的用例。

嘗試使用{2, 4, 99, 2, 4}; 作為hand ,它將失敗。

作者以中找到的號碼hand作為數組的索引numOccurence numOccurence具有以下結構:{nb occ為0 nb occs of 1 ; ...; nb occs of 4 }。 這里99將超出范圍。

創建數組時

int[] numOccurence = new int[hand.length];

它由其默認值填充。 對於基本int,此值為0。

當然,這僅在手的數字小於或等於數組的最大索引(長度為-1)的情況下才有效,否則,它就是ArrayIndexOutOfBound了!

實際上,這是為圖片創建直方圖的方法;)

您創建一個表,您將在其中收集事件。 numOccurence [0]將庫存數量為0 numOccurence [1]將庫存數量為1等。

這就是這樣做的

for (int i = 0; i < hand.length; i++)
    numOccurence[hand[i]]++;

在對應於數字hand [i]的情況下,它會將值加1

所以,如果您先一步一步看,他會把手[0] = 2,所以他會把

numOccurence[2] = numOccurence[2] + 1 ;

與(但編寫起來更快)相同

numOccurence[2]++; 

這種執行計數的方法稱為計數排序

計數排序的優點是速度。 缺點是對大量數字進行排序時需要存儲空間。

代碼中有一個錯誤:

int[] numOccurence = new int[hand.length];

numOccurence必須與列表中的最高編號(而不是列表中的編號)一樣長。 嘗試將數字之一更改為15 ,您將得到一個例外。

首先,代碼是錯誤的。 您應該將numOccurence數組的大小設置為hand數組+ 1的最大值。例如:

int[] hand = {2, 100};
int[] numOccurence[] = new int[101];

(您顯然應該以編程方式找到最大數量)

現在讓我們看一下算法。 它從hand數組中獲取每個數字,將其視為numOccurence索引值,並在hand數組中將該索引處的數字加1。 請注意,默認情況下, numOccurence數組的所有元素numOccurence均為0

int[] hand = {2, 4, 3, 2, 4};
int[] numOccurence = new int[5];

腳步:

i = 0 (什么也沒有發生,因為hand數組中沒有0)

i = 1 (與0相同)

i = 2hand數組中有兩個2 ,所以我們對numOccurence[2] += 1兩次運算,結果為0 +1 + 1 =2。所以我們得到了numOccurence[2] = 2

它會繼續處理從0hand數組中最大數的所有數字(此處為100 )。

代碼遍歷給定的數組hand 它將遇到的每個值作為數組numOccurrence的索引。 對於hand每個n ,這將與hand n發生頻率完全相同,並且每次發生, numOccurrencen個元素都會增加。

因此numOccurrence是一個計數器數組(假設數組元素初始化為0 )。

這種方法的缺點:

  • 分配的計數器數量取決於hand陣列中數字的大小。
  • 如果您的hand數組中的數字分布稀疏,則絕不會使用分配的大部分空間。

另類

您可以通過先整理hands來改進代碼。 在排序數組中,給定數字的所有出現的索引都是連續的,因此您一次掃描排序數組時只需要一個計數器即可編譯頻率。

暫無
暫無

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

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