Kihagyás

5.1. Összetett adatszerkezetek

Stringek

A string típusú változók néhány tulajdonságát már megismerhettük a mobilszám-ellenőrző programban. A C#-ban, mint objektumorientált nyelvben a string nem csak típus, hanem osztály is. Az egy típusba tartozó változókat, a hozzájuk tartozó műveleteket és operátorokat osztálynak nevezzük.

A string osztályhoz tartozó műveletek közül már ismerünk kettőt a fent említett programból:

  • Szöveghossz meghatározása: A szam.Length megadta a szam string hosszát, a szam[0].ToString() pedig a szöveg 1. karakterét.
  • Összeadás: Fontos megemlíteni, hogy az összeadás művelet értelmezhető stringeken, de eredménye nem azonos a számtípusoknál megismerttel. Itt a szövegeket egymás után fűzi a + operátor. Pl.: "objektum" + "orientált" = "objektumorientált", ami talán nem meglepő, de számokból álló stringek esetén már érdekesebb, mert: "77" + "23" = "7723" lesz.
  • Összehasonlítás: A stringek 1 karakterére értelmezhető a < és a > jel ebben a formában: szoveg[4] > szoveg[1]. A teljes stringre viszont csak az ==, vagy != relációs jelek értelmezhetők.

Természetesen a C# nem lenne magas szintű programozási nyelv, ha ilyen hiányosságban szenvedne. A CompareTo segítségével a teljes stringre is tudjuk alkalmazni a kisebb/nagyobb relációkat. A következő feladat ezt mutatja be.

45. feladat

Kérjünk be két szöveget és írassuk ki a képernyőre az ABC-ben előbb lévőt, majd alá az ABC-ben hátrébb levőt! Név: Szövegrendezés

Megoldás:

static void Main(string[] args)
{
    string szoveg1, szoveg2;

    Console.WriteLine(" Kérem az 1. szöveget:");
    szoveg1 = Console.ReadLine();
    Console.WriteLine(" Kérem a 2. szöveget:");
    szoveg2 = Console.ReadLine();

    Console.WriteLine(" ABC sorrendben:");

    // A CompareTo() metódus összehasonlítja a két stringet
    if (szoveg1.CompareTo(szoveg2) > 0)
    {
        Console.WriteLine("1. {0}", szoveg2);
        Console.WriteLine("2. {0}", szoveg1);
    }
    else
    {
        Console.WriteLine("1. {0}", szoveg1);
        Console.WriteLine("2. {0}", szoveg2);
    }

    Console.ReadKey();
}

Két string összehasonlításakor 3 eset lehetséges:

  1. Ha szoveg1 > szoveg2, vagyis szoveg1 később van az ABC-ben, akkor a szoveg1.CompareTo(szoveg2) = 1
  2. Ha szoveg1 < szoveg2, vagyis szoveg1 előbb van az ABC-ben, akkor a szoveg1.CompareTo(szoveg2) = -1
  3. Ha szoveg1 == szoveg2, akkor a szoveg1.CompareTo(szoveg2) = 0

