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

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

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

השוואת טקסט כאשר המילים אינם לפי הסדר בc#

מתוזמן נעוץ נעול הועבר תכנות
9 פוסטים 5 כותבים 426 צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • pcinfogmachP מנותק
    pcinfogmachP מנותק
    pcinfogmach
    כתב ב נערך לאחרונה על ידי pcinfogmach
    #1

    בC# קיימת הפונקציה contains שבודקת האם מחרוזת טקסט מכיל בתוכו מחרוזת טקסט אחרת
    אבל מה קורה אם המחרוזת השניה מבולגנת (כלומר המילים אינם לפי הסדר) ואתה רוצה לבדוק אם היא קיימת בתוך מחרוזת הראשונה (לדוגמא אם נחפש את "כי זרע יקרא לך ביצחק" בתוך חומש בראשית).
    בניתי לזה קוד והייתי שמח לקבל משוב - תודה מראש

     public static bool StringContains(this string line, string[] searchPatternArray, int maxDistance)
     {
         maxDistance = maxDistance - searchPatternArray[searchPatternArray.Length - 1].Length;
         List<List<int>> wordIndexesList = new List<List<int>>();
    
         // Get indexes of each word in the line
         foreach (string word in searchPatternArray)
         {
             var indexes = AllIndexesOf(line, word).ToList();
             wordIndexesList.Add(indexes);
         }
    
         if (wordIndexesList.Any(list => list.Count == 0))
             return false;
    
         // Calculate if there is an occurrence of all words within the max distance
         return IsWithinMaxDistance(wordIndexesList, maxDistance);
     }
    
     static IEnumerable<int> AllIndexesOf(string str, string value)
     {
         if (string.IsNullOrEmpty(value))
             throw new ArgumentException("The string to find may not be empty", nameof(value));
    
         int index = 0;
         while (index < str.Length)
         {
             index = str.IndexOf(value, index);
             if (index == -1)
                 break;
             yield return index;
             index += value.Length;
         }
     }
    
     static bool IsWithinMaxDistance(List<List<int>> wordIndexesList, int maxDistance)
     {
         // Check if all words occur within the maximum distance
         for (int i = 0; i < wordIndexesList[0].Count; i++)
         {
             int startIndex = wordIndexesList[0][i];
             if (IsWithinMaxDistanceForIndex(wordIndexesList, maxDistance, 1, startIndex))
             {
                 return true;
             }
         }
         return false;
     }
    
     static bool IsWithinMaxDistanceForIndex(List<List<int>> wordIndexesList, int maxDistance, int wordIndex, int startIndex)
     {
         if (wordIndex >= wordIndexesList.Count)
             return true; // All words checked within max distance
    
         for (int j = 0; j < wordIndexesList[wordIndex].Count; j++)
         {
             int endIndex = wordIndexesList[wordIndex][j];
             int distance = Math.Abs(endIndex - startIndex);
             if (distance <= maxDistance)
             {
                 if (IsWithinMaxDistanceForIndex(wordIndexesList, maxDistance, wordIndex + 1, endIndex))
                 {
                     return true;
                 }
             }
             else if (endIndex > startIndex)
             {
                 // No need to check further as the indexes are sorted
                 break;
             }
         }
    
         return false;
     }
    
    yossizY תגובה 1 תגובה אחרונה
    1
    • dovidD מנותק
      dovidD מנותק
      dovid ניהול
      כתב ב נערך לאחרונה על ידי dovid
      #2

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

      יש בקוד כמה שיפורים אפשריים, למשל:

      1. את הבדיקה אם יש מילה שחסרה לגמרי כדאי לבצע בתוך הלולאה הראשונה, ולחסוך את איתור המילים האחרות.
      2. את הפוקנציה IsWithinMaxDistance כדאי להריץ על המילה עם הכי פחות מופעים מאשר המילה הראשונה כפי שזה כעת.
      3. בIsWithinMaxDistanceForIndex משתמשים ברקורסיה במקום מאוד לא מקובל ומשולל ייתרון. צריך לעשות לולאה מקוננת בIsWithinMaxDistance, זה יהיה יותר יפה ובר תחזוקה ואפילו קוד קצר יותר.

      בפונקציות הפרטיות (כלומר ישמשו רק את הפונקציה הראשית StringContains), מיותר להעיף שגיאות שיכולות להיבדק בקלות בפונקציה הראשית.
      בOOP מקובל להשתמש עם מחלקה שחולקת כמה מאפיינים וככה הפונקציות פחות עמוסות בפרמטרים, אבל בתכנות פונקציונלי דוקא מעדיפים כפי שעשית.

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

      pcinfogmachP תגובה 1 תגובה אחרונה
      2
      • pcinfogmachP מנותק
        pcinfogmachP מנותק
        pcinfogmach
        השיב לdovid ב נערך לאחרונה על ידי pcinfogmach
        #3
        פוסט זה נמחק!
        תגובה 1 תגובה אחרונה
        0
        • sivan22S מנותק
          sivan22S מנותק
          sivan22
          כתב ב נערך לאחרונה על ידי
          #4

          אני הייתי משתמש בספרייה fuzzysharp. הפונקציה fuzz.token_sort_ratio תתן את הניקוד של דימיון בין מחרוזות שאינן באותו הסדר.

          pcinfogmachP תגובה 1 תגובה אחרונה
          2
          • pcinfogmachP מנותק
            pcinfogmachP מנותק
            pcinfogmach
            השיב לsivan22 ב נערך לאחרונה על ידי pcinfogmach
            #5

            @sivan22

            1. זה יותר איטי ממה שאני הצעתי
            2. התוצאות לא משהו אא"כ בין מחרוזות באורך זהה

            אולי אני לא פועל איתו נכון?

            תגובה 1 תגובה אחרונה
            0
            • sivan22S מנותק
              sivan22S מנותק
              sivan22
              כתב ב נערך לאחרונה על ידי
              #6

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

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

                @pcinfogmach מה שדוד העיר שאתה לא מגדיר את הפוקנציה בצורה טובה היא הערה מאוד חשובה, עד שקראתי את הקוד בעיון באמת לא ידעתי מה הפונקציה עושה, וזה באמת עושה משהו מוזר קצת (לענ"ד) ואם היית מגדיר את זה במילים אולי היית שם לב לזה (או אולי זה באמת מה שרצית)

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

                עוד הערה לגבי המרחק. שורה זו:

                maxDistance = maxDistance - searchPatternArray[searchPatternArray.Length - 1].Length
                

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

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

                תגובה 1 תגובה אחרונה
                2
                • dovidD מנותק
                  dovidD מנותק
                  dovid ניהול
                  כתב ב נערך לאחרונה על ידי dovid
                  #8
                  פוסט זה נמחק!
                  תגובה 1 תגובה אחרונה
                  0
                  • E מנותק
                    E מנותק
                    ELIKO
                    כתב ב נערך לאחרונה על ידי
                    #9

                    היי אני לא יודע איך לכתוב את הקוד לזה ב C#

                    לדעתי מה שצריך לעשות זה לקחת מילה אחת (יתכן וישנה עדיפות לפי שכיחות)
                    למצוא את כל המופעים שלה בקוד ולשמור אותם
                    אחכ לרוץ עם המילה הבאה רק במרחק האינקס שמצאנו + N תווים עם כל המיקומים האפשריים של המילה מהאינדקס שמצאנו (צריך לקחת בחשבון את אורך המילים שנשארו כדי לחשב את המיקומים האפשריים בין היתר לכן ישנה עדיפות בבחירת סדר המילים)
                    וכן הלאה
                    וכל פעם גורעים מהרשימה הראשונית את מה שלא מתאים בוודאות
                    וכשמסיימים לרוץ על כל המילים לוקחים רק את הרצפים שמתאימים מתוך האינדקס הראשוני

                    מקווה שהייתי ברור 😎

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

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

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

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