Զանգվածներ

!!! Վերանվանել «Հավաքածուներ» !!!

Զանգվածը նույն տիպն ունեցող տարրերի հավաքածու է, որոնք տեղավորված են հիշողության անընդհատ տիրույթում։ C++ լեզվի ստանդարտ գրադարանում իրականացված են երկու տեսակի զանգվածներ՝ array և vector դասերով։ array դասով մոդելավորվում են ֆիքսված չափով զանգվածները, իսկ vector դասով՝ դինամիկ ընդլայնվող զանգվածները։

Սկսենք array դասից։ Ենթադրենք ունենք drone անօդաչու թռչող սարքը (ԱԹՍ), որը կարող է օդում մնալ առավելագույնը երկու ժամ։ Ղեկավարող համակարգիչը (server) ամեն կես րոպեն մեկ գրանցում է ԱԹՍ-ի թռիչքի բարձրությունն ու արագությունը։ Այդ տվյալները հարմար է պահել double տարրերի height և speed զանգվածներում։ Ահա դրանց սահմանումները.

array<double,120> speed = { 0 };  // արագություն
array<double,120> heigth = { 0 }; // բարձրություն

Այստեղ array դասի օբյեկտ սահմանելիս առաջին պարամետրով նշում ենք զանգվածի տարրերի տիպը, իսկ երկրորդով՝ չափը։ Քանի որ լեզվի ներդրված տիպերի համար array-ի բոլոր տարրերն սկզբնարժեքավորվում են անորոշ արժեքներով, speed և height զանգվածներն արժեքավորում ենք զրո արժեքներով։ ?? Համոզվելու համար կարելի է, օրինակ, արտածել բոլոր տարրերը.

for( auto e : speed )
    cout << e << endl;

array տիպի զանգվածի բոլոր տարրերին մի որևէ սկզբանական արժեք վերագրելու համար նախատեսված է նրա fill() մեթոդը։

speed.fill(0);

Տվյալների հարցման և գրանցման ցիկլը, որ պետք է աշխատի առանձին հոսքում (տես Կատարման հոսքեր գլուխը), կունենա մոտավորապես այսպիսի տեսք։

int ix = 0;
while( drone.inFlight() ) {
    speed[i] = drone.getSpeed(); // գրանցել արագությունը
    height[i] = drone.getHeight(); // գրանցել բարձրությունը
    this_thread::sleep_for(30s); // սպասել կես րոպե
    ++ix;
}

isFlight() պրեդիկատը դրական պատասխան է տալիս այն դեպքում, երբ ԱԹՍ-ն օդում է, getSpeed() ֆունկցիան վերադարձնում է արագությունը, իսկ getHeight()-ը՝ բարձրությունը։ this_thread անունների տիրույթի sleep_for() ֆունկցիան հոսքի կատարումը կանգնեցնում (սպասեցնում) է իր արգումենտում նշված չափով։ Ցիկլի ավարտին ix փոփոխականը ցույց կտա, թե քանի անգամ է տվյալների գրանցում կատարվել։

Հիմա, ենթադրենք, ավարտվել է ԱԹՍ-ի թռիչքը, և փորձարկողն ուզում է ինչ-որ վիճակագրական տվյալներ թռիչքի ընթացքից։ Հաշվենք թռիչքի միջին արագությունը. դրա համար պետք է գումարել արագության բոլոր գրառումները և բաժանել քանակի վրա.

double avgSpeed = 0.0;
for( auto e : speed )
    avgSpeed += e;
avgSpeed /= ix;
cout << avgSpeed << endl;

height զանգվածի վրայով անցնելով կարող ենք հաշվել ԱԹՍ-ի թռիչքի առավելագույն բարձրությունը.

double maxHeight = height[0];
for( int i = 1; i < ix; ++i )
    if( height[i] > maxHeight )
        maxHeight = height[i];
cout << maxHeight << endl;

Այս օրինակում height զանգվածի տարրերին դիմելու համար օգտագործել ենք ինդեքսավորման (կամ՝ տարրին դիմելու) [] գործողությունը։

ԱԹՍ-ներին մի կողմ թողնենք և անցնենք «ռազմաճակատի» մյուս կողմը։ Դիցուք ունենք շուրջօրյա հերթապահության ռեժիմում աշխատող մի ռադիոտեղորոշիչ կայան (ՌՏԿ, ռադար), որը հսկում է 100 կմ օդային տարածք։ Ամեն անգամ, երբ ռադարի հսկողության տիրույթում հայտնվում է մի որևէ թռչող օբյեկտ, այն գրանցում է օբյեկտի ազիմուտը, հեռավորությունը, բարձրությունը և գրառման ժամանակը՝ համապատասխանաբար azimuth, distance, height և timestamp զանգվածներում։ Նորից պարզության համար ենթադրենք, որ մեր ՌՏԿ-ն կարողանում է հետևել միայն մեկ թռչող սարքի։

Խնդրի նկարագրությունից պարզ է, որ նշված զանգվածները չեն կարող սահմանվել ֆիքսված չափերով. ի սկզբանե հայտնի չէ, և չի էլ կարող հայտնի լինել, թե ինչ քանակով ու հաճախությամբ կարող են լինել օդային տարածքի խախտումները։ Նմանատիպ դեպքերի համար C++ լեզվի ստանդարտ գրադարանն առաջարկում է vector դասը. այս դասի օբյեկտ զանգվածները հնարավորություն ունեն ըստ պահանջի ընդլայնվելու։

Եվ այսպես. սահմանենք վերը նշված չորս զանգվածները.

vector<double> azimuth;               // ազիմուտ
vector<double> distance;              // հեռավորություն
vector<double> height;                // բարձրություն
vector<chrono::time_point> timestamp; // ժամանակ

Այս սահմանումներում ոչ մի չափ նշված չէ։ Եթե արտածենք զանգվածներից որևէ մեկի տարողությունը, ապա կտեսնենք, որ այն զրո է։ ??

cout << azimuth.capcaity() << endl; // զանգվածի տարողությունը
cout << azimuth.size() << endl;     // տարրերի քանակը

Եթե պետք է vector ցանգվածի մեջ նոր տարր ավելացնել, ապա օգտագործում ենք push_back() մեթոդը։ Օրինակ, դիտարկենք ՌՏԿ֊ի աշխատանքային ցիկլը։ Այն կունենա մոտավորապես հետևյալ տեսքը․

// քանի դեռ ՌՏԿ-ն աշխատում է ...
while( radar.inService() ) {
    // եթե օբյեկտ է հայտնաբերվել
    if( auto obj = detected() ) {
        // գրանցել հայտնաբերման ժամանակը ...
        timestamp.push_back(chrono::high_resolution_clock::now());
        // ... և օբյեկտի ազիմուտը
        azimuth.push_back(obj.getAzimuth());
        // ... և օբյեկտի հեռավորությունը
        distance.push_back(obj.getDistance());
        // ... և օբյեկտի թռիչքի բարձրությունը
        height.push_back(obj.getHeight());
    }
}

-- շարունակել վեկտորի տարրերի թվարկման մասին, at() մեթոդի մասին, erase()-ի մասին, դատարկ լինելը ստուգելու մասին --


-- մի երկու բառ էլ C զանգվածների մասին --

results matching ""

    No results matching ""