HashSet

mseo39ยท2025๋…„ 4์›” 27์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
6/6
post-thumbnail

๐Ÿ“์ž๋ฐ”์˜ ์ •์„ ์—ฐ์Šต๋ฌธ์ œ๋ฅผ ํ’€๋‹ค๊ฐ€ ์ฃผ์ œ๊ฐ€ ์žฌ๋ฐŒ์–ด์„œ ์ž‘์„ฑํ•œ๋‹ค

๋‹ค์Œ ์˜ˆ์ œ์˜ ๋น™๊ณ ํŒ์€ 1~30์‚ฌ์ด์˜ ์ˆซ์ž๋“ค๋กœ ๋งŒ๋“  ๊ฒƒ์ธ๋ฐ, 
์ˆซ์ž๋“ค์˜ ์œ„์น˜๊ฐ€ ์ž˜ ์„ž์ด์ง€ ์•Š๋Š”๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. 
์ด๋Ÿฌํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ด์œ ์™€ ์ด ๋ฌธ์ œ๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๊ณ ,
์ด๋ฅผ ๊ฐœ์„ ํ•œ ์ƒˆ๋กœ์šด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์‹œ์˜ค.

์˜ˆ์ œ:
(1) 1~30๋ฒ”์œ„์˜ ๋žœ๋ค๊ฐ’์„ ๋งŒ๋“ค๊ณ 
(2) ๋žœ๋ค๊ฐ’ 25๊ฐœ๋ฅผ HashSet์— ์ €์žฅ
(3) HashSet์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ์ถœ๋ ฅ
*๊ธฐ์กด ์ž‘์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ์š”์•ฝํ•œ๊ฒ๋‹ˆ๋‹ค

๊ฒฐ๊ณผ:
์ˆซ์ž๋“ค์ด ์ œ๋Œ€๋กœ ์„ž์ด์ง€ ์•Š์€ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค

HashSet์€ ์ˆœ์„œ์œ ์ง€๋ฅผ ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ํ•ด์‹ฑ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋น„์Šทํ•œ ๊ฐ’๋“ค์ด ๋น„์Šทํ•œ ์œ„์น˜์— ์ €์žฅ๋œ๋‹ค๋Š” ๊ฒƒ์€ ๋Œ€์ถฉ ์•Œ ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿผ ์‹ค์ œ ๋‚ด๋ถ€๋™์ž‘์€ ์–ด๋–จ๊นŒ..?


๐Ÿ”์ฝ”๋“œ ์‚ดํŽด๋ณด๊ธฐ

์ด์ œ ์ฝ”๋“œ๋ฅผ ํŒŒ๊ณ ๋“ค์–ด๊ฐ€๋ณด์ž,,,๐Ÿ”๐Ÿ”๐Ÿ”

HashSet()

hashSet ๋จผ์ € ์ƒ์„ฑโ›๏ธ

/**
* Constructs a new, empty set; the backing {@code HashMap} instance has
* default initial capacity (16) and load factor (0.75).
*/
public HashSet() {
    map = new HashMap<>();
}

: HashSet์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐฐ์—ด ํฌ๊ธฐ๊ฐ€ 16์ด๊ณ  load factor๋Š” 0.75๋กœ ์ƒ์„ฑํ•œ๋‹ค๊ณ  ํ•œ๋‹ค

  • load factor
    : ์–ธ์ œ ๋ฐฐ์—ด ํฌ๊ธฐ๋ฅผ ๋Š˜๋ฆด ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๊ธฐ์ค€์œผ๋กœ 16*0.75=12๊ฐœ๊ฐ€ ์ €์žฅ๋˜๋ฉด ํฌ๊ธฐ๊ฐ€ ์ฆ๊ฐ€๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค

add()

์ด์ œ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด๋ณด์ž!โ›๏ธ

