יישום אלגוריתמים של ArrayList
הוצג| English | משמעות |
|---|---|
| shift/ʃɪft/ | הזזה |
| delete/dɪˈliːt/ | מחיקה |
| insert/ˈɪnsɜːt/ | הכנסה |
הסרות צמודות חושפות אלמנט שדולק
- התחל עם
[0, 0, 5], הסר את האינדקס 0 ואז גדל את i. האפס השני הזז לאינדקס 0, ולכן לולאת קדימה זו דולקת אותו ומשאירה[0, 5]. - עבור לולאת while קדמית שנלמדה כאן, נשאר באותו אינדקס לאחר הסרה והתקדם רק כאשר שומר על אלמנט. כך היא תסיר את שני האפסים ותסיים עם
[5].
שמור על האינדקס הקדמי הנוכחי לאחר ההסרה
- לאחר
remove(i), כל אלמנט מאוחר יותר מזיז מקום אחד שמאלה. אם אלמנט תופס כעת את i, הוא טרם נבדק; בדוק אותו בפנייה הבאה. - הלולאה למטה מקבלת רשימה שאינה null של Integers שאינם null ומסירה כל אפס במקום. היא משתמשת בגודל הנוכחי בכל פנייה ואינה ביצע get על רשימה ריקה.
import java.util.ArrayList;
public class RemoveZeros {
public static void removeZeros(ArrayList<Integer> list) {
int i = 0;
while (i < list.size()) {
if (list.get(i) == 0) {
list.remove(i);
} else {
i++;
}
}
}
}
הסבר מדוע לולאה זו מסתיימת
- בכל פנייה או שהיא מסירה אלמנט אחד ומצמצמת גודל, או שומרת על אלמנט ומגדילה את i. כך
size() - i, מספר המיקומים שעוד לבדוק, מצטמצם באחד בכל פנייה. - ההתחל עם
[0, 0, 5], המצבים הם[0, 5]ב-i=0,[5]ב-i=0, ולאחר מכן[5]ב-i=1. התנאי הסופי הוא false, ולכן אין גישה מחוץ לגבול.
לולאה אחורית עוקבת אחרי כלל שונה
- לולאה הפוכה מתחילה באינדקס האחרון הקיים:
for (int i = list.size() - 1; i >= 0; i--). הסר אלמנטים תואמים עםremove(i); ה-i הבא הוא תמיד אחד פחות. - מחיקה ב-i מזיזה רק אינדקסים מאוחרים, שאלה כבר נבדקו. אלמנטים מאוחרים שלא נבדקו שומרים על האינדקסים שלהם, ולכן הצמצמה לאחר הסרה היא נכונה כאן; "לעולם אל תעלה לאחר הסרה" אינו כלל אוניברסלי.
בחר עדכון אינדקס המתאים לכיוון הטיפוס. בלולאת while קדמית, נשאר לאחר ההסרה; בלולאת for אחורית, המשך בהקטעה. שינויים מבניים ישירים בזמן לולאה משופרת הם דגם מסוכן נפרד, גם כאשר אין יוצא מהכללים של fail-fast.
בתוך לולעת while קדמית המוצגת כאן, הקדם את i רק כאשר אתה...
Difficulty 1/5 · 100 coins + a small bonus on first completion today
לאחר ביצוע remove(i), האלמנט הבא עובר לתוך i — אל תדלגו עליו.
לולאת קדימה גסה ב-[0, 0, 5] שמסירה באינדקס i=0 ומזזה את i אחרי כך דורשת את האפס הבא.
Difficulty 1/5 · 100 coins + a small bonus on first completion today
האפס הנותר זז לאינדקס 0, אך הבדיקה הבאה היא באינדקס 1. לולאה אחורית משתמשת בכלל אינדקס נכון שונה.
חלופה להסרה במקום שמניקה הזזה היא...
Difficulty 1/5 · 100 coins + a small bonus on first completion today
הוספת השומרים לרשימה טרייה מונעת הזזה.
אלגוריתמי ArrayList משתמשים מחודשת בדפוסים של מערך באמצעות...
Difficulty 1/5 · 100 coins + a small bonus on first completion today
החליפו את [] ו-length ב-get(i) ו-size().
הטבע הגמיש של ArrayList מאפשר הוספה ומחיקת אלמנטים, בניגוד למערך קבוע.
Difficulty 1/5 · 100 coins + a small bonus on first completion today
add ו-remove משנים את גודל הרשימה.
לולאת הסרה אחורית החל מ size()-1 חייבת להישאר באותו אינדקס לאחר כל מחיקה.
Difficulty 1/5 · 100 coins + a small bonus on first completion today
False: אלמנטים שלא נבדקו קודם שומרים על האינדקסים שלהם, ולכן לולאה אחורית מצטמצמת כרגיל.
בנה רשימה חדשה כאשר הדרוש לשמור על המקור
- כדי לשמר את הרשימה המקורית, צור תוצאה חדשה והוסף אליה כל אלמנט שאינו אפס בזמן הקריאה מהמקור. כך נשמר הרצף המקורי וגודלו ללא שינוי, אך הדבר דורש אחסון נוסף ברשימה.
- עבור רשימות של אובייקטים משתנים (mutable), העתקת הייחוסים הנשמרים אינה ביצוע עותק (clone) של האובייקטים עצמם. ייתכן שרשימה חדשה תשתף את אובייקטי האלמנטים עם המקור; יש להבחין בין זהות הרשימה לבין זהות האלמנטים.
הסרה קדימה שומרת על האינדקס לאחר מחיקה
שתי אפסים סמוכים נבדקים באינדקס 0 לפני שהאחד 5 נשמר.
בדוק את המקרים החושפים את האלגוריתם
- בדוק רשימה ריקה, כולם אפסים, ללא אפסים, אפסים סמוכים ואפס באינדקס האחרון. עבור הסרה במקום, ייחוסים אחרים אותה רשימה יצפו לשינוי שלה; תוצאה חדשה תשאיר את המבנה המקורי ללא פגיעה.
- רשימת ArrayList יכולה להכניס או למחוק אלמנטים; פעולות אלו עלולות להזז אינדקסים מאוחרים יותר. חיפוש עשוי להחזיר אינדקס שנמצא או -1 כאשר האלמנט לא קיים; מקסימום דורש מדיניות ספציפית לרשימה ריקה. שימוש חוזר בדפוסי מערך באמצעות get/size עוזר, אך כל אלגוריתם עדיין זקוק לגבולות ולחוזים משלו.
הסרה גורמת להזזת אינדקסים. הסבר אילו אלמנטים נותרו ללא בדיקה ובחר את האינדקס הבא בהתאם. נהלי שמירה-או-הגדלה קדימה והורדה אחורית הם שניהם דפוס תקפים; רשימה חדשה של אלמנטים שנשמרו תשמור על המבנה המקורי אך עשויה לשתף אובייקטים.
Order the states for the corrected removal loop on [0, 0, 5].
Difficulty 3/5 · 200 coins + a small bonus on first completion today
Each removal rechecks the shifted value; keeping 5 finally advances the index.
כמה קריאות get מבצע השיטה removeZeros הקדמית המוצגת על רשימה ריקה?
Difficulty 2/5 · 140 coins + a small bonus on first completion today
התנאי ההתחלתי 0 < 0 הוא false, ולכן לא מתרחשת קריאת get.