[英]How does this code remove duplicates from a sorted array?
如果我通過在若干,陣列2, 3, 3, 3, 1
,例如。 它刪除了重復的3,但為什么呢? 結果是123(由於排序方法,它應該是這樣的)。
Sortering.sorterHeltallstabell(tab)
只對我的代碼進行排序,而其余的則刪除重復的代碼。 它會在刪除重復項之前進行排序。
為什么在將代碼傳遞給方法時,此代碼會刪除數組的重復項?
public static int[] utenDubletter(int[] tab){
Sortering.sorterHeltallstabell(tab);
if (tab.length < 2)
return tab;
//why does this code remove duplicates?
int j = 0;
int i = 1;
while (i < tab.length) {
if (tab[i] == tab[j]) {
i++;
} else {
j++;
tab[j] = tab[i];
i++;
}
}
int[] B = Arrays.copyOf(tab, j + 1);
return B;
}
挖掘這個模擬:
Start
[1, 1, 1, 2, 2, 2, 3]
j i
Duplicate found (tab[i] == tab[j]), move i over 1 (i++)
[1, 1, 1, 2, 2, 2, 3]
j i
Duplicate found, move i over 1
[1, 1, 1, 2, 2, 2, 3]
j i
Non-duplicate (else); adding 1 to j (j++),
copying element i to el j (tab[j] = tab[i]),
adding 1 to i (i++)
[1, 2, 1, 2, 2, 2, 3]
j i
Duplicate found, move i over 1
[1, 2, 1, 2, 2, 2, 3]
j i
Duplicate found, move i over 1
[1, 2, 1, 2, 2, 2, 3]
j i
Non-duplicate; adding 1 to j, copying i to j, adding 1 to i
[1, 2, 3, 2, 2, 2, 3]
j i
i == tab.length, so stop
Copy first 3 elements of array (up to j) to result
(int[] B = Arrays.copyOf(tab, j + 1)) and return it
這是因為下面的代碼
if (tab[i] == tab[j])
迭代排序的數組,跳過重復的元素,然后將每個唯一元素向前復制到數組的前部,就在已經掃描過的(並且已知是唯一元素)之后。 然后它只保留數組的前部。
單步執行代碼:
if (tab.length < 2)
return tab;
int j = 0;
int i = 1;
方法得到輸入:[1,1,1,2,2,2,3],是排序的(因為輸入已經在這個例子中排序,沒有變化),tab大於2,所以不要返回。 j被賦值為0 i被賦值為1
while (i < tab.length) { ... }
i(為1)小於標簽長度(即7)。 輸入循環時:
if (tab[i] == tab[j]) {
i++;
} else {
j++;
tab[j] = tab[i];
i++;
}
迭代1:tab [i],它是tab [1],它是1,與tab [j]進行比較,tab [j]是tab [0],它是1.它們相等,所以i遞增。 我現在2歲。
迭代2:tab [i](tab [2]或1)與tab [j](tab [0]或1)進行比較。 他們是平等的,所以我增加了。 我現在3歲。
迭代3:tab [i](tab [3]或2)與tab [j](tab [0]或1)進行比較。 他們不平等。 j遞增,現在為1. tab [j](tab [1])被賦值tab [i](tab [3])的值。 tab現在是[1,2,1,2,2,2,3]。 我增加了,現在是4。
迭代4:tab [i](tab [4]或2)與tab [j](tab [1]或2)進行比較。 他們是平等的,所以我增加了。 我現在5歲。
迭代5:tab [i](tab [5]或2)與tab [j](tab [1]或2)進行比較。 他們是平等的,所以我增加了。 我現在6歲。
迭代6:tab [i](tab [6]或3)與tab [j](tab [1]或2)進行比較。 他們不平等。 j遞增,現在為2. tab [j](tab [2])被賦值tab [i](tab [6])的值。 選項卡現在是[1,2,3,2,2,2,3]。 我增加了,現在是7。
我現在不再小於tab的長度,我們退出while循環。
int[] B = Arrays.copyOf(tab, j + 1);
return B;
通過從第一個元素開始將tab復制到長度j + 1或3來創建B. B現在是[1,2,3]。
方法按預期返回[1,2,3]。
很明顯,這條線
if (tab[i] == tab[j])
如果兩個連續的元素相同,則可以跳過數組的元素。
對於此代碼的重復刪除部分,有一些重要的注意事項。
它實際上是在確定重復的過程中覆蓋數組的內容。 它使用數組的前部(先前已經檢查過)來存儲非重復項的內容。 由於Java按值傳遞對象(特別是引用值),因此對參數的本地副本的更改不會在調用方法中傳播回來。 對於通過引用傳遞對象的語言(如C#),情況並非如此,因此該算法無法在那里工作。
此算法取決於對數組進行排序的事實將所有相同的副本放入單個連續的索引塊中。 這可以保證所有未來的元素永遠不會匹配以前在多次迭代之前被覆蓋的東西(因為它至少是當前最大值的大小,否則數組實際上沒有正確排序)。
大力評論解釋
public static int[] utenDubletter(int[] tab){
//sort the array
Sortering.sorterHeltallstabell(tab);
//There must be at least 2 elements for any duplicate to exist
if (tab.length < 2)
return tab;
int j = 0; //index of the largest element in the new array found so far
int i = 1; //index of the current index of the array being checked
while (i < tab.length) {
//if it's a duplicate
if (tab[i] == tab[j]) {
i++; //just skip this element and check the next one
} else {
j++; //since this number does not exist in the new array make space for it
tab[j] = tab[i]; //record this new element
//we have checked this element (with i) before this
//so we don't need to keep it around any longer
i++; //move onto the next element
}
}
int[] B = Arrays.copyOf(tab, j + 1); //copy only the elements that we actually
//manually overwrote. Since arrays are
//0-indexed, add one to the final index (j)
//for the number of elements in our new array.
return B;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.