יום שני, 6 בנובמבר 2017

שפת #C - מחרוזות

אנחנו כבר יודעים איך לעבוד עם מחרוזות בשפת C ובשפת ++C.
היום נלמד על מחרוזות ב-#C:

String

עד היום השתמשנו במערך של משתנים מטייפ char לעבודה עם מחרוזות.
ב#C, (בדומה לJava), קיים טייפ מיוחד בשם "String" שנועד במיוחד לאחסון מחרוזות.

הגדרה:
String str;

אתחול בהגדרה:
String str = "Hello!";

הדפסה:
Console.WriteLine(str);

קליטה:
כאן אין צורך בפונקציית ההמרה "()Parse", משום שהפונקציה ()ReadLine כבר מחזירה String.
str = Console.ReadLine();


NULL מסיים:
ל-String אין NULL מסיים. במקומו נוכל להשתמש במאפיין Length שמייצג את אורך המחרוזת.
str.Length





שימושים ייחודיים ל-String:
היות שכל דבר כמעט ב-#C הוא אובייקט, הדבר נכון גם עבור String.
זה מאפשר לנו:
העתקה
            String str1 = "Hello", str2;
            str2 = str1;
חיבור
            String str1 = "Hello", str2 = " World!", str3;
            str3 = str1 + str2;
            Console.WriteLine(str3); // Hello World! ידפיס








ב C++ / C היינו חייבים לכתוב את הגודל המקסימלי בשורת ההגדרה:
char str [80];

בעבר השתמשנו במצביעים והקצאה דינאמית כדי לא לציין מראש את גודל המחרוזת, אך עם משתני String אין בכך כל צורך. כל ההקצאות מתרחשות מאחורי הקלעים (בתוך המחלקה של String).








שימו לב:
למרות ש-String מתנהג מבחינה תחבירית כמו טייפ ייחודי, עדיין אפשר להתייחס אליו כמו אל מערך עבור קריאה ממנו:
            String str = "Hello!";
            Console.WriteLine(str[1]); // 'e' ידפיס


