דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. תרגיל: עיגול מספר לפי מערך מפתחות

תרגיל: עיגול מספר לפי מערך מפתחות

מתוזמן נעוץ נעול הועבר תכנות
23 פוסטים 5 כותבים 530 צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • קומפיונטק מנותק
    קומפיונטק מנותק
    קומפיונט
    השיב לdovid ב נערך לאחרונה על ידי
    #14

    @dovid אמר בתרגיל: עיגול מספר לפי מערך מפתחות:

    א. אני גם תהיתי אם יום אחד תכתוב לנו את הקוד בו סרקת תוך שניות את הקוד ההוא של המודלו...

    אין לי משהו מיוחד בקוד, זה brute force פשוט. העניין הוא מאיזה מספר להתחיל את הסריקה. לא התחלתי מאפס, כמובן.

    שים לב שההצעה שלי לא יותר קצרה, ושים לב שלבקש קוד הכי קצר והכי יעיל זה כמו לבקש מכונית הכי מהירה ועם הכי הרבה מקום בו זמנית בלי להסביר לפי מה יחולק הציון בין שני הפרמטרים.

    אם יש לך אחד משני הפרמטרים שהוא יותר טוב זה מספיק לי.
    כולנו לעיתים כותבים קוד יותר קריא מאשר מהיר מבחינת ביצועים. (מי מאתנו לא משתמש ב-LINQ? זה ודאי יותר איטי מלולאה) אז צריך לבחור בצורה הגיונית מה עדיף, ואני לא צריך לתת ציונים מפורשים איזה פרמטר אני מעדיף. לך לפי השכל הישר. (אם יש לי קוד קצר כנגד קוד מאוד מסורבל אבל קצת יותר מהיר, אז אני אעדיף את הקוד הקצר, לעומת זאת אם יש לי קוד קצר איטי כנגד קוד יותר ארוך אבל יותר מהיר משמעותית אז אני יבחר את הקוד הארוך, ובפרט אם זה קוד שמתבצע הרבה פעמים, ולא רק פה ושם).

    אתה יודע מה, שורה תחתונה - אני מעוניין בקוד הכי קצר שאפשר.

    תגובה 1 תגובה אחרונה
    0
    • Y.Excel.AccessY מנותק
      Y.Excel.AccessY מנותק
      Y.Excel.Access
      השיב לקומפיונט ב נערך לאחרונה על ידי Y.Excel.Access
      #15

      @קומפיונט אמר בתרגיל: עיגול מספר לפי מערך מפתחות:

      יש לי מערך של מפתחות, לדוג 100 200 300 ... ואני רוצה שהמשתמש יזין מספר כלשהו הוא יעוגל למספר המפתח הקרוב ביותר.

      יש לי כמה דרכים לעשות את זה, אבל אני מחפש את הדרך הכי קצרה ויעילה.

      אולי יש למשהו דרך יצירתית לעשות את זה?

      יש לציין שהפתרון שלי הוא רק בשפות של NET., אבל בטוח יש דרכים יצירתיות גם בשפות אחרות. אז אתם גם מוזמנים לנסות (כמובן בלי גוגל).

      בלי לחפש...
      הפתרון כאן הוא ב VBA.
      אני מניח שכל המערך הוא עם ערכי INT בלבד,
      וגודל המערך ידוע, אך גודלו יכול להיות LONG.

      והדרך הכי יעילה מבחינתי, זה לקודד לבד... כך כל פעולה ידועה,
      והכי קצרה - לכתוב את זה כפונקציה:)

      נ.ב. יכול להיות שיש עוד דרכים יותר טובות - לא בדקתי את הקודים בשרשור.
      וגם - יש משהו מעצבן בVBA, שבחלק מהיישומים (לדוגמה, אצלי) א"א לדעת את גבולות המערך למרות שיש פונקציה ייעודית לזה (LowerBound, ו UpperBound) וכש"כ לא את גודל המערך, לכן הוספתי פרמטרים של גבולות המערך.

      Option Explicit
      
      Public Function Round(ByRef Value As Integer, ByRef Arr() As Integer, ByRef Length As Long, Optional ByRef LowerBound As Long = 0) As Integer
      
          Dim i As Long
          Dim lower As Integer, upper As Integer
          
          If Value = Arr(LowerBound) Then
              Round = Value
              Exit Function
          ElseIf Arr(LowerBound) > Value And Arr(LowerBound) < 32767 Then       ' limit intreger == 32767
              upper = Arr(LowerBound)
          ElseIf Arr(LowerBound) < Value And Arr(LowerBound) > lower Then
              upper = 32767
              lower = Arr(LowerBound)
          End If
          
          For i = LowerBound + 1 To LowerBound + Length - 1
              If Value = Arr(i) Then
                  Round = Value
                  Exit Function
              ElseIf Arr(i) > Value And Arr(i) < upper Then
                  upper = Arr(i)
              ElseIf Arr(i) < Value And Arr(i) > lower Then
                  lower = Arr(i)
              End If
              
              'Debug.Print "arr(i) " & Arr(i) & " lower " & lower & " upper " & upper
          Next i
          
          If upper - Value <= Value - lower Then Round = upper Else Round = lower
          
      End Function
      
      Sub בדיקה()
      Dim AA(1 To 5) As Integer
      AA(1) = 4
      AA(2) = 12
      AA(3) = 2
      AA(4) = 22
      AA(5) = 80
      MsgBox Round(CInt(InputBox("")), AA, 5, 1)
      End Sub
      

      Y.Excel.Access @ gmail.com

      dovidD תגובה 1 תגובה אחרונה
      2
      • dovidD מנותק
        dovidD מנותק
        dovid ניהול
        השיב לY.Excel.Access ב נערך לאחרונה על ידי dovid
        #16

        @Y-Excel-Access יפה מאוד!
        אני חושב שאתה יכול בדרך שלך לחסוך את ההקדמה ללולאה:

        Dim i As Long
        Dim lower As Integer, upper As Integer
        lower = -32768
        upper = 32767
        
        For i = LowerBound To LowerBound + (Length - 1)
            If Value = Arr(i) Then
                Round = Value
                Exit Function
            ElseIf Arr(i) > Value And Arr(i) < upper Then
                upper = Arr(i)
            ElseIf Arr(i) < Value And Arr(i) > lower Then
                lower = Arr(i)
            End If
            
        Next i
        
        If upper - Value <= Value - lower Then Round = upper Else Round = lower
        

        @Y-Excel-Access אמר בתרגיל: עיגול מספר לפי מערך מפתחות:

        וגם - יש משהו מעצבן בVBA, שבחלק מהיישומים (לדוגמה, אצלי) א"א לדעת את גבולות המערך למרות שיש פונקציה ייעודית לזה (LowerBound, ו UpperBound) וכש"כ לא את גודל המערך, לכן הוספתי פרמטרים של גבולות המערך.

        מה הכונה א"א? מה הפונקציות UBound/LBound מחזירים? באיזה יישומים מדובר?

        בכל מקרה לולאת for each חוסכת את כל העצבים של מעבר על לולאה, וככה נחסכת לך גם בעיית הגבולות:

        Public Function Round(ByRef Value As Integer, ByRef Arr() As Integer) As Integer
            Dim lower As Integer, upper As Integer
            lower = -32768
            upper = 32767
            
           For Each Item In Arr    ' Iterate through each element.
                If Value = Item Then
                    Round = Value
                    Exit Function
                ElseIf Item > Value And Item < upper Then
                    upper = Item
                ElseIf Item < Value And Item > lower Then
                    lower = Item
                End If
            Next
            
            
            If upper - Value <= Value - lower Then Round = upper Else Round = lower
            
        End Function
        

        בכל מקרה חשיבה קוד יפים!

        מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

        בכל נושא אפשר ליצור קשר dovid@tchumim.com

        תגובה 1 תגובה אחרונה
        1
        • yossizY מנותק
          yossizY מנותק
          yossiz
          כתב ב נערך לאחרונה על ידי
          #17

          במקרה בו הרווחים קבועים וידועים, יש פתרון פשוט בלי לעבור על המערך כלל

          לדוגמה:

          const int INTERVAL = 100;
          
          int[] keys = Enumerable.Range(1, 9).Select(v => v * INTERVAL).ToArray(); // 100 200 300 ...
          
          int input = new Random().Next(1000);
          
          int mod = input % INTERVAL;
          int rounded = Math.Clamp((input - mod) + ((mod > INTERVAL / 2) ? INTERVAL : 0), keys[0], keys[keys.Length - 1]);
          

          📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

          קומפיונטק תגובה 1 תגובה אחרונה
          2
          • קומפיונטק מנותק
            קומפיונטק מנותק
            קומפיונט
            כתב ב נערך לאחרונה על ידי
            #18

            @Y-Excel-Access יפה מאוד. אני לא בקיא ב-vb אז קצת קשה לי להבין את כל הקוד שכתבת. אבל מבדיקה מהירה שלי ראיתי שאם אני מכניס מספר יותר גבוה מהמספר המקסימאלי אז נזרקת שגיאה.

            אגב, הקוד נראה לי קצת ארוך... אז בשביל התרגיל תנסה לקצר אותו כמה שאפשר, אני רואה ש@dovid כבר קיצר לך קצת.

            תגובה 1 תגובה אחרונה
            0
            • קומפיונטק מנותק
              קומפיונטק מנותק
              קומפיונט
              השיב לyossiz ב נערך לאחרונה על ידי קומפיונט
              #19

              @yossiz ממש אהבתי 👍 👍 👍

              אבל אם במערך יש מספרים שליליים זה נותן תוצאות לא צפויות.

              אגב, אפשר לכתוב keys[^1] במקום keys[keys.Length - 1]

              עריכה: מדובר בפיצ'ר די חדשני של #C.

              dovidD 2 תגובות תגובה אחרונה
              1
              • dovidD מנותק
                dovidD מנותק
                dovid ניהול
                השיב לקומפיונט ב נערך לאחרונה על ידי dovid
                #20

                @קומפיונט אמר בתרגיל: עיגול מספר לפי מערך מפתחות:

                אגב, אפשר לכתוב keys[^1] במקום keys[keys.Length - 1]

                הגיוני בפורום לכתוב באופן שכל אחד יכול לבדוק בלי לציין שמדובר בגריסה מאוד חדשנית.
                בפרט בקוד רעיוני/תרגיל.

                מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

                בכל נושא אפשר ליצור קשר dovid@tchumim.com

                dovidD תגובה 1 תגובה אחרונה
                0
                • dovidD מנותק
                  dovidD מנותק
                  dovid ניהול
                  השיב לקומפיונט ב נערך לאחרונה על ידי dovid
                  #21

                  @קומפיונט אני נותן רמז, שהפתרון של @Y-Excel-Access מממש את ההבדל עליו דיברתי שיהיה יעיל יותר מהMaxBy.

                  הנה הקוד של @Y-Excel-Access אבל עם שימוש בMath.Abs:

                  Public Function Round(ByRef Value As Integer, ByRef Arr() As Integer) As Integer
                      Dim temp  As Integer, diff  As Integer, fit As Integer
                      diff = 32767
                      
                      For Each Item In Arr    ' Iterate through each element.
                          If Value = Item Then
                              Round = Value
                              Exit Function
                          Else
                              temp = Math.Abs(Value - Item) 'Math.Abs turn minus and plus to plus.
                              If temp < diff Then
                                  diff = temp
                                  fit = Item
                              End If
                          End If
                      Next
                      
                      Round = fit
                  End Function
                  

                  מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

                  בכל נושא אפשר ליצור קשר dovid@tchumim.com

                  תגובה 1 תגובה אחרונה
                  1
                  • dovidD מנותק
                    dovidD מנותק
                    dovid ניהול
                    השיב לdovid ב נערך לאחרונה על ידי
                    #22

                    @dovid אמר בתרגיל: עיגול מספר לפי מערך מפתחות:

                    @קומפיונט אמר בתרגיל: עיגול מספר לפי מערך מפתחות:

                    אגב, אפשר לכתוב keys[^1] במקום keys[keys.Length - 1]

                    הגיוני בפורום לכתוב באופן שכל אחד יכול לבדוק בלי לציין שמדובר בגריסה מאוד חדשנית.
                    בפרט בקוד רעיוני/תרגיל.

                    סליחה, בכל מקום שMath.Clamp יעבוד (CORE 2 ומעלה) זה בהכרח C# 7.3 לפחות.

                    מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

                    בכל נושא אפשר ליצור קשר dovid@tchumim.com

                    קומפיונטק תגובה 1 תגובה אחרונה
                    2
                    • קומפיונטק מנותק
                      קומפיונטק מנותק
                      קומפיונט
                      השיב לdovid ב נערך לאחרונה על ידי
                      #23

                      @dovid כתב בתרגיל: עיגול מספר לפי מערך מפתחות:

                      סליחה, בכל מקום שMath.Clamp יעבוד (CORE 2 ומעלה) זה בהכרח C# 7.3 לפחות.

                      הערת אגב: הפיצ'ר שכתבתי (arr[^1]) לא קיים ב C# 7.3, זה רק מ 9.0 או 8.0.

                      תגובה 1 תגובה אחרונה
                      2

                      • 1
                      • 2
                      בא תתחבר לדף היומי!
                      • התחברות

                      • אין לך חשבון עדיין? הרשמה

                      • התחברו או הירשמו כדי לחפש.
                      • פוסט ראשון
                        פוסט אחרון
                      0
                      • דף הבית
                      • קטגוריות
                      • פוסטים אחרונים
                      • משתמשים
                      • חיפוש
                      • חוקי הפורום