פירוק ספרות משמאל לימין
-
static void scanNumLR(int num) { while (num > 0) { int tempNum = num; int counter = 0; while (tempNum > 10) { tempNum /= 10; counter++; } Console.WriteLine(tempNum); num -= (int)(tempNum * Math.Pow(10, counter)); } }
מרגיש לי לא יעיל עד כאב . (While^2) יש למישהו הצעה לשיפור? (בדגש על דרך מתמטית ולא סריקת סטרינג וכדו')
תודה רבה -
static void scanNumLR(int num) { while (num > 0) { int tempNum = num % 10; Console.WriteLine(tempNum); num /= 10; } }
מחברינו ChatGPT (הוא לפחות טען לי מקודם שהוא ממש רוצה להיות חבר שלי...)
אגב, שים לב שמבחינתו הבעיה היא שבגלל ששאלתי בעברית אני רוצה את המספרים מימין לשמאל...
i me: האם אתה יכול לייעל עבורי את הקוד הזה? static void scanNumLR(int num) { while (num > 0) { int tempNum = num; int counter = 0; while (tempNum > 10) { tempNum /= 10; counter++; } Console.WriteLine(tempNum); num -= (int)(tempNum * Math.Pow(10, counter)); } } ChatGPT: כנראה שאתה מנסה לכתוב פונקציה שמסודרת את מספר מספרי לפי סדר לפידים ימינה לשמאל אך אני מרגיש כי קוד זה לא יעבוד כמו שאתה מכיר. אם זה מה שאתה מנסה לעשות, אני מציע לכתוב פונקציה כזו: Copy code static void scanNumLR(int num) { while (num > 0) { int tempNum = num % 10; Console.WriteLine(tempNum); num /= 10; } } הפונקציה עובדת על ידי מחלקת את המספר עד שנשאר רק ספרה אחת בכל פעם. כך, כל פעם שנשאר ספרה אחת, הפונקציה תדפיס את הספרה ותמשיך למחלק עד שהמספר הנוכחי הוא אפס. אם אתה רוצה שהפונקציה תדפיס את המספר בסדר הפונקציה שלך (לפידים ימינה לשמאל), ניתן לשנות את הפונקציה כך: Copy code static void scanNumLR(int num) { string numStr = num.ToString(); for (int i = numStr.Length - 1; i >= 0; i--) { Console.WriteLine(numStr[i]); } } בפונקציה זו, אנחנו משתמשים במתודת ToString כדי להמיר את המספר למחרוזת, ואז משך
-
@yyy התשובה ש @אביי הביא היא מצוינת מימין לשמאל, ומה שאתה צריך זה משמאל לימין. אז נראה לי שבמקום לחפש אלגוריתם לפרק משמאל לימין (פחות עדיף בעיני, כי זה יותר מורכב ויותר קוד) אפשר פשוט לפרק מימין לשמאל ולהשתמש בפונקציית Reverse.
אני נגיד הייתי כותב את זה ככה:
public static IEnumerable<int> ScanNumber(int value) { for (int x = value; x > 0; x /= 10) { yield return x % 10; } } public static IEnumerable<int> ScanNumber(int value, bool reverse) { var source = ScanNumber(value); return reverse ? source.Reverse() : source; }
-
הנה פתרון מהבינה הלא-מלאכותית שלי:
static IEnumerable<int> ScanNumberLTR(int num) { int magnitude = (int)Math.Log10(num); for (int i = magnitude; i >= 0; i--) { yield return (num / (int)Math.Pow(10, i) % 10); } }
נ.ב. אני לא ממליץ על פתרון זו, אישית הייתי עושה משהו כזה:
static IEnumerable<char> ScanNumberLTRs(int num) { return num.ToString(); }
זה הכי פשוט לקריאות, אבל פותח הנושא ביקש "דרך מתמטית"
במקום השני הייתי הולך על דרך ה-AI וקומפיונט, והייתי מחשבן קודם כל את המחרוזת המלאה משמאל לימין ואז הייתי מהפך אותו,
נראה לי שזה יותר יעיל בביצועים ופחות יעיל בשימוש בזכרון
הפתרון שלי בא לפתור את השאלה בדיוק כפי שפותח הנושא הציג אותהואם כבר, אז צריך "דרך מתמטית" להמיר ספרה לתו... אז הנה:
char Digit2Char(int digit) { return (char)(digit + 48); } foreach (int c in ScanNumberLTR(204300234)) { Console.WriteLine(Digit2Char(c)); }
-
אם לא אכפת לו באמצעות מחרוזת, אז זה הייתי עושה את זה ככה:
(עריכה: לי זה היה פשוט, אבל שכחתי לציין שהקרדיט מגיע ל @yossiz על הטריק להמרת char למספר)
public static IEnumerable<int> ScanNumberUsingString(int value) { string str = value.ToString(); for (int i = str.Length - 1; i >= 0; i--) { yield return str[i] - 48; } }
-
@קומפיונט אחרי תיקון קטן לקוד שלי (חסכתי כמה קריאות ל-
Math.Pow
) נוכחתי לראות שהוא יותר יעיל משלך גם בזמן מעבד (לזה לא ציפיתי) וגם בזכרון (זה מובן)הקוד המתוקן:
IEnumerable<long> ScanNumberLTR(long num) { long magnitude = (long)Math.Log10(num); long divisor = (long)Math.Pow(10, magnitude); for (long i = magnitude; i >= 0; i--) { yield return (num / divisor % 10); divisor = divisor / 10; } }