אבל אי אפשר להתייחס אליו כמערך לצורך כתיבה אליו:
(כלומר לא ניתן לשנות את str ע"י התייחסות אליו כמערך)
            String str = "Hello!";
            str[1] = 'q';  // לא חוקי











פונקציות שימושיות:

(כל הפונקציות הבאות לא משפיעות על str)

1
str.ToLower()
מחזיר את המחרוזת באותיות קטנות
            String str = "Hello";
            Console.WriteLine(str.ToLower()); // hello ידפיס


2
str.ToUpper()
מחזיר את המחרוזת באותיות גדולות
            String str = "Hello";
            Console.WriteLine(str.ToUpper()); // HELLO ידפיס

3
str.TrimStart()
מחזיר את המחרוזת בלי רווחים בתחילתה
            String str = "  Hello";
            Console.WriteLine(str.TrimStart()); //בלי רווחים בהתחלה Hello ידפיס

4
str.TrimEnd()
מחזיר את המחרוזת בלי רווחים בסופה
            String str1 = "Hello ", str2 = "World!";
            Console.WriteLine( str1.TrimEnd() + str2 ); // HelloWorld! ידפיס

5
str.Trim()
מחזיר את המחרוזת בלי רווחים בתחילתה ובסופה
            String str1 = "     Hello ", str2 = "World!";
            Console.WriteLine( str1.Trim() + str2 ); // בלי רווח בהתחלה HelloWorld! ידפיס

6
("טקסט")str.StartsWith
מחזיר True אם str מתחיל בטקסט שהזנו, אחרת מחזיר False 
            String str = "Hello World!";
            Console.WriteLine(str.StartsWith("Hello")); // True ידפיס

7
("טקסט")str.EndsWith
מחזיר True אם str מסתיים בטקסט שהזנו, אחרת מחזיר False 
            String str = "Hello World!";
            Console.WriteLine(str.EndsWith("Peace")); // False ידפיס

8
("טקסט חדש" , "טקסט ישן")str.Replace
מחזיר את המחרוזת כאשר כל מקום שמופיע בה ה-"טקסט ישן" מוחלף ב-"טקסט חדש"
            String str = "Good morning. It's a beautiful morning";
            str = str.Replace("morning""night");
            Console.WriteLine(str); // Good night. It's a beautiful night ידפיס

9
(מספר_תווים_למחיקה , אינדקס_תחילת_מחיקה)str.Remove
החל מ-"אינדקס_תחילת_מחיקה", מוחק תווים כמספר "מספר_תווים_למחיקה"
-אם רוצים ניתן לכתוב רק את "אינדקס_תחילת_מחיקה" ואז ימחוק מהמקום שצוין ועד לסוף המחרוזת.
-חשוב להקפיד ש-"מספר_תווים_למחיקה" לא יגרום לחריגה מעבר לאורך המחרוזת.                        
            String str = "ABCDEFGHIJK";
            Console.WriteLine(str.Remove(2, 3)); // ABFGHIJK ידפיס
            Console.WriteLine(str.Remove(2));    // AB ידפיס

10
("טקסט")str.IndexOf
אם מוצא את "טקסט" בתוך str מחזיר את האינדקס שבו הוא מופיע בפעם הראשונה. אם לא מוצא מחזיר 1-.
            String str = "Good morning. It's a beautiful morning";
            Console.WriteLine(str.IndexOf("morning")); // ידפיס 5
            Console.WriteLine(str.IndexOf("boy"));     // בטקסט boy ידפיס 1- משום שלא מצא את המילה

11
("מספר_תווים" , "אינדקס_התחלה")str.Substring
החל מ-"אינדקס_התחלה", מחזיר תווים כמספר "מספר_תווים"
-אם רוצים ניתן לכתוב רק את "אינדקס_התחלה" ואז יחזיר מהמקום שצוין ועד לסוף המחרוזת.
-חשוב להקפיד ש-"מספר_תווים" לא יגרום לחריגה מעבר לאורך המחרוזת.                          
            String str = "Good morning";
            Console.WriteLine(str.Substring(5,3)); // mor ידפיס
            Console.WriteLine(str.Substring(5));   // morning ידפיס

12
(str1.CompareTo(str2
משווה אסקי של מחרוזות. (מקביל ל- ()strcmp בשפת C)
אם str1 קודם - מחזיר 1  
אם str2 קודם - מחזיר 1-
אם זהים - מחזיר 0       
            String str1 = "Shalom", str2 = "Shlomo";
            Console.WriteLine(str1.CompareTo(str2)); // -1 ידפיס 










אתחול מערך בתו:
אם נרצה להכניס ל-str2 רק את התו הראשון של str1, מה נעשה?

בעיה:

;[str2[0] = str1[0
לא חוקי משום שגישה למחרוזת בתחביר של מערך מתאפשרת רק בקריאה ממנו.

;[0]str2 = str1
לא חוקי משום שלא ניתן לבצע '=' בין char ל-String.

;[str2 += str1[0
לא חוקי משום ש-str2 עדיין לא מאותחל. לכן לא ניתן להשתמש באופרטור '+' או '=+'.



פתרון 1:
            String str1 = "abc";
            String str2 = "";
            str2 += str1[0];
            Console.WriteLine(str2); // a ידפיס
חוקי משום ש-str2 כעת כן מאותחל. אתחול זה הוא "אתחול ריק".




פתרון 2:
            String str1 = "abc";
            String str2;
            str2 = str1.Substring(0, 1);
            Console.WriteLine(str2); // a ידפיס
חוקי משום ש-Substring מחזירה את התו הראשון של str1 בתור String ולא בתור char.

















שאלות לתרגול:

(אם חשובים לנו ביצועי מערכת מהירים עדיף לכתוב בשפת ++C)

1) כתוב תוכנית אשר מקבלת מחרוזת, הופכת את כל האותיות הקטנות לגדולות, ומדפיסה את המחרוזת החדשה.
          לדוגמא:
             אם המחרוזת הראשונה היא:  "abA1#2cN"
             אז המחרוזת החדשה תהיה: "ABA1#2CN"


2) כתוב תוכנית אשר קולטת מחרוזת ומעתיקה רק את האותיות שבמחרוזת למחרוזת חדשה.
          לדוגמא:
             אם המחרוזת הראשונה היא: ”Ad3$3Laad”
             אז המחרוזת החדשה תהיה:        ”AdLaad”


3) כתוב תוכנית אשר קולטת מחרוזת ומעתיקה את תוכנה למחרוזת חדשה ללא כפילויות. כלומר כל תו יופיע לכל היותר פעם אחת בכל המחרוזת.
          לדוגמא:
                אם המחרוזת הראשונה היא: "aa12#1b1"
                אז המחרוזת החדשה תהיה:        "a12#b"


4) כתוב תוכנית אשר קולטת מחרוזת וסופרת את מספר ההופעות של אותיות קטנות ברצף.
    כלומר כל פעם שמופיע רצף שמונה 2 אותיות קטנות לפחות - המונה עולה.
          לדוגמא:
                עבור המחרוזת: "gg5*Tta2arrs52ss2R"
                הפלט יהיה:  4
                עבור המחרוזת: "tRtYYqq"
                הפלט יהיה:  1


5) כתוב תוכנית אשר קולטת מחרוזת ומדפיסה את הכמות הכי גדולה של ספרות שהופיעו ברצף.
          לדוגמא:
                עבור המחרוזת: "A12dk34532r125"
                הפלט יהיה:  5












תשובות:

תשובה 1:
    class Program // שאלה 1
    {
        static void Main(string[] args)
        {
            String str1, str2;
            Console.WriteLine("Enter string: ");
            str1 = Console.ReadLine();
            str2 = str1.ToUpper();
            Console.WriteLine(str2);
        }
    }




תשובה 2:
    class Program // שאלה 2
    {
        static bool Letter(char c)
        {
            if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) return true;
            return false;
        }
        static void Main(string[] args)
        {
            String str1, str2 = "";
            Console.WriteLine("Enter string: ");
            str1 = Console.ReadLine();
 
            for (int i = 0; i < str1.Length; i++)
                if (Letter(str1[i])==true) str2 += str1[i];
            Console.WriteLine(str2);
        }
    }




תשובה 3:
class Program // שאלה 3
    {
        /*
         * (ראוי לציין שהתוכנית הזו מאוד לא יעילה מבחינת ביצועים)
         */
        static void Main(string[] args)
        {
            String str1, str2 = "";
            Console.WriteLine("Enter string: ");
            str1 = Console.ReadLine();
 
            for (int i = 0; i < str1.Length; i++)
                if (str2.IndexOf(str1[i]) == -1) str2 += str1[i];
            Console.WriteLine(str2);
 
        }
    }



תשובה 4:

[נסו בעצמכם]



תשובה 5:
    class Program // שאלה 5
    {
        static Boolean Digit(char c)
        {
            if (c >= '0' && c <= '9'return true;
            return false;
        }
 
        static void Main(string[] args)
        {
            int MAX = 0, count = 0;
            String str = "qqqq98w2u333u4444uuuu555555";
            for (int i = 0; i < str.Length; i++)
            {
                if (Digit(str[i]) == true)
                {
                    count++;
                }
                else
                {
                    if (MAX < count) MAX = count;
                    count = 0;
                }
            }
            if (MAX < count) MAX = count; // עבור מקרה שהמחרוזת נגמרת במספר
 
            Console.WriteLine(MAX);
        }
    }








בהצלחה!
ראו גם: StringBuilder לביצועים מהירים יותר.

תגובה 1:

  1. שאלה 3:

    class Program
    {

    static void Main(string[] args)
    {
    String str1;
    String str2 = "\0";

    Console.WriteLine("Enter string: ");
    str1 = Console.ReadLine();
    str2 += str1[0];

    for (int i = 1; i < str1.Length; i++)
    if (str1[i] != str2[str2.Length - 1]) str2 += str1[i];


    str2 = str2.Remove(0, 1);
    Console.WriteLine(str2);

    }
    }

    השבמחק