/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element {@code e} to this set if
* this set contains no element {@code e2} such that
* {@code Objects.equals(e, e2)}.
* If this set already contains the element, the call leaves the set
* unchanged and returns {@code false}.
*
* @param e element to be added to this set
* @return {@code true} if this set did not already contain the specified
* element
*/
public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}


// Dummy value to associate with an Object in the backing Map
static final Object PRESENT = new Object();

: ์ €์žฅํ•˜๋ ค๋Š” ์š”์†Œ๊ฐ€ ํฌํ•จ๋˜์–ด์žˆ๋‹ค๋ฉด ์ถ”๊ฐ€ํ•œ ๋‹ค์Œ true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ด๋ฏธ ์กด์žฌํ•ด์„œ ์ถ”๊ฐ€๋ฅผ ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ false๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค

๐Ÿค” ์ € PRESENT๋Š” ๋ญ์ง€?

HashSet์€ ๋‚ด๋ถ€์ ์œผ๋กœ HashMap์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์ ธ์žˆ๋Š”๋ฐ HashMap์€ (key,value)๋ฅผ ์ €์žฅํ•˜์ง€๋งŒ HashSet์€ key๋งŒ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— value์—๋Š” ๋”๋ฏธ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๋Š” ๊ฒƒ!

put()

๋” ๋“ค์–ด๊ฐ€๋ณด์ž~โ›๏ธ

/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for the key, the old
* value is replaced.
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with {@code key}, or
*         {@code null} if there was no mapping for {@code key}.
*         (A {@code null} return can also indicate that the map
*         previously associated {@code null} with {@code key}.)
*/
public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}

: ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๋ช…ํ•˜์ž๋ฉด key์— ๋งคํ•‘๋œ value๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์—๋Š” null์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด์— ์ €์žฅ๋˜์–ด์žˆ๋˜ value๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

โญ hash()

๊ทธ๋ฆฌ๊ณ  ์—ฌ๊ธฐ์„œ hash(key)๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

  • ํ•ด๋‹น key ๊ฐ์ฒด์˜ hashCode() ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
  • ์ƒ์œ„ 16๋น„ํŠธ์™€ ํ•˜์œ„ 16๋น„ํŠธ๋ฅผ XOR (์ถฉ๋Œ์„ ์ค„์ด๊ธฐ ์œ„ํ•จ)
static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

๐Ÿค” ๊ทผ๋ฐ ๊ธฐ๋ณธํ˜•์€ hashCode()๋ฅผ ์•ˆ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ?

์• ์ดˆ์— HashSet์€ HashSet<Object>๋กœ ๊ธฐ๋ณธํ˜•์„ ๋ฐ›์ง€ ์•Š์•„ ๋ž˜ํผ ํด๋ž˜์Šค๋ฅผ ์ „๋‹ฌํ•ด์ค˜์•ผ ํ•œ๋‹ค. ๊ทผ๋ฐ set.add(10)๋Š” ์–ด๋–ป๊ฒŒ ๊ฐ€๋Šฅํ•œ๊ฑฐ์ง€..?

public class Main {
    public static void main(String[] args) {
        HashSet<int> set = new HashSet<>();
        set.add(10);
    }
}

์œ„ ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•œ ํŒŒ์ผ์„ ์ฝ์œผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

