Count Vowels
בהינתן מחרוזת s של אותיות באנגלית, החזר את מספר התווים בה שהם תנועות. התנועות הן a, e, i, o ו־u, באותיות קטנות או גדולות. האות y אינה נחשבת.
פונקציה
- sstring
- מחרוזת האותיות באנגלית לסריקה
- מחזירהinteger
- מספר התנועות ב־s, אותיות גדולות וקטנות יחד
אילוצים
1 ≤ s.length ≤ 5 × 104sמכיל רק אותיות באנגלית (aעדz,AעדZ).
דוגמאות
- קלט
- s = "Interview"
- פלט
- 4
- הסבר
- התנועות הן
I,e,iו־e. האות הגדולהIנחשבת כמו אות קטנה, ולכן התשובה היא 4.
- קלט
- s = "rhythm"
- פלט
- 0
- הסבר
- אין ב־
rhythmאתa,e,i,oאוu, ו־yלא מופיעה ברשימה, לכן התשובה היא 0.
שאלת המשך
האם תוכל להחזיר כמה פעמים כל אחת מחמש התנועות מופיעה, תוך קריאה של המחרוזת פעם אחת בלבד?
רמזים
פתחו אותם אחד אחד. כל רמז חושף קצת יותר.
התבוננו בתווים אחד־אחד. מה הופך תו לתנועה, והאם אות גדולה משנה את התשובה?
המר כל תו לאות קטנה לפני הבדיקה שלו. לאחר מכן השווה מול חמש אותיות במקום עשר.
נהלו מונה שמתחיל ב־0. עבור כל תו, הפכו אותו לאות קטנה והוסיפו 1 למונה אם הוא
a,e,i,oאוu.
פתרון
קרא את המחרוזת פעם אחת עם מונה. המר כל תו לאות קטנה, כך שבדיקה אחת מול חמש התנועות תכסה את שני סוגי האותיות.
סופרים כל תנועה במעבר נפרד
האינטואיציה
ספרו כל אחת מעשר האותיות שב-aeiouAEIOU במעבר משלה על המחרוזת, ואז חברו את עשרת הספירות. כל תנועה שווה בדיוק לאחת מעשר האותיות, ולכן היא נספרת פעם אחת, ואף עיצור אינו שווה לאף אחת מהן.
המחרוזת נקראת עשר פעמים. זה עדיין O(n), אבל עבור 5 × 10^4 תווים פירוש הדבר הוא 5 × 10^5 השוואות, כאשר בכל מעבר נקרא כל תו פעם אחת.
אלגוריתם
- הגדירו
total = 0. - קחו את עשר האותיות
aeiouAEIOUאחת בכל פעם. - עבור כל אות, עברו על כל המחרוזת והוסיפו 1 ל־
totalבכל פעם שתו שווה לה. - לאחר עשרת המעברים, החזירו את
total.
def countVowels(s):
total = 0
for vowel in "aeiouAEIOU":
total += s.count(vowel) # one pass over s for this letter
return totalמעבר אחד עם בדיקה של אותיות קטנות
האינטואיציה
קרא את המחרוזת פעם אחת ובדוק עבור כל תו אם הוא תנועה. המרתה לאותיות קטנות תחילה הופכת את I ל־i ומשאירה עיצורים כעיצורים, כך שמשווים לחמש אותיות במקום לעשר.
הבדיקה מתבצעת בזמן קבוע: באמצעות switch, חיפוש בקבוצה או חיפוש במחרוזת aeiou. כל תו נקרא פעם אחת ונשמר רק מונה: זמן O(n), מקום O(1).
אלגוריתם
- הגדר את
count = 0. - עבור על המחרוזת תו אחד בכל פעם.
- המר את התו לאות קטנה.
- אם הוא
a,e,i,oאוu, הוסף 1 ל-count. - החזר את
count.
def countVowels(s):
vowels = set("aeiou")
count = 0
for ch in s:
if ch.lower() in vowels:
count += 1
return count
מלכודות ומקרי קצה
- בדיקה של אותיות קטנות בלבד. השוואה ל־
aeiouבלבד מפספסת את האות הגדולהIבמילהInterviewומחזירה 3. - ספירת
y. כאן היא אף פעם אינה תנועה, ולכןrhythmמחזירה 0. - התייחסות לאינדקס 0 כאילו אין התאמה.
"aeiou".indexOf('a')הוא 0, וזה מציין התאמה. בדקו אם הערך הוא-1, או ב־PHP השוו אתstrposל־falseבאמצעות!==, כי שם0 == false. - קריאה ל־
strlen(s)בתנאי הלולאה ב־C. היא סורקת מחדש את המחרוזת בכל צעד, ולכן עיבוד של5 × 10^4תווים דורש בערך2.5 × 10^9צעדים.
שאלות נפוצות3
איך סופרים את התנועות במחרוזת?
עבור על המחרוזת פעם אחת באמצעות מונה. המר כל תו לאות קטנה והוסף 1 אם הוא a, e, i, o או u. כשהלולאה מסתיימת, המונה מכיל את התשובה.
מהי סיבוכיות הזמן של ספירת תנועות?
O(n), כאשר n הוא אורך המחרוזת, כי כל תו נבדק פעם אחת מול לכל היותר חמש אותיות. המקום הנוסף הוא O(1): מונה אחד והקבוצה הקבועה של התנועות.
האם y היא תנועה בבעיה הזאת?
לא. בכתיב האנגלי, y משמשת לפעמים כתנועה, כמו ב־rhythm, אבל בבעיות תכנות כמעט תמיד מגדירים את התנועות בתור a, e, i, o ו־u, וכך גם בבעיה הזאת. אם בעיה כוללת את y, הוסף אותה לאותיות שאתה בודק.
בעיות דומות
בעיות שמשתמשות באותם רעיונות. פתרון של שתיים או שלוש מהן מקבע את הדפוס.
def countVowels(s):
# כתבו כאן קודבדיקה #1
בדיקה #2
ארגומנט
s = "Interview"
הפלט הצפוי
4