Сайн байцгаана уу?
Энэ удаагийхаа постоор C++ -н ерөнхий мэдлэгээ дээшлүүлэх, боломжит функцууд мөн уг хэлэнд аль хэдийнээ бичигдцэн байдаг өгөгдөлийн бүтэцүүдийг хэрхэн ашиглах талаар бичье. Маш амархан энгийн зүйлүүд байгаа.
Юуны өмнө заагчийн талаар маш товч тодорхой тайлбарлая.
Ямар ч хамаагүй төрлийн хувьсагч байг. Энэ хувьсагч нь тухайн төрлийн нэг утгыг хадгалдаг, бид бүгдээрэй үүнийг мэднэ. Тэгвэл тухайн энэ хадгалагдаж байгаа утга маань компьютерт санах ой гэх төхөөрөмжинд, энэ төхөөрөмж нь бидний мэдэх РАМ, хадгалагддаг. РАМ нь тодорхой хэмжээний утгуудыг хадгална, эдгээрийгээ 0-ээс эхлээд дугаарлая. Тэгэхээр програмд зарласан болон хэрэглэгдэж байгаа бүх өгөгдөл, утгууд санах ойд хадгалагдах ба мөн санах ойд хаана хадгалагдаж байгаагаас хамаараад бүгд санах ойн дугаартай байх нь. ЗААГЧ бол яг энэ дугаарыг л авч явдаг нэгэн төрлийн хувьсагч юм.
Анхаарах зүйл нь заагч нь тухайн зааж байгаа хаяганд байрлах утгийн төрөлтэй яг адилхан байх ёстой.
Заагч төрөл зарлахдаа тухайн заагчийн төрөлийг тавиад од тэгээд хувьсагчийн нэр.
int *intZaagch; //int turuliin zaagch.
char *charZaagch; //char turuliin zaagch.
Ямар нэгэн энгийн төрлийн хувьсагч байг. Уг утгын санах ойн дугаарт хандахдаа тухайн хувьсагийн нэрний өмнө & тавьж хандна, харин ямар нэгэн заагч хувьсагийн зааж байгаа хаяг дахь утганд хандахдаа од тавиад заагийн нэрийг тавьдаг, дараах жишээг харна уу.
int a = 20; //engiin huvisagch.
int *intZaagch; //zaagch huvisagch.
intZaagch = &a; //intZaagch a-n zaagch bolj bn.
cout << a << " " << &a << " " << intZaagch << " " << *intZaagch << endl;
*intZaagch = 10;
cout << a; // end 10-g hevlene. Yagaad gevel *intZaagch = 10 ni tuhain sanah oid bga utgiig 10 bolgoj bga ba ene ni a-n utga bsn.
Iterator:
Итератор бол заагч. Обьект хандалтад програмчлалд тодорхой ганцхан зүйлээс бүтсэн төрөл гэж байдаггүй. Бүх зүйл ямар нэгэн өөрсдийн гэсэн хэд хэдэн төрөл зүйл болон туслах функцуудтэй зүйлүүд нийлж нэг обьект үүсгэдэг. Олон ийм обьектуудтай массив байг. Бид энэ массивын бүх обьектоор гүйж боловсруулалт хийх гэж байгаа гэж бодъё. Гэвч бид ямар төрөл юм гэдэгийг мэдэхгүй. Иймээс итератор хэрэглэж шаардлага гарна, зөвхөн санах ойд хаана байгаагаар нь гүйгээд хаягаар нь дамжиж орно. Ерөнхий ойлголт авсан байх гэж үзээд түр хойш нь тавиад жишээгээр сайн хараад авна уу.
Дараагийн заах зүйл Макро директив ашиглах. Макро директив нь
#define orlogch orluulagch
гэсэн форматтай байдаг ба үүнийг ухаалаг ашигласнаар програмын код маш бага болдог. Мөн бас нэг давуу тал нь компайлер тухайн код-г компайлдахаас өмнө Preprocessing гэсэн алхам байдаг ба энд хийгддэг зүйлүүдийн нэг нь код-г шалгаж orlogch таарах юм бол orluulagch-г өөрөөр нь шууд сольж тавьдаг. Энэ нь компайлдах, оптимиз хийхэд шууд нөлөөлдөггүй тул үр дүн сайтай хурдан ажилладаг програм үүсэхэд тустай байдаг. Жишээ нь бид тогтмол утга const double INF = 1e10;. Энд const double гэсэн 2 түлхүүр үгнүүд компайлдах явцад өөр зүйл хийлгэдэг. Энэ удаагийн пост компайлер, оптимиз хэрхэн ажилдаг талаар биш тул үүнээс цааш тайлбарлах дэмий байх. Товчхондоо бол дээрх бичиглэлээс мактор дирэктив ашигласан нь хамаагүй хурдан шүү. #define INF 1e10
STL-рүү орохоос өмнө дахиад нэг зүйлийг анхааруулах үүднээс хэлье. Бид ихэнх тохиолдолд аргументтэй функц бичдэг. Энэ нь тухайн функц дуудагдаж ашиглагдахад тухайн аргументуудыг яг дахин шинээр хуулбарлан санах ойд үүсгэж байж функц ажилладаг, энэ хуулбарлаж шинээр үүсгэх нь мэдээж хэрэг шугаман хугацаа зарцуулна. Энэ үнэхээр хэрэгтэй юу? Үүнээс зайлхийх арга нь заагчуудыг функцийн аргумантад ашиглах хэрэгтэй. Жишээ болгон дараах код-н хэсгийг харна уу.
void function(int a[], int size) {...//end shineer sanah oid uusgene.
void function(int &a[], int &size) {...//end shuud zaagchtai haritsah tul yamar ch iluu uildel hiihgui.
STL - Standart Template Library.
Хэрэглээ маш өндөртэй өгөгдлийн бүтэцүүд бас бусад функц алгоритмуудыг хэрэглэхэд бэлэн болгоод маш өндөр түвшинд, алдаагүй шахуу, биччихсэн байдаг сан юм. Ихэнх, бараг бүгд, STL-н функцүүдын аргументууд нь хаанаас хаа хүртэл гүйхийг нь зааж өгөхийг шаарддаг.
Шугаман массив бүтэцтэй өгөгдөлийн бүтцүүд. Хамгийн энгийн зүйл бол массив. int a[101]; Гэвч массивын сул талууд бол, бид хэмжээг нь заавал байж болох хамгийн томоор нь зааж байж зарладаг. Энэ нь дахиад л санах ойд бидэнд хэрэгтэйгээс хамаагүй илүү зай эзлэж цаг үрдэг. Мөн бидэнд дараах үйлдлүүд массив дээр хийх хэрэгтэй байг.
Массивт элемент нэмэх.
Элемент хасах.
Ямар нэгэн элемент байгаа эсэхийг шалгах.
Массиваас бүгд ялгаатай байх бүх элементийг олох.. гэх үйлдлүүд хэрэгтэй байг. Мэдээж бид үүнийг өөрсдөө бичиж чадна, энэ нь жоохон төвөгтэй мөн тухайн массив маань ямар төрөл вэ гэдэгээс шалтгаалаад өөр өөр бичих хэрэг гарна. Тэгвэл үүнийг бүгдийг нь шийдчихсэн STL-н сан байна. Энэ нь
vector юм. Постоо товч бөгөөд тодорхой байлгахын тулд жишээ кодууд маш их ашиглана шүү.
Шинээр вектор үүсгэх:
#include < vector >
using namespace std;
int main() {
vector < int > v; //hooson vector.
/*
shuud v[0] = 1; ingevel ajillah uyiin aldaa garna RE. Yagad gevel ene ni odoohondoo hooson vector.
*/
v.resize(10); // odoo harin 10 urttai vector bolloo.
vector < int > vv(10); // buh element ni teg baih 10 urttai vector.
vector < int > vv(10, -1); //buh element ni -1 baih 10 urttai vector.
vector < int > vvv(vv.begin(), vv.end()); //vv.begin() ni vv-n hamgiin ehnii elementiig zaana.
//vv.end() ni hamgiin suuliihiig zaana. End yag tsaanaa ng iterator guij baigaa ba hamgiin ehnii bolon hamgiin suuliin
//elementiing hoorond guigeed vvv-ruu hiij bn.
vector < int > vi(vvv); //shuud vvv-g huulj shine vector uusgej bn.
vector < vector < int > > matrix(10, vector < int > (10, 0)); //2d.
int size = vi.size(); // vector-n hemjeeg butsaana. Gehdee ene size() function O(1) bish shuu!
//vector-g hooson bnuu gdgiig shalgahdaa empty() function true butsaahna uu gdgeer shalgaj bgaarai.
for (size_t i = 0; i < size; i++) { v.push_back(i); } //engiin cycle-aar guij bn. End mun vector-t herhen element nemj baigaag harna uu.
for (vector < int > ::iterator it = vi.begin(); it != vi.end(); it++) { printf("%d ", *it);} //iterator ashiglan guij bn.
}
Pair:
utility санд байдаг дараах байдлаар тодорхойлогдсон 2 элементээс бүтсэн өгөгдлийн бүтэц.
template < typename T1, typename T2 > struct pair {
T1 first;
T2 second;
};
Т1, Т2 нь дурын төрөл тул юу ч байж болно.
#include < utility >
using namespace std;
int main() {
pair < string, pair < int, int > > P;
P = make_pair("aa", make_pair(1, 2)); // make_pair gj shineer uusgej bolno.
pair < int, int > point(1, 1); //mun ingej uusgej bolno,
cout << P.first << " " << P.second.first << " " << P.second.second;// herhen elementuuded handaj bgag harna uu.
return 0;}
Reverse: - тухайн вектор эсвэл массив-г хамгийн сүүлийхийг хамгийн урд гэх мэтээр байрыг солино.
#include < algorithm >
#include < vector >
using namespace std;
int main() {
vector < int > v;
const int N = 10;
int a[10];
for (int i = 0; i < N; i++) {
v.push_back(i);
a[i] = i;
}
reverse(v.begin(), v.end());
reverse(a, a+n);
return 0;}
Хайлтын функцууд:
Аргументууд нь яг адилхан, өөр нэг төстэй зүйлүүд нь хэрэв тухайн хайж байгаа зүйл олдохгүй бол тухайн хайлт хийгдэж байгаа агуулагчийн төгсгөлийн заагчийг буцаадаг.
if (find(vector.begin(), vector.end(), HaihObject) != vector.end()) {..
int data[5] = { 1, 5, 2, 4, 3 };
vector < int > X(data, data+5);
int v1 = *max_element(X.begin(), X.end()); // hamgiin tom elementiig butsaana.
int i1 = min_element(X.begin(), X.end()) – X.begin; // hamgiin baga elementiin index-g butsaana.
int v2 = *max_element(data, data+5); // Hamgiin tom elementiig butsaana.
int i3 = min_element(data, data+5) – data; // Hamgiin baga elementiin index-g butsaana.
Өөр нэг хэрэглээтэй зүйл бол тухайн өгөгдлийн төрлийг ологч typeof.
typeof(a+b) x = (a+b);
Үүнийг ашиглан дараах макро директивийг биччихвэл дараа дараагийн код-г хурдлуулах байх.
#define tr(container, it) \
for(typeof(container.begin()) it = container.begin(); it != container.end(); it++)
#define all(c) c.begin(), c.end()
Дараах маягаар ашиглана.
void f(const vector
& v) {
int r = 0;
tr(v, it) {
r += (*it)*(*it);
}
return r;
}
insert:
vector < int > v;
// ...
v.insert(1, 42); // ehnii 42 shirheg elementiin daraa 1-g oruulj bn.
erase:
erase(iterator);
erase(iteratoriin ehlel, iteratoriin tugsgul);
String:
string s = "hello";
string
s1 = s.substr(0, 3), // "hel"
s2 = s.substr(1, 3), // "ell"
s3 = s.substr(0, s.length()-1), "hell"
s4 = s.substr(1); // "ello"
Set: Энэ нь бүх элемент нь ялгаатай байх 2тын хайлтын мод. Мөн 2тын мод нь дараалалгүй шугама бус мод бүтэцтэй тул индекс гэж байхгүй, тэгэхээр элементүүдтэй харьцахын тулд итератор хэрэглэхээс өөр арга байхгүй.
- Элемент нэмэх, Log(N).
- Элемент хасах, Lof(N).
- Бүх ялгаатай элемент тоолох, Log(N).
- Ямар нэгэн байгаа эсэхийг шалгах. Log(N).
set < int > s;
for(int i = 1; i <= 100; i++) {
s.insert(i);
}
s.insert(42); // 42 ali hediin baigaa tul yuch hiigdehgui!
for(int i = 2; i <= 100; i += 2) {
s.erase(i); // buh tegsh tonuudiig hasaj bn.
}
int n = int(s.size()); // 50.
int r = 0;
for(set < int > ::const_iterator it = s.begin(); it != s.end(); it++) {
r += *it;
} // 1-s 100 hurtleh buh sondgoi toonuudiin niilber bn.
int data[5] = { 5, 1, 4, 2, 3 };
set < int > S(data, data+5);
set< pair < string, pair < int, vector < int > > > SS;
int total = 0;
tr(SS, it) {
total += it->second.first;
}
if(s.find(42) != s.end()) {
// herev 42 baival
} else {
// 42 baihgui bol..
}
find функц ер нь асар их ашиглагдах байх, тэгэхээр дараах макро директивийг зарлачих хэрэгтэй.
#define present(container, element) (container.find(element) != container.end())
#define cpresent(container, element) (find(all(container),element) != container.end())
Векторын элементийн давхар элементийг хасаж эрэмлэхийг дараах маягаар маш хялбар хийж болно.
vector < int > v;
// …
set < int > s(all(v));
vector < int > v2(all(s));
Map: Map ерөнхийдөө бол Set. Ялгаа нь 2тын модны орой бүр түлхүүр үгтэй, тиймээс индекс маркаар ашиглаж бас болно.
map < string, int > M;
M["Top"] = 1;
M["Coder"] = 2;
M["SRM"] = 10;
int x = M["Top"] + M["Coder"];
if(M.find("SRM") != M.end()) {
M.erase(M.find("SRM")); // bas M.erase("SRM") bolno.
}
map < string, int > M;
// …
int r = 0;
tr(M, it) {
r += it->second;
}
Энэ удаагийн постоо энэ хүрээд өндөрлөе. Дараагийн парт2 гэж посто байгаа ба тэрүүгээрэй арай ахисан түвшинд хэрхэн ашиглах талаар заая.
Ашигласан материалууд:
http://en.cppreference.com/w/cpp/algorithm
http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=standardTemplateLibrary