$ javap -verbose Main
public class Main
  minor version: 0
  major version: 64
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #20                         // Main
  super_class: #2                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
   #1 = Methodref          #2.#3          // java/lang/Object."<init>":()V
   #2 = Class              #4             // java/lang/Object
   #3 = NameAndType        #5:#6          // "<init>":()V
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Class              #8             // java/util/HashSet
   #8 = Utf8               java/util/HashSet
   #9 = Methodref          #7.#3          // java/util/HashSet."<init>":()V
 ๐Ÿ‘‰#10 = Methodref          #11.#12        // java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
  #11 = Class              #13            // java/lang/Integer
  #12 = NameAndType        #14:#15        // valueOf:(I)Ljava/lang/Integer;
  #13 = Utf8               java/lang/Integer
  #14 = Utf8               valueOf
  #15 = Utf8               (I)Ljava/lang/Integer;
  #16 = Methodref          #7.#17         // java/util/HashSet.add:(Ljava/lang/Object;)Z
  #17 = NameAndType        #18:#19        // add:(Ljava/lang/Object;)Z
  #18 = Utf8               add
  #19 = Utf8               (Ljava/lang/Object;)Z
  #20 = Class              #21            // Main
  #21 = Utf8               Main
  #22 = Utf8               Code
  #23 = Utf8               LineNumberTable
  #24 = Utf8               main
  #25 = Utf8               ([Ljava/lang/String;)V
  #26 = Utf8               SourceFile
  #27 = Utf8               Main.java
{
  public Main();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: new           #7                  // class java/util/HashSet
         3: dup
         4: invokespecial #9                  // Method java/util/HashSet."<init>":()V
         7: astore_1
         8: aload_1
        ๐Ÿ‘‰9: bipush        10
        ๐Ÿ‘‰11: invokestatic  #10                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        14: invokevirtual #16                 // Method java/util/HashSet.add:(Ljava/lang/Object;)Z
        17: pop
        18: return
      LineNumberTable:
        line 5: 0
        line 6: 8
        line 7: 18
}
SourceFile: "Main.java"

๐Ÿง???์ด๊ฒŒ ๋ญ์ง€... ์‹ถ๊ฒ ์ง€๋งŒ ์œ„์—์„œ ๊ด€๋ จ๋œ ๋ถ€๋ถ„๋งŒ ๊ฐ€์ ธ์˜ค๋ฉด ์ดํ•ด๊ฐ€ ์‰ฝ๋‹ค

(1) #10 = Methodref          #11.#12        // java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
(2) bipush        10
(3) invokestatic  #10                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

(1) #10์€ Integer.valueOf(int) ๋ฉ”์„œ๋“œ๋ฅผ ์ฐธ์กฐ
(2) int ํƒ€์ž…์˜ 10์„ ์Šคํƒ์— ํ‘ธ์‹œ
(3) invokestatic #10์€ #10 ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ผ๋Š” ๊ฒƒ์œผ๋กœ ์Šคํƒ์—์„œ 10์„ ๊บผ๋‚ด์„œ #10์— ์ •์˜๋œ Integer.valueOf(10)์„ ์‹คํ–‰ํ•˜์—ฌ Integer ๊ฐ์ฒด๋กœ ๋ž˜ํ•‘๋œ 10์„ ๋ฐ˜ํ™˜

๐Ÿ’ก์ด๋Ÿฌํ•œ ๊ณผ์ •์„ ์˜คํ† ๋ฐ•์‹ฑ, ์–ธ๋ฐ•์‹ฑ์ด๋ผ๊ณ  ํ•œ๋‹ค

putVal()

๋”๋” ๋“ค์–ด๊ฐ€๋ณด์žโ›๏ธ

    /**
     * Implements Map.put and related methods.
     *
     * @param hash hash for key
     * @param key the key
     * @param value the value to put
     * @param onlyIfAbsent if true, don't change existing value
     * @param evict if false, the table is in creation mode.
     * @return previous value, or null if none
     */
    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }

์ „์ฒด์ ์ธ ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

  • ํ…Œ์ด๋ธ” ์ƒ์„ฑ
  • tab[i = (n - 1) & hash ํ™•์ธ
    • ๋น„์—ˆ๋‹ค๋ฉด ๊ฐ’ ์ถ”๊ฐ€
    • ์•ˆ๋น„์—ˆ๋‹ค๋ฉด ํ•ด๋‹น ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ์ˆœ์ฐจ์ ์œผ๋กœ ํ™•์ธ
      • ๋‹ค์Œ ๋…ธ๋“œ๊ฐ€ ๋น„์—ˆ๋‹ค๋ฉด (key,value) ์ถ”๊ฐ€
      • ๋™์ผํ•œ ํ‚ค๋ฅผ ์ฐพ์•˜๋‹ค๋ฉด ์ข…๋ฃŒ
    • ์ด๋ฏธ ํ‚ค๊ฐ€ ์กด์žฌํ•œ๋‹ค๋ฉด value ๋ฎ์–ด์“ฐ๊ณ  ์ด์ „ value ๋ฐ˜ํ™˜
  • ํ˜„์žฌ size๊ฐ€ 16*0.75=12๊ฐœ๋ณด๋‹ค ํฌ๋‹ค๋ฉด
    • ํฌ๊ธฐ๋ฅผ 2๋ฐฐ ํ™•์žฅ newThr = oldThr << 1
    • ์žฌ๋ฐฐ์น˜ ์ธ๋ฑ์Šค๋Š” (ํ™•์žฅํ•œ ํฌ๊ธฐ - 1) & hash๋กœ ๋‹ค์‹œ ๊ณ„์‚ฐํ•œ๋‹ค

โญ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๊ฒƒ๋งŒ ๋ณด์ž๋ฉด ์ธ๋ฑ์Šค๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค
tab[i = (n - 1) & hash

๐Ÿค”๊ทผ๋ฐ ์ด๊ฒŒ ๋ญ์ง€?.?

static final int TREEIFY_THRESHOLD = 8;

if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
    treeifyBin(tab, hash);

binCount >= TREEIFY_THRESHOLD - 1๋ผ๋ฉด ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋ฅผ Red-Black Tree๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ O(n) -> O(log n)์œผ๋กœ ํƒ์ƒ‰ ์„ฑ๋Šฅ์„ ๋†’์ด๋Š” ๊ฒƒ
-> ์ด ๋ถ€๋ถ„์€ ์ธ์ง€๋งŒ ํ•˜๊ณ  ๋‚˜์ค‘์— ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด์ž

  • binCount: ๊ฐ™์€ ์ธ๋ฑ์Šค์˜ ์ถฉ๋Œ ์ˆ˜

๐Ÿง๊ทธ๋ž˜์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ €์žฅ๋˜๋Š”์ง€ ๋ณด๊ณ ์‹ถ์–ด

์œ„์—์„œ โญ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ธ๋ฑ์Šค๊ฐ€ ๊ตฌํ•ด์ง€๋Š”๋ฐ ์ด๊ฑธ ์ด์šฉํ•ด์„œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์ž

  • h = key.hashCode()
  • hash = h ^ (h >>> 16)
  • i = (n - 1) & hash
import java.util.*;

public class test {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();

        set.add("1");
        set.add("2");
        set.add("3");
        set.add("4");
        set.add("5");
        set.add("6");
        set.add("7");
        set.add("8");
        set.add("9");
        set.add("10");
        set.add("11");
        set.add("12");

        int n = 16; // HashMap ๊ธฐ๋ณธ ํฌ๊ธฐ
        int h, hash, index;

        System.out.printf("%-6s | %-12s | %-20s | %-10s\n", "Key", "hashCode", "hash (h ^ (h >>> 16))", "Index");
        System.out.println("---------------------------------------------------------------");

        for (String str : set) {
            h = str.hashCode();
            hash = h ^ (h >>> 16);
            index = (n - 1) & hash;

            System.out.printf("%-6s | %-12d | %-20d | %-10d\n", str, h, hash, index);
        }
    }
}
๐Ÿ’ก๊ฒฐ๊ณผ
Key    | hashCode     | hash (h ^ (h >>> 16)) | Index     
---------------------------------------------------------------
11     | 1568         | 1568                 | 0         
1      | 49           | 49                   | 1         
12     | 1569         | 1569                 | 1         
2      | 50           | 50                   | 2         
3      | 51           | 51                   | 3         
4      | 52           | 52                   | 4         
5      | 53           | 53                   | 5         
6      | 54           | 54                   | 6         
7      | 55           | 55                   | 7         
8      | 56           | 56                   | 8         
9      | 57           | 57                   | 9         
10     | 1567         | 1567                 | 15       

๐Ÿ”๋ฐ์ดํ„ฐ๊ฐ€ 13๊ฐœ ์ด์ƒ์ด๋ผ๋ฉด?

ํ˜„์žฌ ํฌ๊ธฐ * 2๊ฐ€ ๋˜๋ฏ€๋กœ ํฌ๊ธฐ๊ฐ€ 16์ผ ๊ฒฝ์šฐ์™€ 32์ผ ๊ฒฝ์šฐ์˜ ์ธ๋ฑ์Šค๋ฅผ ๊ตฌํ–ˆ๋‹ค

<import java.util.*;

public class test {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();

        set.add("1");
        set.add("2");
        set.add("3");
        set.add("4");
        set.add("5");
        set.add("6");
        set.add("7");
        set.add("8");
        set.add("9");
        set.add("10");
        set.add("11");
        set.add("22");
        set.add("21");
        set.add("24");
        set.add("50");
        set.add("13");
        set.add("12");

        // ํ…Œ์ด๋ธ” ํฌ๊ธฐ (16 -> 32๋กœ ์ฆ๊ฐ€)
        int oldCapacity = 16;
        int newCapacity = oldCapacity + (oldCapacity >> 1);

        System.out.printf("%-6s | %-12s | %-20s | %-10s\n", "Key", "hashCode", "hash (h ^ (h >>> 16))", "Index (Old -> New)");
        System.out.println("---------------------------------------------------------------");

        for (String str : set) {
            int h = str.hashCode();
            int hash = h ^ (h >>> 16);

            // ๋ฆฌ์‚ฌ์ด์ฆˆ ์ „ ์ธ๋ฑ์Šค (16 ํฌ๊ธฐ์ผ ๋•Œ)
            int oldIndex = (oldCapacity - 1) & hash;

            // ๋ฆฌ์‚ฌ์ด์ฆˆ ํ›„ ์ธ๋ฑ์Šค (32 ํฌ๊ธฐ์ผ ๋•Œ)
            int newIndex = (newCapacity - 1) & hash;

            System.out.printf("%-6s | %-12d | %-20d | %-10d -> %-10d\n", str, h, hash, oldIndex, newIndex);
        }
    }
}
๐Ÿ’ก๊ฒฐ๊ณผ
Key    | hashCode     | hash (h ^ (h >>> 16)) | Index (Old -> New)
---------------------------------------------------------------
11     | 1568         | 1568                 | 0          -> 0         
22     | 1600         | 1600                 | 0          -> 0         
12     | 1569         | 1569                 | 1          -> 1         
24     | 1602         | 1602                 | 2          -> 2         
13     | 1570         | 1570                 | 2          -> 2         
1      | 49           | 49                   | 1          -> 17        
2      | 50           | 50                   | 2          -> 18        
3      | 51           | 51                   | 3          -> 19        
4      | 52           | 52                   | 4          -> 20        
5      | 53           | 53                   | 5          -> 21        
6      | 54           | 54                   | 6          -> 22        
7      | 55           | 55                   | 7          -> 23        
8      | 56           | 56                   | 8          -> 16        
9      | 57           | 57                   | 9          -> 17        
50     | 1691         | 1691                 | 11         -> 19        
10     | 1567         | 1567                 | 15         -> 23        
21     | 1599         | 1599                 | 15         -> 23      

p.s ์š”์ฆ˜,, ์ดˆ๋ก์ดˆ๋กํ•œ๊ฒŒ ์ข‹์•„์„œ ์ธ๋„ค์ผ์„ ๋ฐ”๊ฟจ๋‹ค,,ใ…Žใ…Ž

profile
ํ•˜๋ฃจํ•˜๋ฃจ ์„ฑ์‹คํ•˜๊ฒŒ

0๊ฐœ์˜ ๋Œ“๊ธ€