Sobes.tech
Middle

როდის უნდა გამოიყენოთ std::set და როდის std::unordered_set C++-ში?

sobes.tech AI

პასუხი AI-სგან

std::set և std::unordered_set օգտագործվում են եզակի տարրեր պահելու համար։ Ընտրությունը նրանց միջև կախված է առաջնահերթություններից՝ կարգավորել կամ կատարողականությունը մուտքագրման/հեռացման/փնտրելու ժամանակ։

std::set հիմնված է բալանսավորված բինար որոնողական ծառի վրա (հաճախ՝ կարմրո-սև ծառի):

std::set-ի հատկանիշներ՝

  • տարրերը պահվում են դասավորված կարգով։
  • մուտքագրման, հեռացման և որոնման ժամանակը՝ O(log N), որտեղ N՝ տարրերի քանակն է։
  • հարմար է, երբ կարևոր է տարրերի դասավորված կարգը կամ երբ անհրաժեշտ է ստանալ տարրեր որոշակի տիրույթում։

std::unordered_set հիմնված է հեշ-թերթի վրա։

std::unordered_set-ի հատկանիշներ՝

  • տարրերը պահվում են ոչ դասավորված կարգով։
  • մուտքագրման, հեռացման և որոնման ժամանակը՝ միջին՝ O(1), բայց վատագույն դեպքում (երբ շատ է հեշ-ֆունկցիայի բախումները) կարող է հասնել՝ O(N)։
  • պահանջվում է, որ տարրի տիպը ունենա որոշված հեշ-ֆունկցիա (std::hash) և համեմատության օպերատոր (operator==
  • հարմար է, երբ անհրաժեշտ է առավելագույն արագություն մուտքագրման, հեռացման և որոնման համար, և տարրերի կարգը կարևոր չէ։

Տեղեկատվական աղյուսակ՝

Կատեգորիա std::set std::unordered_set
Ներքին կառուցվածք Բալանսավորված ծառ Հեշ-թերթ
Տարրերի կարգը Դասավորված Անցնցող
Վերցման/մուտքագրման/հեռացման ժամանակը (միջին) O(log N) O(1)
Վերցման/մուտքագրման/հեռացման ժամանակը (բադագույն) O(log N) O(N)
Տիպի պահանջներ < օպերատոր std::hash, operator==

Օրինակ std::set-ի օգտագործման համար՝

#include <iostream>
#include <set>

int main() {
    std::set<int> դասավորված_մասիվ;
    դասավորված_մասիվ.insert(5);
    դասավորված_մասիվ.insert(2);
    դասավորված_մասիվ.insert(8);

    // Էлементները կարտահանվեն դասավորված կարգով՝ 2 5 8
    for (int արժեք : դասավորված_մասիվ) {
        std::cout << արժեք << " ";
    }
    std::cout << std::endl;

    return 0;
}

Օրինակ std::unordered_set-ի օգտագործման համար՝

#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> ոչդասավորված_մասիվ;
    ոչդասավորված_մասիվ.insert(5);
    ոչդասավորված_մասիվ.insert(2);
    ոչդասավորված_մասիվ.insert(8);

    // Արտածման կարգը կարող է տարբեր լինել
    for (int արժեք : ոչդասավորված_մասիվ) {
        std::cout << արժեք << " ";
    }
    std::cout << std::endl;

    return 0;
}