További szöveges műveletek

  • Levágás: A levágás a Trim(), a TrimStart() és a TrimEnd() segítségével jön létre. Ha a zárójelek közé nem írunk paramétereket, akkor a Trim() levágja a szöveg elejéről és végéről, a TrimStart() csak az elejéről, a TrimEnd() csak a végéről a szóközöket. Ha a szoveg egy string típusú változó, akkor a szoveg.Trim('b'); levágja a szöveg elejéről és végéről az összes 'b' karaktert.
  • Átalakítás (kisbetű - nagybetű): Átalakítani nagybetűkké a ToUpper(), kisbetűkké a ToLower() segítségével lehet. Pl.: Ha szoveg = "félév", akkor a szoveg.ToUpper(); után a szöveg "FÉLÉV" lesz.
  • Másolás: Egy szövegből tetszőleges részt másolhatunk a Substring(kezd, db) segítségével, ahol a kezd és a db egész típusú változók és a sztringből a kezd karaktertől db darab karaktert másolhatunk ki. Ha a zárójelek között csak egy paraméter van, akkor a kezd értéktől egészen a szöveg végéig másolhatunk ki részsztringet. Ha sz = "Paróka", akkor sz.Substring(2) = "róka". Ne felejtsük el, hogy itt is 0-tól kezdjük a sztring karaktereinek számozását, mint a tömböknél.
  • Keresés: Az IndexOf() függvénnyel megtudhatjuk, hogy az adott karakter vagy karaktersorozat szerepel-e a sztringben, és ha igen, hol. Ha benne van, akkor a függvény értéke 0 vagy pozitív, ha nincs benne, akkor -1 lesz. Ha a függvény értéke nem -1, akkor a kapott érték azt mutatja meg, hogy hányadik karaktertől találjuk meg az adott karaktersorozatot a szövegben. Pl.: Ha a szoveg.IndexOf(szo) = 3, akkor a szoveg szövegben a szo szó a 4. pozíciótól található meg. (Pl: szoveg = "M á t é s z a l k a" és szo = "é s z").

46. feladat

Kérjünk be egy szöveget és egy karaktert majd írjuk ki, hogy a szövegben hányszor fordul elő a megadott karakter! Név: Karakterszamlalas

Megoldás:

static void Main(string[] args)
{
    string szoveg;
    char karakter = ' ';
    int db = 0, i = 0;

    Console.Write(" Kérem a szöveget: ");
    szoveg = Console.ReadLine();
    Console.Write(" Kérem a karaktert: ");
    karakter = Convert.ToChar(Console.ReadLine());

    for (i = 0; i < szoveg.Length; i++)
    {
        if (karakter == szoveg[i]) db++;
    }

    Console.WriteLine();
    Console.WriteLine(" A(z) {0} karakterből {1} db van a szövegben", karakter, db);
    Console.ReadKey();
}

Mivel csak szöveget lehet bekérni billentyűről, ezért a k (karakter) bekérésénél karakterré kell konvertálni.

47. feladat

Kérjünk be egy szöveget és egy szót majd írjuk ki, hogy a szövegben hányszor fordul elő a megadott szó! Név: Szoszamlalas

Megoldás:

static void Main(string[] args)
{
    string szoveg, szo;
    int db = 0, i = 0;

    Console.Write(" Kérem a szöveget: ");
    szoveg = Console.ReadLine();
    Console.Write(" Kérem a szót: ");
    szo = Console.ReadLine();

    for (i = 0; i <= szoveg.Length - szo.Length; i++)
    {
        if (szoveg.Substring(i, szo.Length) == szo) db++;
    }

    Console.WriteLine();
    Console.WriteLine(" A(z) {0} szóból {1} db van a szövegben", szo, db);
    Console.ReadKey();
}

A for ciklus a szót a szövegben a 0. karaktertől kezdve keresi a szöveg hossza - szó hossza értékig. Ha tehát a szöveg 10 hosszú, a szó pedig 3, akkor 10 - 3 = 7 lesz az i végértéke, tehát 0-tól 7-ig 8-szor fut le a ciklusmag. Utoljára az szoveg.Substring(7,3) értékét hasonlítjuk össze a szóval, vagyis a szöveg 7., 8., 9. karakterét hasonlítjuk a 3 hosszúságú szóval és ha megegyezik, akkor növeljük db értékét.

48. feladat

Kérjünk be egy szöveget, és írjuk ki visszafelé! A fordított szöveg csak nagybetűből álljon! Név: Szovegmegfordito

Megoldás:

static void Main(string[] args)
{
    string szoveg = "", forditottSzoveg = "";
    int i = 0;

    Console.Write(" Kérem a szöveget: ");
    szoveg = Console.ReadLine();

    for (i = szoveg.Length - 1; i >= 0; i--)
    {
        forditottSzoveg = forditottSzoveg + szoveg[i];
    }

    Console.WriteLine(" A szöveg megfordítva: ");
    Console.WriteLine(forditottSzoveg.ToUpper());
    Console.ReadKey();
}

