עזרה בקוד, שפת C
מנהלים: kabanist, Sir Psycho Sexy
-
- Moderator
- הודעות: 4093
- הצטרף: 08/9/2002 , 2:00
- מיקום: קריית מוצקין
- אמר/ה תודה: 0
- קיבל תודה: 0
עזרה בקוד, שפת C
בקצרה, נתנו לי מערך ממויין בגודל n עם טוויסט- כל האיברים זזו k מקומות ימינה, באופן סיבובי (כדי לא לחרוג מתחומי המערך). אני צריך לכתוב פונקציה שמוצאת מהו אותו k (ואחר כך להשתמש בזה כדי למיין את המערך).
כל זה, בסיבוכיות זמן של log(n), סיבוכיות מקום של 1.
זה הקוד שלי, הכל היה טוב ויפה עד שהחלתי לוותר על אלגוריתם מיון קיים ולכתוב אחד משל עצמי שמתבסס על הk שאני מוצא, ואז גיליתי שאני לא מוצא את k כמו שצריך:
עזרה מישהו?
כל זה, בסיבוכיות זמן של log(n), סיבוכיות מקום של 1.
זה הקוד שלי, הכל היה טוב ויפה עד שהחלתי לוותר על אלגוריתם מיון קיים ולכתוב אחד משל עצמי שמתבסס על הk שאני מוצא, ואז גיליתי שאני לא מוצא את k כמו שצריך:
עזרה מישהו?
-
- Moderator
- הודעות: 4093
- הצטרף: 08/9/2002 , 2:00
- מיקום: קריית מוצקין
- אמר/ה תודה: 0
- קיבל תודה: 0
הייתי צריך למצוא את k בlog(n) ואז למיין בn*k.
ההדבקה של הקוד פה בפורום עשתה לי קצת צרות, ועד שסידרתי את זה פה קצת שיחקתי עם זה עוד, ופתאום זה עובד לי בצורה סבירה (כלומר, אני עובר את הכמות המינימלית של הטסטים, אבל מקרי קיצון עושים לי בעיות).
אני מניח שמחר אני אמשיך לשבת על זה כדי לחדד מקרי קצה, אבל לעכשיו אני יכול להתקדם הלאה לרקורסיה
ההדבקה של הקוד פה בפורום עשתה לי קצת צרות, ועד שסידרתי את זה פה קצת שיחקתי עם זה עוד, ופתאום זה עובד לי בצורה סבירה (כלומר, אני עובר את הכמות המינימלית של הטסטים, אבל מקרי קיצון עושים לי בעיות).
אני מניח שמחר אני אמשיך לשבת על זה כדי לחדד מקרי קצה, אבל לעכשיו אני יכול להתקדם הלאה לרקורסיה
בדקתי ברפרוף קצת ולא בדקתי את ההצעה שלי, אז ייתכן שאני טועה...
הצעת פיתרון ב-PasteBin:
עריכה: עריכה של הקוד
לא ברור לי מה קורה בבלוק של else. הייתי מצפה שזה יהיה רק middle = (middle + max)/2 וזהו.
דבר שני, נדמה שבבדיקה של if else אתה מנסה למצוא את הצד השמאלי של ההזזה (אם האמצע קטן מהסוף --> תמשיך לחפש, ז"א אתה מחפש אמצע שגדול מהסוף) ואילו בבדיקה של do while אתה בודק האם זה הצד הימני של ההזזה (צא כשהמספר הקודם מהאמצע גדול ממנו)
ז"א אם המערך הוא:
[0]7
[1]8
[2]0
[3]1
[4]2
[5]3
[6]4
[7]5
[8]6
ב-if אתה מוצא את המיקום של 8 ([1]) כשאתה בעצם אמור למצוא את המיקום של 0 ([2]). יוצא שב-while אתה בודק שהוא עדיין גדול מקודמו: [1]8 גדול מ-[0]7 ואתה ממשיך שמאלה שלא כשורה.
אילו זה היה [2]0 התנאי היה מוציא אותך במקום הנכון.
או, אילו התנאי היה שהמספר העוקב לאמצע גדול או שווה לו, היית יוצא במקום שקטן מהזזה ב-1.
אז אולי תשנה את התנאי ב-if else כדי למצוא את הצד הימני של ההזזה. או שתנסה להחליף את התנאי של do while בבדיקה של המספר העוקב במקום הקודם. בחזרה תתן לו middle + 1. תוודא ש-middle + 1 לא גולש. לצורך זה אפשר לשמור על הערך של length (ונראה שאין צורך לשנות אותו כי אני נעזר ב-max_array בבלוק של ה-else). צריך גם איכשהו לבדוק שזה מחזיר 0 כשאמצע הוא תחילת המערך וה-if עדיין מתקיים...
הצעת פיתרון ב-PasteBin:
עריכה: עריכה של הקוד
לא ברור לי מה קורה בבלוק של else. הייתי מצפה שזה יהיה רק middle = (middle + max)/2 וזהו.
דבר שני, נדמה שבבדיקה של if else אתה מנסה למצוא את הצד השמאלי של ההזזה (אם האמצע קטן מהסוף --> תמשיך לחפש, ז"א אתה מחפש אמצע שגדול מהסוף) ואילו בבדיקה של do while אתה בודק האם זה הצד הימני של ההזזה (צא כשהמספר הקודם מהאמצע גדול ממנו)
ז"א אם המערך הוא:
[0]7
[1]8
[2]0
[3]1
[4]2
[5]3
[6]4
[7]5
[8]6
ב-if אתה מוצא את המיקום של 8 ([1]) כשאתה בעצם אמור למצוא את המיקום של 0 ([2]). יוצא שב-while אתה בודק שהוא עדיין גדול מקודמו: [1]8 גדול מ-[0]7 ואתה ממשיך שמאלה שלא כשורה.
אילו זה היה [2]0 התנאי היה מוציא אותך במקום הנכון.
או, אילו התנאי היה שהמספר העוקב לאמצע גדול או שווה לו, היית יוצא במקום שקטן מהזזה ב-1.
אז אולי תשנה את התנאי ב-if else כדי למצוא את הצד הימני של ההזזה. או שתנסה להחליף את התנאי של do while בבדיקה של המספר העוקב במקום הקודם. בחזרה תתן לו middle + 1. תוודא ש-middle + 1 לא גולש. לצורך זה אפשר לשמור על הערך של length (ונראה שאין צורך לשנות אותו כי אני נעזר ב-max_array בבלוק של ה-else). צריך גם איכשהו לבדוק שזה מחזיר 0 כשאמצע הוא תחילת המערך וה-if עדיין מתקיים...
-
- Creature - Dwarf Idiot
- הודעות: 2066
- הצטרף: 10/9/2007 , 19:55
- מיקום: יבנה.
- אמר/ה תודה: 0
- קיבל תודה: 0
- יצירת קשר:
בשביל למצוא את k, תשווה את middle ל- middle+1. ואז תחזור על הפעולה הזו ברקורסיה על חצי המערך הנותן (זה שהאיבר הקריטי נמצא בו). זה עושה את זה בלוג n.Sir Psycho Sexy כתב:הייתי צריך למצוא את k בlog(n) ואז למיין בn*k.
ההדבקה של הקוד פה בפורום עשתה לי קצת צרות, ועד שסידרתי את זה פה קצת שיחקתי עם זה עוד, ופתאום זה עובד לי בצורה סבירה (כלומר, אני עובר את הכמות המינימלית של הטסטים, אבל מקרי קיצון עושים לי בעיות).
אני מניח שמחר אני אמשיך לשבת על זה כדי לחדד מקרי קצה, אבל לעכשיו אני יכול להתקדם הלאה לרקורסיה
Don't drink and draft.
-
- Moderator
- הודעות: 4093
- הצטרף: 08/9/2002 , 2:00
- מיקום: קריית מוצקין
- אמר/ה תודה: 0
- קיבל תודה: 0
הזיזו בk, אתה אומר? ז"א שעכשיו המינימום במקום להיות באינדקס אפס זז k מקומות ימינה? אילו רק יכולת למצוא איפה הוא במערך...
(או שאתה צריך עזרה עם המימוש?)
(או שאתה צריך עזרה עם המימוש?)
נא לא לשלוח לי יותר מה"פ אחת בכל פעם. לפני השליחה, מומלץ לעיין בחוקי הפורום ובשיטת האימות אם עוד לא קראתם אותם.
-
- Moderator
- הודעות: 4093
- הצטרף: 08/9/2002 , 2:00
- מיקום: קריית מוצקין
- אמר/ה תודה: 0
- קיבל תודה: 0
אכן, לעשות את זה בO(n) זה קל. אז הרמז שלי לא היה מספיק עבה?
[עריכה] לא לספיילר לך את מבני, אבל למצוא מינימום במערך בO(logn) אפשרי גם במערך בכלל לא ממוין, אז על אחת כמה וכמה בזה.
[עריכה] לא לספיילר לך את מבני, אבל למצוא מינימום במערך בO(logn) אפשרי גם במערך בכלל לא ממוין, אז על אחת כמה וכמה בזה.
נא לא לשלוח לי יותר מה"פ אחת בכל פעם. לפני השליחה, מומלץ לעיין בחוקי הפורום ובשיטת האימות אם עוד לא קראתם אותם.
-
- Moderator
- הודעות: 4093
- הצטרף: 08/9/2002 , 2:00
- מיקום: קריית מוצקין
- אמר/ה תודה: 0
- קיבל תודה: 0
אני לא ממש יודע שפת C אבל אולי אני יוכל לעזור..
int k = 0;
int min = Array[0];
for (int i = 1; i < Length; i++)
if (Array < min)
{
k = i;
min = Array;
}
זה השורות קוד למציאת k
עריכה: יש משהו יותר יעיל:
for (int i = 0; i <Length> Array[i + 1])
return i;
int k = 0;
int min = Array[0];
for (int i = 1; i < Length; i++)
if (Array < min)
{
k = i;
min = Array;
}
זה השורות קוד למציאת k
עריכה: יש משהו יותר יעיל:
for (int i = 0; i <Length> Array[i + 1])
return i;
נערך לאחרונה על ידי leeron ב 20/6/2012 , 22:41, נערך פעם 1 בסך הכל.
-
- Moderator
- הודעות: 4093
- הצטרף: 08/9/2002 , 2:00
- מיקום: קריית מוצקין
- אמר/ה תודה: 0
- קיבל תודה: 0
leeron כתב:אני לא ממש יודע שפת C אבל אולי אני יוכל לעזור..
int k = 0;
int min = Array[0];
for (int i = 1; i < Length; i++)
if (Array < min)
{
k = i;
min = Array;
}
זה השורות קוד למציאת k
נכון, הבעייה היחידה היא שזה עובדת בסיבוכיות זמן O(n), כשאני צריך O(logn). ברור שלרוץ על המערך, לבדוק איבר איבר ולבחור את ההכי קטן זה הדרך הכי פשוטה- היא אבל הדרך לא הכי יעילה.
-
- Legendary Samurai
- הודעות: 1069
- הצטרף: 04/11/2009 , 23:08
- מיקום: חיפה
- אמר/ה תודה: 0
- קיבל תודה: 0
אם אתה ממש צריך פיתרון, לא ממש הסתכלתי, אבל את ה יכול לעשות חיפוש לפי אמצע.
אתה צריך a>a[i+1]
אם זה מתקיים מצאת רק עם a[i+1]<a[2+i]
אם מקיים הראשון אבל לא השני, אתה צריך לחפש מחצי הימיני. אם הראשון לא מתקיים חפש בחצי השמאלי .
אתה צריך בעיקרון רק שני משתנים - קצע ימין וקצה שמאל. זה בעצם חיפוש בינארי ולכן o(logn). במקום זה o(1)
אתה צריך a>a[i+1]
אם זה מתקיים מצאת רק עם a[i+1]<a[2+i]
אם מקיים הראשון אבל לא השני, אתה צריך לחפש מחצי הימיני. אם הראשון לא מתקיים חפש בחצי השמאלי .
אתה צריך בעיקרון רק שני משתנים - קצע ימין וקצה שמאל. זה בעצם חיפוש בינארי ולכן o(logn). במקום זה o(1)
-
- Moderator
- הודעות: 4093
- הצטרף: 08/9/2002 , 2:00
- מיקום: קריית מוצקין
- אמר/ה תודה: 0
- קיבל תודה: 0
אז אני מבין שלא הסתכלת בהודעה שלי? בעריכות לקוד שלך? בהערות?Sir Psycho Sexy כתב:אתם כל כך מצחיקים... מישהו בכלל הסתכל על הקוד שפרסמתי? כי כולם אומרים לי לכתוב אותו מחדש.
לא יזיק אם תספק דוגמאות שניסית ולא עבדו כדי שנוכל לראות מה הבעיה, וכן את השינויים שעשית שכביכול תיקנו את זה.
הבנתי שאתה נעזר ב-length כדי לדלג את middle למקום הנכון. אבל משום מה אתה לא עושה בו שימוש בבלוק של ה-if. זה אומר שבבדיקה של צד שמאל אתה עובר לאמצע שבין 0 ל-middle שזה בעיה. היית צריך כמו ב-else להעזר ב-length/2 אבל להפחית במקום להגדיל. אולי אפילו שווה ללכת על בטוח עם משתנה start.