2015-05-27 141 views
1

我想比較兩個在Java中的哈希集,它們都包含幾個字符,但我需要做很多次(10^5〜8),所以我試圖提高性能。 具體,我想比較是集合A中是否包含B或設置B包含A和它們的大小區別< = 2,這裏有兩種方法我想出,Java集合包含所有性能

  1. 使用設置containsall方法,
  2. 因爲set只能包含26個字母,所以我不再使用hashset,我使用位操作,如果虛擬集具有'a',那麼我給1;如果它有'b',我給1 < < 1,這是2;如果它有'c',我給1 < < 2,這是4,然後我將所有值一起添加爲該集合的值。然後我做異或並計算結果中的數字1。

哪種方法會更好?

+0

是不是使用'containsAll'執行,或者這是一個基於感知瓶頸的優化? –

+1

第二個,可能。但是這很容易解決:嘗試兩種方式,報告結果,我們都會學到一些東西。順便說一下,您不必計數位數,通過移除最右邊的位組兩次(查找訣竅),然後與零進行比較,可以確定是否至多有兩位。 – harold

+1

同意其他評論,但也想指出你在Java的'BitSet'類。你可以避免必須考慮所有的移位,位計數和什麼。 –

回答

1

如果我理解正確,第二種方法是使用。

我會做這樣的事情:

public class IntBitSet { 

    private int set = 0; 
    private final int firstChar = (byte) 'a'; 
    private final int lastChar = (byte) 'z'; 

    public int size() { 
    return Integer.bitCount(set); 
    } 

    public boolean isEmpty() { 
    return set == 0; 
    } 

    public boolean contains(char c) { 
    assert c <= lastChar && c >= firstChar : c + " is not a valid value."; 

    return ((set >>> (c - firstChar)) & 1) != 0; 
    } 

    public void add(char c) { 
    assert c <= lastChar && c >= firstChar : c + " is not a valid value."; 

    set = set | (1 << (c - firstChar)); 
    } 

    public void remove(char c) { 
    assert c <= lastChar && c >= firstChar : c + " is not a valid value."; 

    set = set & ~(1 << (c - firstChar)); 
    } 

    public boolean containsAll(IntBitSet c) { 
    return (this.set & c.set) == c.set; 
    } 

    public void clear() { 
    set = 0; 
    } 
} 

和單元測試。

import org.junit.Test; 
    import static org.junit.Assert.*; 

    public class IntBitSetTest { 

    public IntBitSetTest() { 
    } 

    @Test 
    public void testSize() { 
     System.out.println("size"); 
     IntBitSet instance = new IntBitSet(); 

     int count = 0; 
     for(char c = 'a'; c <= 'z'; c+=3) { 
     instance.add(c); 
     count++; 
     } 

     assertEquals(count, instance.size()); 

    } 

    @Test 
    public void testIsEmpty() { 
     System.out.println("isEmpty"); 
     IntBitSet instance = new IntBitSet(); 

     assertTrue(instance.isEmpty()); 

     instance.add('g'); 
     assertFalse(instance.isEmpty()); 

    } 

    @Test 
    public void testContains() { 
     System.out.println("contains"); 
     IntBitSet instance = new IntBitSet(); 

     for(char c = 'a'; c <= 'z'; c++) { 
     instance.add(c); 
     } 

     instance.remove('o'); 
     instance.remove('u'); 
     instance.remove('s'); 

     assertTrue(instance.contains('a')); 
     assertTrue(instance.contains('d')); 
     assertTrue(instance.contains('i')); 

     assertFalse(instance.contains('o')); 
     assertFalse(instance.contains('u')); 
     assertFalse(instance.contains('s')); 
    } 

    @Test 
    public void testAdd() { 
     System.out.println("add"); 
     IntBitSet instance = new IntBitSet(); 
     instance.add('b'); 
     assertFalse(instance.contains('a')); 
     assertTrue(instance.contains('b')); 
     assertFalse(instance.contains('c')); 
     assertFalse(instance.contains('d')); 
     assertFalse(instance.contains('e')); 
     assertFalse(instance.contains('f')); 
     assertFalse(instance.contains('g')); 
     assertFalse(instance.contains('h')); 
     assertFalse(instance.contains('i')); 
     assertFalse(instance.contains('j')); 
     assertFalse(instance.contains('k')); 
     assertFalse(instance.contains('l')); 
     assertFalse(instance.contains('m')); 
     assertFalse(instance.contains('n')); 
     assertFalse(instance.contains('p')); 
     assertFalse(instance.contains('q')); 
     assertFalse(instance.contains('r')); 
     assertFalse(instance.contains('s')); 
     assertFalse(instance.contains('t')); 
     assertFalse(instance.contains('u')); 
     assertFalse(instance.contains('v')); 
     assertFalse(instance.contains('w')); 
     assertFalse(instance.contains('x')); 
     assertFalse(instance.contains('y')); 
     assertFalse(instance.contains('z')); 
    } 

    @Test 
    public void testRemove() { 
     System.out.println("remove"); 

     IntBitSet instance = new IntBitSet(); 

     for(char c = 'a'; c <= 'z'; c++) { 
     instance.add(c); 
     } 

     instance.remove('e'); 

     assertTrue(instance.contains('a')); 
     assertTrue(instance.contains('b')); 
     assertTrue(instance.contains('c')); 
     assertTrue(instance.contains('d')); 
     assertFalse(instance.contains('e')); 
     assertTrue(instance.contains('f')); 
     assertTrue(instance.contains('g')); 
     assertTrue(instance.contains('h')); 
     assertTrue(instance.contains('i')); 
     assertTrue(instance.contains('j')); 
     assertTrue(instance.contains('k')); 
     assertTrue(instance.contains('l')); 
     assertTrue(instance.contains('m')); 
     assertTrue(instance.contains('n')); 
     assertTrue(instance.contains('p')); 
     assertTrue(instance.contains('q')); 
     assertTrue(instance.contains('r')); 
     assertTrue(instance.contains('s')); 
     assertTrue(instance.contains('t')); 
     assertTrue(instance.contains('u')); 
     assertTrue(instance.contains('v')); 
     assertTrue(instance.contains('w')); 
     assertTrue(instance.contains('x')); 
     assertTrue(instance.contains('y')); 
     assertTrue(instance.contains('z')); 
    } 

    @Test 
    public void testContainsAll() { 
     System.out.println("containsAll"); 

     IntBitSet instance1 = new IntBitSet(); 
     IntBitSet instance2 = new IntBitSet(); 
     IntBitSet instance3 = new IntBitSet(); 

     for(char c = 'a'; c <= 'z'; c+=3) { 
     instance1.add(c); 
     instance2.add(c); 
     if(c % 2 == 0) 
      instance3.add(c); 
     } 

     assertTrue(instance1.containsAll(instance2)); 
     assertTrue(instance1.containsAll(instance3)); 
     assertFalse(instance3.containsAll(instance1)); 
    } 

    @Test 
    public void testClear() { 
     System.out.println("clear"); 
     IntBitSet instance = new IntBitSet(); 

     instance.add('z'); 

     instance.clear(); 
     assertTrue(instance.size() == 0); 
     assertTrue(instance.isEmpty()); 

    } 
    }