A for ciklust most a szöveg vége - 1-től 0-ig visszafelé kell léptetni és az új, megfordított szöveghez egyesével kell hozzáfűzni az aktuális, 1 hosszúságú szöveget.

49. feladat

Kérjük be egy személy nevét, amely vagy 2 vagy 3 részből áll! Írjuk ki a vezetéknevet, majd alá a keresztnevet és ez alá a második keresztnevet, ha van! Név: Nevkiiras

Megoldás:

static void Main(string[] args)
{
    string nev = "", vNev = "", kNev = "", k2Nev = "";
    int i = -1;

    Console.WriteLine(" Kérem a nevet: ");
    nev = Console.ReadLine();

    do
    {
        i++;
        vNev = vNev + Convert.ToString(nev[i]);
    } while (nev[i] != ' ');

    Console.WriteLine(" A vezetéknév: {0}", vNev);

    do
    {
        i++;
        kNev = kNev + Convert.ToString(nev[i]);
    } while (nev[i] != ' ' && i + 1 != nev.Length);

    Console.WriteLine(" A keresztnév: {0}", kNev);

    if (nev[i] == ' ')
    {
        do
        {
            i++;
            k2Nev = k2Nev + Convert.ToString(nev[i]);
        } while (i < nev.Length - 1);
        Console.WriteLine(" A 2. keresztnév: {0}", k2Nev);
    }

    Console.ReadKey();
}

A program megírásánál abból indulunk ki, hogy a neveket szóköz választja el egymástól. Ha egy szóköz van a szövegben, akkor csak vezeték- és keresztnév van, ha két szóköz, akkor második keresztnév is van. Ezért a név bekérése után egy hátultesztelő ciklusban addig tesszük a szöveg karaktereit a vNev változóba, amíg az 1. szóközig elérünk. Ekkor már a vezetéknevet ki is írjuk a képernyőre. A szövegben továbbhaladva a keresztnevet kapjuk meg. Addig kell a ciklusban maradni, amíg két feltétel egyszerre teljesül: 1. nev[i] != ' ' vagyis a szöveg aktuális karaktere nem egyenlő szóközzel és 2. i + 1 != nev.Length tehát a következő karakter sorszáma nem az utolsó a szövegben.

Nézzük fordítva: Kiléphetünk a ciklusból, ha szóközhöz érünk – ekkor nem teljesül az első feltétel –, vagy ha a szöveg utolsó karakteréhez értünk. Ha szóköz volt a szövegben, akkor egy újabb ciklusban előállítjuk a 2. keresztnevet és kiírjuk, ha nem, befejezzük a programot.


Ellenőrző kérdések

Mi lesz az alábbi szövegfüggvényekkel végzett műveletek eredménye?

  1. Ha sz = "süveges"; akkor sz.Trim('s') = .......
  2. Ha sz = "Messi a messiás"; akkor sz.IndexOf("si") = .......
  3. Ha sz = "Paróka"; akkor sz.Substring(2,2) = .......
  4. Ha sz = "Ouagadougou"; akkor sz.Substring(8) = .......
Kattints ide a megoldásért!
  1. Ha sz = "süveges"; akkor sz.Trim('s') = "üvege" (Levágja az 's' betűket az elejéről és a végéről)
  2. Ha sz = "Messi a messiás"; akkor sz.IndexOf("si") = 3 (A "si" karaktersorozat a 0-tól indexelt szöveg 3. indexén kezdődik a "Messi" szóban)
  3. Ha sz = "Paróka"; akkor sz.Substring(2,2) = "ró" (A 2-es indextől - ami az 'r' - számítva kivág pontosan 2 karaktert)
  4. Ha sz = "Ouagadougou"; akkor sz.Substring(8) = "gou" (A 8-as indextől - ami a 'g' - a string legvégéig mindent kivág)