Am definit o clasa care permite calcului cu numere mari implementata cu templated string si pentru a permite o accesibilitate user-friendly, operatori aritmetici au fost de asemenea adaptati pentru a permite calculul. Din nefericire avand in vedere ca C++
este limitat de arhitectura procesorului pentru a executa calcule in anumite intervale, consider ca va fi de folos aceasta clasa.
Avem header-ul unde se afla definitile functilor constructorul si destructorul.
#pragma once #include<string> #include<algorithm> #include<vector> #include<utility> #include<iostream> using namespace std; class BigInt { private: string s; bool mai_mic_sau_egal(string s,string ss); bool mai_mic(string s,string ss); bool mai_mare(string s, string ss); bool mai_mare_sau_egal(string s,string ss); string sx(string s,string ss); string dx(string s,string ss); string px(string s,string ss); string pow(string s,string ss); pair<string,string> ddx(string s,string ss); void convert_to_int(); void convert_to_float(); public: BigInt(string n); ~BigInt()=default; bool operator<(BigInt ss); bool operator<=(BigInt ss); bool operator==(BigInt ss); bool operator>(BigInt ss); bool operator>=(BigInt ss); void operator=(string ss); void operator=(BigInt ss); string operator+(BigInt ss); string operator-(BigInt ss); string operator*(BigInt ss); string operator^(BigInt ss); operator int(); operator float(); //if you are sure the number is within c++ bounds you can convert it to the wanted value int to_int(); double to_double(); long long to_ll(); unsigned long long to_ull(); friend ostream& operator<<(ostream& os, BigInt &s); friend istream& operator>>(istream& is, BigInt &s); pair<string,string> operator/(BigInt ss); //returns a pair containing on first the quotient and on second the reminder of the division string sqrt(); };
Iar aici implementarea functilor impreuna cu functile de tip get/set.
#include "BigInt.h" BigInt::BigInt(string n){ s=n; } string BigInt::operator+(BigInt ss) { return sx(s,ss.s); } string BigInt::operator*(BigInt ss) { return px(s,ss.s); } void BigInt::operator=(string ss) { s=ss; } string BigInt::operator-(BigInt ss) { return dx(s,ss.s); } bool BigInt::operator<(BigInt ss) { return mai_mic(s,ss.s); } string BigInt::sqrt() { string rezerve=s; string rez,temp,aux,p; int ok=0,k,o=0,c=0,l; if(s[0]=='-') ok=1,s.erase(s.begin()+0); if(s.find('.')==-1) { l=s.size(); if(s.size()%2) k=s.size()/2+1; else k=s.size()/2; } else { k=s.find('.'),s.erase(s.begin()+k); l=k; if(k%2) k=k/2+1; else k/=2; } s+="0000000000000000"; if(l%2) { o=1; temp+=s[0]; while(c<9) { aux+=to_string(c++); p=px(aux,aux); if(!mai_mic_sau_egal(p,temp)) break; aux.pop_back(); } rez+=--aux[0]; p=dx(temp,px(aux,aux)); while(p[0]=='0') p.erase(p.begin()+0); if(p!="") temp=p; else temp=""; } for(int i=o;i<s.size();) { c=-1; temp+=s[i++]; temp+=s[i++]; if(temp=="00") { rez+='0'; temp=""; continue; } if(aux!="") aux=px(rez,"2"); else { while(c<9) { c++; if(c==10) { aux+=to_string(--c); p=px(aux,aux); break; } else aux+=to_string(c); p=px(aux,aux); if(!mai_mic_sau_egal(p,temp)) { if(c==9) c--; break; } if(c!=9) aux.pop_back(); } if(c==9) rez+=to_string(c); else rez+=--aux[0]; p=dx(temp,px(aux,aux)); while(p[0]=='0') p.erase(p.begin()+0); if(p!="") temp=p; else temp=""; continue; } while(c<9) { c++; if(c==10) { aux+=to_string(--c); p=px(aux,to_string(c)); break; } else aux+=to_string(c); p=px(aux,to_string(c)); if(!mai_mic_sau_egal(p,temp)) { if(c==9) c--; break; } if(c!=9) aux.pop_back(); } if(c==9) rez+=to_string(c); else rez+=--aux[aux.size()-1]; c=aux[aux.size()-1]-'0'; p=dx(temp,px(aux,to_string(c))); while(p[0]=='0') p.erase(p.begin()+0); if(p!="") temp=p; else temp=""; if(rez.size()-k>8 && k<rez.size()) break; } rez.insert(rez.begin()+k,'.'); c=rez.find('.'); while(rez.size()-1-c>8) rez.pop_back(); if(ok) rez+='i'; s=rezerve; return rez; } string BigInt::sx(string s,string ss) { int ls=0,lss=0,o1=0,o2=0,lmax,len; if(s.find('.')!=-1) ls=s.find('.'),o1=1; if(ss.find('.')!=-1) lss=ss.find('.'),o2=1; lmax=max(ls,lss); len=max(s.size(),ss.size()); if(o1) { s.erase(s.begin()+ls),ls--; ls=s.size()-1-ls; } if(o2) { ss.erase(ss.begin()+lss),lss--; lss=ss.size()-1-lss; } len=max(s.size(),ss.size()); if(ls>lss) for(int i=1;i<=ls-lss;i++) ss+='0'; else if(lss>ls) for(int i=1;i<=lss-ls;i++) s+='0'; int t=0; if (s.length()>ss.length()) swap(s,ss); string str=""; int n1=s.length(),n2=ss.length(); int dif=n2-n1; for(int i=n1-1;i>=0;i--) { int sum=((s[i]-'0')+(ss[i+dif]-'0')+t); str.push_back(sum%10+'0'); t=sum/10; } for(int i=n2-n1-1;i>=0;i--) { int sum=((ss[i]-'0')+t); str.push_back(sum%10+'0'); t=sum/10; } if(t) str.push_back(t+'0'); reverse(str.begin(),str.end()); if(ls || lss) str.insert(str.begin()+lmax+(str.size()-len),'.'); return str; } string BigInt::dx(string s,string ss) { int ls=0,lss=0,o1=0,o2=0,lmax,len; if(s.find('.')!=-1) ls=s.find('.'),o1=1; if(ss.find('.')!=-1) lss=ss.find('.'),o2=1; lmax=max(ls,lss); len=max(s.size(),ss.size()); if(o1) { s.erase(s.begin()+ls),ls--; ls=s.size()-1-ls; } if(o2) { ss.erase(ss.begin()+lss),lss--; lss=ss.size()-1-lss; } len=max(s.size(),ss.size()); if(ls>lss) for(int i=1;i<=ls-lss;i++) ss+='0'; else if(lss>ls) for(int i=1;i<=lss-ls;i++) s+='0'; int ok=0; if(mai_mic_sau_egal(s,ss) && s!=ss) swap(s,ss),ok=1; string str = ""; if(s[0]=='0') return "0"; int n1=s.length(),n2=ss.length(); int dif=n1-n2; int t=0; for(int i=n2-1;i>=0;i--) { int sub=((s[i+dif]-'0')-(ss[i]-'0')-t); if(sub<0) sub+=10,t=1; else t=0; str.push_back(sub+'0'); } for(int i=n1-n2-1;i>=0;i--) { if(s[i]=='0'&&t) { str.push_back('9'); continue; } int sub=((s[i]-'0')-t); if (i>0||sub>0) str.push_back(sub+'0'); t=0; } reverse(str.begin(),str.end()); if(ls || lss) str.insert(str.begin()+lmax+(str.size()-len),'.'); while(str[0]=='0' && str.size()>1) str.erase(str.begin()+0); if(ok) str.insert(str.begin()+0,'-'); return str; } string BigInt::px(string s,string ss) { int ls=0,lss=0,o1=0,o2=0,ls1=0,ls2=0,lmax; if(s.find('.')!=-1) ls=s.find('.'),o1=1,ls1=ls; if(ss.find('.')!=-1) lss=ss.find('.'),o2=1,ls2=lss; if(o1) ls1=s.size()-1-ls1; if(o2) ls2=ss.size()-1-ls2; lmax=ls1+ls2; if(o1) { s.erase(s.begin()+ls),ls--; ls=s.size()-1-ls; } if(o2) { ss.erase(ss.begin()+lss),lss--; lss=ss.size()-1-lss; } if(ls>lss) for(int i=1;i<=ls-lss;i++) ss+='0'; else if(lss>ls) for(int i=1;i<=lss-ls;i++) s+='0'; int n1=s.size(); int n2=ss.size(); if(n1==0||n2==0) return "0"; vector<int> rez(n1+n2,0); int i_n1=0; int i_n2=0; for(int i=n1-1;i>=0;i--) { int t=0; int n1=s[i]-'0'; i_n2=0; for(int j=n2-1;j>=0;j--) { int n2=ss[j]-'0'; int sum=n1*n2+rez[i_n1+i_n2]+t; t=sum/10; rez[i_n1+i_n2]=sum%10; i_n2++; } if(t>0) rez[i_n1+i_n2]+=t; i_n1++; } int i=rez.size()-1; while(i>=0 && rez[i]==0) i--; if(i==-1) return "0"; string sss=""; while(i>=0) sss+=to_string(rez[i--]); if(ls1 || ls2) sss.insert(sss.begin()+(sss.size()-1-lmax),'.'); return sss; } bool BigInt::mai_mic_sau_egal(string s,string ss) { int n1=s.length(),n2=ss.length(); if(n1<n2) return true; if(n1>n2) return false; for(int i=0;i<n1;i++) { if(s[i]<ss[i]) return true; else if(s[i]>ss[i]) return false; } return true; } void BigInt::operator=(BigInt ss) { s=ss.s; } pair<string,string> BigInt::ddx(string s, string ss) { string rest="0"; int m=2,ls=0,lss=0,o1=0,o2=0,p1=0,p2=0; if(s[0]=='-' || ss[0]=='-') { m=1; if(s[0]=='-' && ss[0]!='-') p1=1; if(s[0]!='-' && ss[0]=='-') p2=1; } if(s[0]=='-' && ss[0]=='-') m=0; if(s[0]=='-') s.erase(s.begin()+0); if(ss[0]=='-') ss.erase(ss.begin()+0); if(s.find('.')!=-1) ls=s.find('.'),o1=1; if(ss.find('.')!=-1) lss=ss.find('.'),o2=1; if(o1) { s.erase(s.begin()+ls),ls--; ls=s.size()-1-ls; } if(o2) { ss.erase(ss.begin()+lss),lss--; lss=ss.size()-1-lss; } if(ls>lss) for(int i=1;i<=ls-lss;i++) ss+='0'; else if(lss>ls) for(int i=1;i<=lss-ls;i++) s+='0'; if(ss=="1") { return make_pair(s+".000000","0"); } if(s=="0") { return make_pair("0.000000","0"); } string rez; if(mai_mic(s,ss)) rez="0."; if(mai_mic(s,ss)) rest=s; while(mai_mic(s,ss)) { s+='0'; if(!mai_mic(s,ss) || (rez.size()-1-rez.find('.')==6 && rez.find('.')!=-1)) break; rez+='0'; } if(rez.find('.')!=-1) { if(rez.size()-1-rez.find('.')==6) return make_pair(rez,rest); else if(rez.size()-1-rez.find('.')<6 && rez.find('.')!=-1) { string temp; while(rez.size()-1-rez.find('.')<6) { int ap=0; while(!mai_mic(s,ss)) s=dx(s,ss),ap++; rez+=to_string(ap); s+='0'; } return make_pair(rez,rest); } } string temp; int j,k=s.size(),ap=0; s+="000000"; for(int i=0;i<s.size() && mai_mic(temp,ss);i++) temp+=s[i],j=i+1; while(!mai_mic(temp,ss)) temp=dx(temp,ss),ap++; rez+=to_string(ap); for(;j<s.size();j++) { if(rez.find('.')!=-1 && rez.size()-1-rez.find('.')==6) { if(m==1) rez.insert(rez.begin()+0,'-'); if(((p1 && !p2) || !m) && rest!="0") rest.insert(rest.begin()+0,'-'); return make_pair(rez,rest); } ap=0; if(j==k) { rez+='.'; rest=temp; ls=max(ls,lss); if(ls) { rest.insert(rest.begin()+rest.size()-ls,'.'); if(rest[0]=='.') rest.insert(rest.begin(),'0'); } } if(temp[0]=='0') temp="",temp+=s[j]; else temp+=s[j]; if(temp[0]=='0') { rez+='0'; continue; } while(mai_mic(temp,ss) && j<s.size()) { rez+='0',temp+=s[++j]; if(rez.size()-1-rez.find('.')==6 && rez.find('.')!=-1) { if(m==1) rez.insert(rez.begin()+0,'-'); if(((p1 && !p2) || !m) && rest!="0") rest.insert(rest.begin()+0,'-'); return make_pair(rez,rest); } } while(!mai_mic(temp,ss)) temp=dx(temp,ss),ap++; rez+=to_string(ap); } if(m==1) rez.insert(rez.begin()+0,'-'); if(((p1 && !p2) || !m) && rest!="0") rest.insert(rest.begin()+0,'-'); return make_pair(rez,rest); } pair<string, string> BigInt::operator/(BigInt ss) { return ddx(s,ss.s); } bool BigInt::mai_mic(string s, string ss) { int n1=s.length(),n2=ss.length(); if(n1<n2) return true; if(n1>n2) return false; for(int i=0;i<n1;i++) { if(s[i]<ss[i]) return true; else if(s[i]>ss[i]) return false; } return false; } bool BigInt::operator<=(BigInt ss) { return mai_mic_sau_egal(s,ss.s); } bool BigInt::operator==(BigInt ss) { return s==ss.s; } bool BigInt::mai_mare(string s, string ss) { int n1=s.length(),n2=ss.length(); if(n1<n2) return false; if(n1>n2) return true; for(int i=0;i<n1;i++) { if(s[i]<ss[i]) return false; else if(s[i]>ss[i]) return true; } return false; } bool BigInt::mai_mare_sau_egal(string s, string ss) { int n1=s.length(),n2=ss.length(); if(n1<n2) return false; if(n1>n2) return true; for(int i=0;i<n1;i++) { if(s[i]<ss[i]) return false; else if(s[i]>ss[i]) return true; } return true; } bool BigInt::operator>(BigInt ss) { return mai_mare(s,ss.s); } bool BigInt::operator>=(BigInt ss) { return mai_mare_sau_egal(s,ss.s); } string BigInt::pow(string s, string ss) { if(ss=="0") return "1"; string rez="1"; for(string i="1"; mai_mic_sau_egal(i,ss);i=sx(i,"1")) rez=px(rez,s); return rez; } string BigInt::operator^(BigInt ss) { return pow(s,ss.s); } void BigInt::convert_to_int() { int point=s.find('.'); if(point!=-1) s.resize(point); } void BigInt::convert_to_float() { int point=s.find('.'); if(point==-1) s+='.'; for(int i=1;i<=15;i++) s+='0'; } BigInt::operator int() { convert_to_int(); return 0; } BigInt::operator float() { convert_to_float(); return 0; } ostream &operator<<(ostream &stream, BigInt& ss) { cout<<ss.s; return stream; } istream &operator>>(istream &is, BigInt& ss) { is>>ss.s; return is; } int BigInt::to_int() { return stoi(s); } double BigInt::to_double() { return stod(s); } long long BigInt::to_ll() { return stoll(s); } unsigned long long BigInt::to_ull() { return stoull(s); }
Si programul driver cu exemple demo de test.
#include<bits/stdc++.h> #include "BigInt.h" using namespace std; int main() { BigInt s("400.5"); // or s=400 is the same either by assignation or by constructor BigInt ss("50"); cout<<s+ss<<endl; cout<<s-ss<<endl; cout<<s*ss<<endl; pair<string,string> p=s/ss; cout<<p.first<<" "<<p.second<<endl; cout<<s.sqrt()<<endl; s="3.5"; s.operator int(); cout<<s<<endl; s.operator float(); cout<<s<<endl; s="3"; ss="3"; cout<<(s^ss)<<endl; ss=s; cin>>s; cout<<s; cout<<s.to_double(); }
End
Map este un container associativ care are formatul <Key,Value>
de diferite tipuri de date, cu key unic ordonat crescator, inclus in biblioteca map
.
exemplu
map<string,int> nume -> pentru de ex a numara cuvinte.
In limbaj comun, se poate folosi ca un vector de frecventa pentru a numara o anumita cheie pe valoarea corespunzatoare.
Pentru a adauga elemente in acest tip de date se va folosi operatorul []
.
ex: m[5]=1;
Pentru a parcurge map-ul nefiind un container secvential, nu se poate accesa cu random access iterator si va fi nevoie de un iterator specific mapului care sa parcurga map-ul in segmentul begin->end.
map<int,int> m; map[1]=2; map[2]=5; map[1]++; map[3]=10; map<int,int>::iterator it; for(it=m.begin();it!=m.end();it++) cout<<it->first<<" "<<it->second<<endl;
Va afisa:
1 3 2 5 3 10
In cazul in care se foloseste aceelasi aspect pentru stringuri:
map<string,int> m; map["apa"]=2; map["mar"]=5; map["ger"]++; map["apa"]=10; map<int,int>::iterator it; for(it=m.begin();it!=m.end();it++) cout<<it->first<<" "<<it->second<<endl;
Va afisa:
apa 10 ger 1 mar 5
Cum este un container STL
exista functii comune adaptate pentru acest container care pot fi vizualizate in STL Vector.
De asemenea am atasat un template facut de mine care implementeaza map, pentru observarea operatilor care sunt facute, dar este recomandata folosirea map din STL deoarece sigur este mai slefuita.
Listele din STL sunt liste alocate dinamic dublu înlănțuite și circulare. Acestea au avantajul că ștergerile și inserările se fac în O(1)
ÎNSĂ ele nu sunt secvențiale astfel încât nu se pot accesa la o poziție oarecare (random-access), fiind nevoie să se parcurgă până la acea poziție.
Ca și celelalte containăre STL, sunt vide inițial dacă nu cumva se inițializează.
list<int> v;
list<int> v; v.push_back(5); // v={5}; v.pop_back(); // v={};
Parcurgerea se realizează cu un iterator specific.
list<tip_de_date>::iterator it;
Diferența dintre iteratorii de la alte containăre unde iteratorii se devalizează în momentul alterări conținutului din interiorul containerului, în momentul inserării pe poziția iteratorului, el rămâne pe elementul care avea inițial poziția unde s-a inserat.
list<int> v={2,4,6}; list<int>::iterator it=v.begin(); //*it=2 it++; //incrementez | avansez advance(it,1); //*it=4 v.insert(it,10); //v={2,10,4,6}, *it=4
IAR În cazul ștergerii iteratorul se invalidează fiind nevoie reparcurgerea pana la acea pozitie SAU folosirea unui iterator secundar care va fi folosit pentru reținerea adresei imediat anterioare sau următoare.
list<int> v={2,4,6,5,9,21,34,35,74,101}; list<int>::iterator it=v.begin(),itt=v.begin(); for(;it!=v.end();it++) //*it=2 if(*it%2==0) { itt=it,itt++,v.erase(it); //it==NULL it=itt; } // v={5,9,21,34,101}
Atentie v.end()
este ultima pozitie din listă, care este nullă ASTFEL ÎNCÂT nu se consideră element v.end()
deși când it=v.end()
și se incerementează ajunge înapoi la v.begin()
deci este un caz particular.
Exemple de liste:
list<pair<int,int>> v={{1,2},{2,10}}; list<pair<int,int>>::iterator it=v.begin();
Se acesează cu:
it->first, it->second;
SAU
struct data { string s; int n; } list<data> v; list<data>::iterator it; it->s,it->n;
.front() - primul element .back() - ultimul element .clear() - golește lista .emplace() - membru vechi depreciate datorita aparitiei make_pair() .splice() - membru care transferă elementele dintr-o listă în alta, le șterge din sursa și le adauăgă la poziția x în cealaltă listă. .remove() - elimină elementele cu o anumită valoare x .remove_if() - elimină elementele care respectă o condiție specificată .unique() - elimină elementele duplicate. sort() - nu are nevoie de introducere reverse - inverseaza .merge() - interclasează 2 liste ordonate crescător // v.merge(w)
Clasa String
specific C++
este un container pentru șirurile de caractere alocat dinamic. Deși se boicotează folosirea claselor, există multe avantaje în utilizarea lor, altfel ar fi programare în C
nu C++
. Caracteristicile unui programator bun sunt creerea unui algoritm corect, eficient și concis. STL fiind una dintre cele mai folosite biblioteci alături de biblioteca adiționala Boost
.
În general containărele au membrii comuni ca și nume, de exemplu .size()
are aceeași denumire ca la vector
și se mai regăsesc și la alte containăre de specialitate. Vezi Vector.
In momentul declarari șirul este initial vid.
string s;
El se poate construii static initial.
string s(5,'a') // lungime 5, poziții 0-4 umplute cu 'a'.
Se realizează cu ajutorul operatorilor +,=,==,!=,>,<,>=,<=
.
Citire și parcurgere și cautare
string s,voc="aeiou"; int ap=0; cin>>s // citirea pana la spatiu | getline(cin,s); // citirea unei linii; for(int i=0;i<s.size();i++) if(voc.find(s[i])!=-1) // căutăm în voc caracterul s[i], dacă el se gasește returnează poziția altfel returnează @-1@. ap++; // numărăm numărul de vocale din șir. cout<<ap;
ATENTIE. În cazul citirii normale a unui șir sau număr trebuie avansat pe următoarea linie inaintea citirii cu getline
se extrage caracterul '\n'
cu cin.get()
.
Atribuire
string s; s="aeiou";
Concatenare
string s,ss; s+="ae" // s="ae"; if(s=="ae") // se verifică dacă s="ae" ss=s; // copiere in ss a lui s for(int i=0;i<s.size();i++) s+=to_string(i); // se transforma din int in sir de caractere si se adauga la final. deci sirul devine s="ae01"; s+=ss; // s="ae01ae"; s=""; // s devine gol
Comparare Lexicografică
Afisăm lexicografic 2
șiruri.
string s="ar",ss="ae"; if(s<ss) swap(s,ss); // interschibăm cout<<s<<" "<<ss;
string s="aeiou"; s.pop_back() // s="aeio"
Inserare
for(int i=0;i<s.size();i++) s.insert(s.begin()+i+1,s[i]+1),i++; // Inserarea dupa fiecare caracter, caracterul imediat urmator lexicografic.
Stergerea
voc="aeiou"; for(int i=0;i<s.size();i++) if(voc.find(s[i])!=-1) s.erase(s.begin()+i),i--; // Stergerea vocalelor.
Trimiterea ca parametrii la functii a containerlor stl, se face ca la variabile obisnuite, trimis obisnuit se face o copie altfel cu adresă &
modifică direct.
Fara Adresă
void stergere(string s) { s=""; } int main() { string s="aeiou"; stergere(s); // s="aeiou" }
Cu Adresă
void stergere(string &s) { s=""; } int main() { string s="aeiou"; stergere(s); // s="" }
Returnarea Unui Șir De Caractere
string stergere(string s) { s=""; return s; } int main() { string s="aeiou"; s=stergere(s); // s="" }
Inlocuieste
Este o noțiune nouă, înlocuiște de la poziția i
, n
caractere cu șirul ss
.
string s="aeiou",ss="UNU"; s.replace(2,3,ss); //s=aeUNU
char s[500]; string str="aeiou"; strcpy(s,str.c_str());
string s; vector<string> v; // vector de stringuri; getline(cin,s); istringstream b(s); // buffer de stringuri inclus in I/O <sstream> sparge implicit pe spații for(string w;b>>w;) // cat timp exista cuvinte in buffer citim in w v.push_back(w); // punem in vector sort(v.begin(),v.end()) // lexicografic || sort(v.begin(),v.end(),greater<string>()); // sortul din algorithm
string s="aea"; //s.find('a')=0 //s.rfind('a')=2
string s="aeiou",ss; ss=s.substr(2,3); // de la poziția 2, 3 caractere. //ss="iou"
string s="aeiou"; //s.front()='a' , s.back()='u'
DE ASEMENEA .back()
există și pentru vector
.
vector<int> v={5,6,10}; //v.back()=10
Un număr x
se convertește în șir de caractere cu funcția to_string()
introdusă în C++17
, se poate să nu o compileze un standard mai vechi.
int x=10; string s; s=to_string(x),s+=to_string(x); // s="1010";
Se foloseste reverse
din <algorithm>
.
string s="aeiou"; reverse(s.begin(),s.end()); //s="uoiea"
Se folosesc urmatoarele functii:
string s="105"; int x; double y; long long z; unsigned long long w; x=stoi(s); //x=105; y=stod(s); //y=105; z=stoll(s); //z=105; w=stoull(s); //w=105;
<cctype>
de schimbare sau verificare a caracterelor individualestring s="AeUr"; for(int i=0;i<s.size();i++) s[i]=tolower(s[i]); //s="aeur" for(int i=0;i<s.size();i++) s[i]=toupper(s[i]); //s="AEUR"
isalnum(char) // daca este litera sau cifre isalpha(char) // daca este litera isspace(char) // daca este spatiu sau caracter separator cum ar fi '\n' iscntrl(char) // daca caracterul este caracter de control cum ar fi '\n' isdigit(char) // daca este cifre isgraph(char) // daca caracterul se poate printa islower(char) // daca este litera mica isupper(char) // daca este litera mare isxdigit(char) // daca este cifra din reprezentarea unui numar in baza 16 ispunct(char) // daca este semn de punctuatie
De asemenea se pot cauta in sir de la inceput spre sfarsit sau invers, primul caracter din sirul de caractere specificat ca argument sau absenta lui.
string s="aebiouq",ss="ierot"; // s.find_first_of(ss)=1 (e) // s_find_last_of(ss)=4 (o) // s.find_first_not_of(ss)=2 (b) // s.find_last_not_of(ss)=6 (q)
Vectorii sunt containăre alocate dinamic exact ca tablourile statice având o organizare secvențială a elementelor.
Pentu declararea unui vector trebuie inclusă biblioteca <vector>
unde se află funcții de manipulare a acestui container.
vector<tip_date> nume;
exemplu
vector<int> v;
Inițial vectorul este gol având 0
poziții. Se obișnuiește ca în lucrul cu tablouri statice din C
să se prealoce numărul de poziții pentru cât se crede că va fi nevoie și folosirea poziților de la 1
. Ambele sunt obiceiuri proaste deși poate face problemele de numărare mai ușoare se pierde o poziție în zadar care deși pare puțină memorie câte un pic de aici și deacolo într-un program mai complex și se adună iar despre prealocare nu trebuie să mai zic, ori prea multă memorie alocata inutil pentru un caz în care se folosesc doar 10 poziții sau unul mult prea mare, de aceea este folositor o astfel de clasa.
.
for(int i=1;i<=10;i++) v.push_back(i);
for(int i=0;i<v.size();i++) cout<<v[i]<<" "; | cout<<v.at(i)<<" ";
pre.
1 2 3 4 5 6 7 8 9 10
.at()
este un membru de random-access
specific vectorului care înlocuiește operatorul [] având avantajul că dacă se întreabă de o poziție invalidă aruncă excepție.
.size()
este un membru care reține câte elemente sunt în vector. Atenție Elementele sunt mereu indexate de la 0, astfel .size() va fi mereu o poziție invalidă, ex. v={5,2,1}, v[0]=5,v[1]=2,v[2]=1
. .size()=3
, sunt 3 elemente însă de la 0-2
sunt 3
elemente.
Ce este un Iterator?
Un iterator este un pointer la adresă specific fiecărui tip de container pentru parcurgerea lui din adresă în adresă.
Cum funcționeaza?
Iteratorul se declară pentru fiecare tip de container și fiecare tip de date a containerului. NU se pot folosi pentru alte containere de alt tip. După declarare se atribuie adresa de început .begin()
și se se incrementează, vectorul fiind declarat secvential se va oprii atunci cand se termină segmentual pe care este declarat vectorul.
Fiecare vector are 2 membrii .begin(), .end()
.
.begin()
are adresa de început a vectorului și .end()
adresa de sfârșit a vectorului care se află cu o poziție după ultimul element și ea este o poziție invalidă care nu face parte din vector
. Fiecare element se parcurge prin dereferinta iteratorului.
! Orice operatiune de modificare a secventei din interiorul vectorului va devaliza iteratorul deoarece spatiul va fi realocat.
Exemplu
vector<int> v; vector<int>::iterator it; for(it=v.begin();it!=v.end();it++) cout<<*it<<" ";
Mai Mult
Se poate forta prin instructiunea auto
să determine ce fel iterator este nevoie pentru a parcurge containerul.
vector<int> v; for(auto i:v) cout<<i<<" ";
pop_back())
Considerând că avem elementele de la 1-10
în vector. Vom șterge 5 elemente astfel:
while(v.size()>5) v.pop_back();
vector<int> v(100)
Vector cu 100 de elemente cu pozitii de la 0-99 cu valoarea 0 implicită.
vector<int> v(100,1)
Vector cu 100 de elemente cu pozitii de la 0-99 cu valoarea 1.
Schimbarea pe parcurs a lungii se face ori cu push_back
ori cu pop_back
care mareste sau micsorează marimea ori de cate ori este chemata functia. Însă ea poate fi facută și manual cu funcția .resize()
.
vector<int> v; // 0 elemente v.push_back(5) // 1 element {5} v.resize(2) // 2 elemente {5,0} v.push_back(6), v.push_back(7) // 4 elemente {5,0,6,7} v.resize(3) // 3 elemente {5,0,6} v.resize(10) // 10 elemente {5,0,6,0,0,0,0,0,0,0}
Acest lucru se poate folosi in cazul vectorilor de fecventă.
vector<int> v; int n; cin>>n; for(int i=1;i<=n;i++) { cin>>x; if(x>=v.size()) v.resize(x+1) v[x]=1; }
.erase()
, .insert()
.Pentru inserarea pe poziția 2
a numarului 10
considerând că aceasta există trebuie trimis pointer de la sfârșit sau începtul vectorlui.
v.insert(v.begin()+2,10);
La fel și la stergere.
v.erase(v.begin()+2);
Pentru stergerea tuturor elementelor pare din vector.
for(int i=0;i<v.size();i++) if(v.at(i)%2==0) v.erase(v.begin()+i),i--;
Pentru inserarea dupa fiecare numar par dublul lui.
for(int i=0;i<v.size();i++) if(v.at(i)%2==0) v.insert(v.begin()+i+1,v.at(i)*2),i++;
vector<vector<int>> v;
// matricivector<string> v;
// vector de cuvintevector<pair<int,int>> v;
// vector de perechi, elementele se aceseaza ca fiind de exemplu v[1].first, v[1].second
dintr-o pereche.