Teste de informatică pentru liceu, articole C#, C/C++, PHP
Şirurile de caractere se manevrează cu ajutorul tipului string, tip care este un alt nume pentru clasa String. Din această cauză, există multe funcţii membre (metode) foarte puternice şi utile pentru gestiunea şirurilor. De asemenea, apar şi operatorii specifici şirurilor. Pentru simplitate şi deoarece nu am discutat încă despre clase, vom prefera să utilizăm termenul de funcţie în locul celui mai corect de metodă sau funcţie membră.
Operatorii
Clasa String defineşte următorii operatori:
Operatorii de atribuire şi concatenare sunt mult mai uşor de folosit decât greoaiele funcţii din C++ precum strcmp sau strcat. De asemenea, apare atribuirea, care substituie funcţia strcpy din C++. Iată mai jos un exemplu care ilustrează utilizarea lor.
static void Main(string[] args)
{
string s1, s2, s;
s1 = "Hello, ";
s2 = "world!";
s = s1 + s2; // concatenare
Console.WriteLine(s);
s1 = "casa";
s2 = "casca";
// operatorii de egalitate
if (s1 == s2) Console.WriteLine("Sunt siruri identice");
Console.WriteLine("Nu siruri identice");
if (s1 != s2) Console.WriteLine("{0} este diferit de {1}", s1, s2);
else Console.WriteLine("{0} si {1} sunt identice", s1, s2);
//operatorul de atribuire
s1 = s2;
Console.WriteLine(s1);
}
Secvenţele escape şi caracterele verbatim
Secvenţele escape le cunoaştem de la C++. Ele sunt utilizate pentru a defini anumite caractere speciale. Dintre acestea menţionez ' \n ' (enter), ' \t ' (tab), \\ (backslash), ' \' ' (apostrof). Dacă dorim să memorăm într-un string calea către un anumit fişier vom scrie astfel:
string caleFisier = "D:\\lucru\\documente\\fisier.txt";
Acelaşi lucru îl putem face cu ajutorul caracterelor verbatim astfel:
string caleFisier = @"D:\lucru\documente\fisier.txt";
Nu mai este nevoie deci să utilizăm secvenţe escape. Iată un alt exemplu:
string mesaj = "Primul \n al doilea";
string mesaj = @"Primul
al doilea";
Folosind şiruri verbatim, în loc de secvenţa escape '\n' am tastat enter în şir!
Indexatorul pentru string-uri. Proprietatea Length
Să menţionăm că dacă avem la dispoziţie un string, atunci putem afla lungimea şirului cu ajutorul proprietăţii Length (pe care am întâlnit-o la tablouri). De asemenea, putem parcurge şirul exact cum era parcurs şirul şi la C++. Şi tot ca în C++, şirul este indexat începând de la 0. Urmăriţi secvenţa de mai jos:
string s1;
s1 = "I am a Sith Lord";
Console.WriteLine("\nLungimea sirului : " + s1.Length);
Console.WriteLine("\nSirul inversat : ");
for (int i = s1.Length - 1; i >= 0; i--)
Console.Write(s1[i]);
Console.WriteLine();
Compararea şirurilor
Vom analiza pe scurt funcţiile Equals, CompareTo, StartsWith şi EndsWith în următoarea secvenţă:
string s2, s3, s4;
s2 = "abcdef";
s3 = "abcdef";
s4 = "abc";
if (s2.Equals(s3))
Console.WriteLine(s2 + " egal cu " + s3);
else
Console.WriteLine(s2 + " != " + s3);
if (s2 == s3) Console.WriteLine("\n egale ");
else Console.WriteLine("\n diferite ");
string[] text = { "start", "stop", "final", "epocal", "stare", "strop" };
Console.WriteLine("\nCuvinte care incep cu st: ");
foreach (string x in text)
if (x.StartsWith("st"))
Console.WriteLine(x);
Console.WriteLine("\nCuvinte care se termina cu al: ");
foreach (string x in text)
if (x.EndsWith("al"))
Console.WriteLine(x);
Compararea lui s2 cu s3 s-a făcut printr-o expresie de forma s2.Equals(s3)
care returnează o valoare logică după cum s2 este sau nu egal cu s3. Acelaşi lucru îl puteam face prin
String.Compare(s2, s3)
expresie care returnează tot o valoare logică. Am definit apoi un vector de string-uri numit text. Scopul este de a arăta cum se utilizează funcţia membră StartsWith cu ajutorul căreia putem determina care şiruri încep cu aceleaşi caractere. Asemănătoare este EndsWith care determină şirurile care se termină cu aceleaşi caractere.
Localizarea caracterelor în şir
Cu secvenţa de mai jos vom înţelege modul în care se pot utiliza funcţiile IndexOf, LastIndexOf, IndexOfAny pentru localizarea caracterelor într-un string. Toate aceste funcţii furnizează o valoare întreagă, poziţia unde s-a găsit caracterul în şir, sau -1 dacă nu s-a găsit.
string litere = "abcdefghijklmnabcdefghijklmn";
char[] litereCautate = { 'c', 'a', 't', 'h' };
Console.WriteLine("\nPrima aparitie a lui c: " + litere.IndexOf('c'));
Console.WriteLine("\nAparitia lui a dupa pozitia 3: " + litere.IndexOf('a', 3));
Console.WriteLine("\nCautare in subsir a lui b: " + litere.IndexOf('b', 4, 7));
Console.WriteLine("\nUltima aparitie a lui c: " + litere.LastIndexOf('c'));
//gasesc indicele primei aparitii a unui caracter din litereCautate in litere
Console.WriteLine("\nPrima aparitie: " + litere.IndexOfAny(litereCautate));
Console.WriteLine("\nPrima aparitie: " + litere.IndexOfAny(litereCautate, 5));
Linia 4, printr-o expresie de forma
litere.IndexOf('b', 4, 7)
caută în secvenţa de litere de la indicele 4 la 7 caracterul b. Pentru că acolo nu apare b, fucţia furnizează rezultatul -1. Cu funcţia LastIndexOf se realizează căutarea celei mai din dreapta poziţii a unui caracter. Ultima funcţie, IndexOfAny, foloseşte în căutare un vector de caractere. Atenţie, vectorul de caractere nu este un string!. Asupra vectorului nu se pot aplica funcţiile şi operatorii. Dar IndexOfAny foloseşte acest vector pentru a găsi prima apariţie a vreunui caracter din vector în string.
Extragerea subşirurilor
Cea mai simplă modalitate de a extrage un subşir intr-un şir este utilizarea funcţiei Substring. Cu ajutorul acesteia putem extrage o secvenţă începând de la o anumită poziţie până la sfârşitul şirului, sau de la o poziţie iniţială la una finală.
string sirExtras;
sirExtras = litere.Substring(10);
Console.WriteLine("\n\nEm extras din litere de la pozitia 10: " + sirExtras);
Console.WriteLine("Extrag 4 caractere de la poz 2: " + litere.Substring(2, 4));
Actualizarea şirurilor
Prin exemplul de mai jos punem în evidenţă utilitatea funcţiilor Replace, ToUpper, ToLower, Remove, Trim
string w = "ab91_Ecd555QWE";
string w1 = w.Replace('E', 'e'); // inlocuieste E cu e peste tot in sir
Console.WriteLine("\n\n" + w1);
Console.WriteLine("\nSirul w convertit la litere mari" + w.ToUpper());
Console.WriteLine("\nSirul w convertit la litere mici" + w.ToLower());
string s = "0123456789";
string x = s.Remove(4); // in string-ul x sunt memorate primele 4 caractere din s
Console.WriteLine(x);
x = s.Remove(2, 3); // in x este memorat sirul s fara caracterele de la pozitiile 2, 3, 4
Console.WriteLine(x);
string s = " Spatii la inceput si la sfarsit ";
Console.WriteLine("*" + s + "*");
s = s.Trim();
Console.WriteLine("*" + s + "*");
Aşa cum se înţelege foarte uşor din exemplu, funcţia Remove elimină dintr-un şir toate caracterele începând de la o anumită poziţie, sau elimină de la o poziţie un număr specificat de caractere. Funcţia Trim elimină dintr-un şir eventualele spaţii albe de la începutul şi de la sfârşitul unui şir, dar nu şi cele din interior. Similare cu Trim sunt funcţiile TrimEnd şi TrimStart care elimină spaţiile de la sfârşitul şi respectiv de la începutul unui şir.
Funcţia Split()
O ultimă funcţie pe care o discutăm în această lecţie este funcţia Split. Aceasta este foarte importantă, deoarece am văzut că toate datele care se citesc sunt preluate în string-uri. Aceste date trebuie apoi prelucrate. cu ajutorul funcţiei Split putem descompune un string în "cuvinte". Aceste cuvinte sunt stocate foarte uşor într-un vector de string-uri. Iată un prim exemplu
P1. Se citeşte de la tastatură un text format din cuvinte. Cuvintele sunt separate prin câte un spaţiu. Se cere să se afişeze toate cuvintele, fiecare pe câte un rând şi de asemenea să se determine lungimea maximă a unui cuvânt.
string text = "Acesta este un text. Se cere separarea sa in cuvinte";
string[] cuvinte = text.Split(' ');
int lgmax = 0;
foreach (string cuv in cuvinte)
{
if (lgmax < cuv.Length)
lgmax = cuv.Length;
Console.WriteLine(cuv);
}
Console.WriteLine("Lungimea maxima a unui cuvant este " + lgmax);
Funcţia Split are în acest exemplu un parametru, anume separatorul. Fiecare cuvânt din text este memorat în vectorul cuvinte.
P2. Se citeşte de la tastatură un şir de numere separate prin câte un spaţiu. Să se determine suma numerelor.
Vom separa numerele şi le vom converti apoi la int. Calculăm apoi suma numerelor. Rezolvarea este mai jos.
string text = "12 34 1 2 6 8";
string[] cuvinte = text.Split(' ');
int[] t;
int n;
n = cuvinte.Length;
t = new int[n];
for (int i = 0; i < n; i++)
t[i] = int.Parse(cuvinte[i]);
int suma = 0;
foreach (int x in t)
suma += x;
Console.WriteLine("Suma este " + suma);
Rezolvarea aceasta poate duce la funcţionarea defectuoasă în cazul în care între două numere din şirul iniţial sunt mai mulţi separatori unul lîngă celălalt; atunci în vectorul cuvinte apar memorate şi cuvinte de lungime zero (aceste cuvinte sunt cele care apar între doi separatori consecutivi), care nu pot fi convertite la int. Aceeaşi problemă este şi la rezolvarea lui P1. Pentru a evita apariţia cuvintelor vide, procedăm ca în aplicaţia P3.
P3. Se consideră un text în care cuvintele sunt separate prin: spaţiu . , : ; ? ! Între două cuvinte pot fi sunt unul sau mai mulţi separatori. Se cere descompunerea textului în cuvinte.
string text = "Ce-ti doresc eu tie, dulce Romanie?";
char[] separatori = { ' ', ',', '.', '?', '!', ':', ';' };
string[] cuvinte = text.Split(separatori, StringSplitOptions.RemoveEmptyEntries);
foreach (string cuv in cuvinte)
Console.WriteLine(cuv);
Utilizăm un vector de tip char în care memorăm separatorii. Funcţia Split se va apela apoi cu doi parametri, al doilea având rolul de a elimina cuvintele vide.
Probleme propuse
P4. Se citeşte într-un string un nume complet de persoană, în forma "Nume Prenume". Se cere să se obţină într-un string numele complet în forma "Prenume Nume". Exemplu: "Popescu Ioan". Se va obţine "Ioan Popescu".
P5. Se consideră că într-un string este memorată calea completă către un fişier, în forma "d:\\teste\\lucru\\CSharp\\fisier.txt". Se cere să se afişeze pe câte un rând fiecare folder care apare în această cale.
P6. Se citeşte o expresie aritmetică formată din numere naturale între care se află semnele + şi -. Se cere să se evalueze aceastpă expresie. Exemplu: E="23+7-22". Se va afişa 8.
P7. Se citeşte un şir format din litere mari şi mici. Se cere eliminarea tuturor literelor mari din şir, apoi să se afişeze pentru fiecare literă mică din şir de câte ori apare.
Dan Pracsiu deţinător www.dponline.ro
Profesor, Liceul Teoretic "Emil Racoviță" Vaslui
Membru în Comisia Naţională a Olimpiadelor de Informatică
Pasiuni: istoria, călătoriile, fotografia, muzica clasică
Adi 8-2-2014 11:3:43
In lucrul cu siruri, este recomandata si clasa stringBuilder, mai ales atunci cand un sir isi schimba des valoarea stocata pe parcursul executiei programului!