پیاده سازی و استفاده از set در برنامه نویسی

پیاده سازی و استفاده از set در برنامه نویسی

تعریف set

در برنامه نویسی set نوعی پیاده سازی در ساختار داده است و set عناصر تکراری رو نگهداری نمیکنه

عنصر ها رو طبق ترتیبی که اضافه شدن نگهداری نمیکنه و بر خلاف لیست که با افزودن یک عنصر، عنصر بعد به طور خودکار تو خونه ی شماره ی بعدی آرایه قرار میگیره، در set با افزودن عنصر جدید، یک index تصادفی براش ایجاد میشه و به صورت تصادفی در خونه های موجود قرار می گیره.

نحوه ی قرار گرفتن عناصر اضافه شده در set
نحوه ی قرار گرفتن عناصر اضافه شده در set

در واقع set مشابه مجموعه ها در ریاضیاته یعنی یک مجموعه از عناصر که داخلش عنصر تکراری وجود نداشته باشه.

به set هایی که با هش کد (hashcode) پیاده می کنیم، HashSet میگیم، میتونیم HashSet رو مستقیم با هش کد یا از طریق یک رابطه ی aggregation با HashMap پیاده کنیم.

در این مطلب به پیاده سازی set از طریق رابطه ی aggregation با HashMap می پردازیم.

افزودن عنصر به set

برای اضافه کردن یک عنصر به set از تابعی به اسم add یا insert استفاده می کنیم؛ پیچیدگی زمان برای اضافه کردن یک عنصر به set برابر با O(1) است.

function add(E e): boolean{
  
  if !map.contains(e) 
    return false
  
  map.put(e, null)
  size++

  return true
}
        

بررسی وجود عنصر در set

برای بررسی یک عنصر در set از تابعی به نام contains استفاده می کنیم؛ در set پیچیدگی زمان برای جستجو O(1) است.

function contains(e: E): boolean{
  return map.containsKey(e)
}
        

حذف عنصر از set

برای حذف یک عنصر در set از تابعی به نام remove یا delete استفاده می کنیم؛‌ پیچیدگی زمان در set برای حذف یک عنصر O(1) است.

function remove(e: E): boolean{
  if !contains(e)
    return false

  map.remove(e)

  return true
}
        

تبدیل set به آرایه برای جستجوی خطی بین عناصر

میتونیم با استفاده از تابعی به نام toArray عناصر رو به صورت آرایه برگردونیم تا بتونیم به جستجوی خطی بین عناصر بپردازیم، پیچیدگی زمان برای این کار O(n) است.

function toArray(): Object[] {

  size := map.getSize()

  elements := new Object[size]

  entries := map.toArray()

  for 0<= i < entries.length
      elements[i] = entries[i]

  return elements
}
        

پیاده سازی set در زبان های برنامه نویسی

میخوایم یک HashSet رو با رابطه ی aggregation با HashMap در زبان های برنامه نویسی (جاوا و کاتلین) پیاده کنیم.

در زیر نمودار uml پیاده سازی set آورده شده است.

نمودار uml پیاده سازی set در برنامه نویسی
نمودار uml پیاده سازی set در برنامه نویسی
public class MyHashSet<E> {

    private final MyHashMap<E, Object> map = new MyHashMap<>();

    public boolean add(E e){

        if (map.containsKey(e)) return false;

        map.put(e, null);

        return true;
    }

    public boolean contains(E e){
        return map.containsKey(e);
    }

    public boolean remove(E e){

        if (!contains(e)) return false;

        map.remove(e);

        return true;
    }

    public int getSize() {
        return map.getSize();
    }

    public boolean isEmpty(){
       return map.isEmpty();
    }

    public Object[] toArray(){

        int size = map.getSize();
        Object[] elements = new Object[size];

        MyHashMap.Entry<E, Object>[] entries = map.toArray();

        for (int i=0; i<entries.length; i++){
            elements[i] = entries[i].getKey();
        }

        return elements;
    }

    @Override
    public String toString() {

        StringBuilder sb = new StringBuilder("[");

        Object[] array = toArray();

       for (int i=0; i<array.length; i++){
           sb.append(array[i]);
           if (i < array.length - 1){
               sb.append(", ");

           }
       }

       sb.append("]");

       return sb.toString();
    }
}
        
class MyHashSet<E> {
    private val map: MyHashMap<E?, Any?> = MyHashMap()

    val size: Int
        get() = map.size

    val isEmpty: Boolean
        get() = map.isEmpty

    fun add(e: E?): Boolean {
        if (map.containsKey(e)) return false

        map.put(e, null)

        return true
    }

    fun contains(e: E?): Boolean {
        return map.containsKey(e)
    }

    fun remove(e: E?): Boolean {
        if (!contains(e)) return false

        map.remove(e)

        return true
    }

    fun toArray(): Array<Any?> {
        val size: Int = map.size
        val elements = arrayOfNulls<Any>(size)

        val entries: Array<MyHashMap.Entry<E?, Any?>?> = map.toArray()

        for (i in entries.indices) {
            elements[i] = entries[i]?.key
        }

        return elements
    }

    override fun toString(): String {
        val sb = StringBuilder("[")

        val array = toArray()

        for (i in array.indices) {
            sb.append(array[i])
            if (i < array.size - 1) {
                sb.append(", ")
            }
        }

        sb.append("]")

        return sb.toString()
    }
}
        

استفاده از set در زبان های برنامه نویسی

در این قسمت میخوایم یک نمونه از set که پیاده کردیم ایجاد کنیم و اسم چند شهر رو بهش اضافه کنیم و (اسم یک شهر رو دوبار بنویسیم) و سپس دو شهر رو حذف کنیم و در نهایت شهر های داخل set رو نمایش بدیم.

MyHashSet<String> cities = new MyHashSet<>();

    cities.add("Tehran");
    cities.add("Arak");
    cities.add("Qom");
    cities.add("Hamadan");
    cities.add("Mashhad");
    cities.add("Tehran");

    cities.remove("Hamadan");
    cities.remove("Arak");

    System.out.println(cities);
        
val cities: MyHashSet<String> = MyHashSet()

    cities.add("Tehran")
    cities.add("Arak")
    cities.add("Qom")
    cities.add("Hamadan")
    cities.add("Mashhad")
    cities.add("Tehran")

    cities.remove("Hamadan")
    cities.remove("Arak")

    println(cities)
        

خلاصه

  • از set در برنامه نویسی برای نگهداری عناصر غیر تکراری استفاده می کنیم.
  • اگه بخوایم set رو از طریق هش کد (hashcode) پیاده کنیم بهش HashSet میگیم.
  • میتونیم set رو مستقیم با هش کد یا از طریق رابطه ی aggregation با HashMap پیاده کنیم.
  • پیچیدگی زمان برای اضافه، حذف و جستجوی عنصر در set برابر با O(1) است.

notifications برای اطلاع از جدیدترین مطالب و پست های مرتبط، عضو کانال تلگرام ما بشید.

arrow_drop_up
کپی شد!