الگوریتمستان

یادداشت‌های یک معلم علاقه‌مند به نوشتن از آنچه آموخته و یاد می‌دهد
 

  

✤  نکته‌ای در مورد کلاس‌ها و مجموعه‌ها در ++C

زبان برنامه‌نویسی ++C دو کلاس set و unordered_set را برای پیاده‌سازی مفهوم مجموعه (ظرفی با عناصر غیرتکراری) دارد.

کلاس set علاوه بر بررسی تکراری نبودن عناصر، آنها را به صورت مرتب ذخیره می‌کند. پس اگر بخواهیم برای نگه داشتن عناصری از کلاس دلخواه خودمان از set استفاده کنیم، باید حداقل عملگر > را سربارگذاری کرده باشیم تا ظرف set قابلیت تشخیص ترتیب عناصر را داشته باشد. اما گاهی تعریف کوچکتر بودن برای کلاس مقدور نیست یا از لحاظ مفهومی معنی ندارد. در چنین شرایطی می‌توانیم از کلاس unordered_set استفاده کنیم.

کلاس unordered_set از hashing برای بررسی یکسان بودن عناصر استفاده می‌کند. بنابراین باید عملکرد hash برای کلاس دلخواه خودمان را تعریف کنیم. اما طراحی عملگر hash کارا و بدون تداخل لزوما راحت نیست و ممکن است عناصر متفاوت hash یکسانی داشته باشند. به همین دلیل علاوه بر پیاده‌سازی متد hash باید عملگر == هم پیاده شود تا در صورت برابر بودن hash دو عنصر، یکسان بودن آن دو از طریق عملگر == هم بررسی شود. این کار یک حسن بزرگ دارد که لازم نیست درگیر طراحی hash دقیق و بدون تداخل باشیم و حتی اگر تداخلی داشتیم، عملگر == هم برای تشخیص تمایز فراخوانی می‌شود.

  

class Circle {

public:

    double radius;

    Circle(double r) {

        this->radius = r;

    }

    bool operator < (const Circle& l) const {

        return this->radius < l.radius;

    }

};

class Rectangle {

public:

    double width, height;

  

    Rectangle(double w, double h) {

        this->width = w;

        this->height = h;

    }

  

    bool operator == (const Rectangle& l) const {

        return this->width == l.width && this->height == l.height;

    }

  

    size_t hash() const {

        return 2 * this->width + 3 * this->height;

    }

};

  

namespace std {

    template <>

    struct hash<Rectangle> {

        size_t operator () (const Rectangle &r) const { return r.hash(); }

    };

}

  

int main() {

    std::set<Circle> cc;

    cc.insert(Circle(20));

    cc.insert(Circle(10));

    for(auto c : cc)

        std::cout << c.radius << std::endl;

    std::unordered_set<Rectangle> rr;

    rr.insert(Rectangle(6, 2));

    rr.insert(Rectangle(3, 4));

    for(auto r : rr)

        std::cout << r.width << "\t" << r.height << std::endl;

    return 0;

}

مسعود اقدسی فام

مسعود اقدسی فام هستم.

دانش‌آموخته علوم کامپیوتر و فعال حوزه‌های برنامه‌نویسی پایتون، علم داده و یادگیری ماشین

algs.ir/spynvzo     اشتراک‌گذاری در LinkedIn     اشتراک‌گذاری در Twitter     ارسال با Telegram
نوشته‌ها از این دست
       ✦   هدر فایل bits/stdc++.h
آخرین نوشته‌ها
نوشته‌های پرمخاطب
  • 1
  • 2
  • 3
  • 4
  • 5

نام: *  

پست الکترونیک (محرمانه):

متن پیام: *  

01 02 06 07 08 09 10 11 12 13 14