Точный диапазон количества ключей в таблице

#java

#java

Вопрос:

Я должен вернуть количество ключей в таблице в диапазоне [key1, key2], поэтому для примера в строке ключей типа «BEIOU» диапазон от «B» и «U», он должен возвращать 5, поскольку между «B» и «B» есть 5 ключей.»U». Однако моя текущая программа возвращает 4. Если я проверяю ту же строку «BEIOU», но диапазон от «A» до «Z», то он возвращает 5, поскольку между ними 5 ключей, но для «B» и «U» он возвращает 4. Как я могу это исправить?

 public class SortedArrayST<Key extends Comparable<Key>, Value> {
    private static final int MIN_SIZE = 2;
    private Key[] keys;     
    private Value[] vals;  
    private int N = 0;  

    public SortedArrayST() {
        this(MIN_SIZE);
    }

    @SuppressWarnings("unchecked")
    public SortedArrayST(int size) {
        keys = (Key[])(new Comparable[size]);
        vals = (Value[])(new Object[size]);
    }

    public SortedArrayST(Key[] keys, Value[] vals) {
        this(keys.length < MIN_SIZE ? MIN_SIZE : keys.length);
        N = (keys.length == vals.length ? keys.length : 0);
        int i;
        for (i = 1; i < N amp;amp; keys[i].compareTo(keys[i - 1]) > 0; i  );
        if (i < N) { // input is not sorted
            System.err.println("SortedArrayST(Key[], Value[]) constructor error:");
            System.err.println("Given keys array of size "   N   " was not sorted!");
            System.err.println("Initializing an empty symbol table!");
            N = 0;
        } else {
            for (i = 0; i < N; i  ) {
                this.keys[i] = keys[i];
                this.vals[i] = vals[i];
            }
        }
    }

    public int countRange(Key key1, Key key2) {
        int firstkey = 0;
        int secondkey = 0;
        int count = 0;
        if(key1.compareTo(key2)>0) {
            firstkey = rank(key1);
            secondkey = rank(key2);
            count = (firstkey - secondkey   1);
        }
        else if(key2.compareTo(key1)>0) {
            secondkey = rank(key2);
            firstkey = rank(key1);
            count = (secondkey - firstkey   1);
        }
        return count;
    
    }

    public int rank(Key key) {
         int lo = 0, hi = N-1; 
            while (lo <= hi) { 
                int mid = lo   (hi - lo) / 2; 
                int cmp = key.compareTo(keys[mid]);
                if      (cmp < 0) hi = mid - 1; 
                else if (cmp > 0) lo = mid   1; 
                else return mid; 
            } 
            return lo;
        } 


    public static void main(String[] args) {    
        allCountRangeTests();
}
    public static void allCountRangeTests() {
        testCountRange("BEIOU","13456", "B","U", 5);   
        testCountRange("BEIOU","13456", "U","B", 5);  
        testCountRange("BEIOU","13456", "A","Z",5);  
        testCountRange("BEIOU","13456", "C","P",3);   
    }
    
    public static SortedArrayST<String,String> from (String keyData, String valData) {
        int n = keyData.length();
        if ( n != valData.length()) throw new NullPointerException(" from: mismatch sizes");
        String[] keys = new String[n];
        String[] vals = new String[n];
        for (int i=0; i < n; i   ) {
            keys[i] = keyData.substring(i, i 1); 
            vals[i] = valData.substring(i, i 1);  
        }
        return new SortedArrayST(keys,vals);
    }

    public static void testCountRange( String keyData, String valData, String key1,String key2, int expected) {
        SortedArrayST<String, String> x = from(keyData,valData);
        int actual = x.countRange(key1,key2);
        if ( actual == expected)  // test passes
            StdOut.format("countRangeTest: Correct  Keys: %s, key1: %s  key2: %s     actual: %d expected: %dn", keyData, key1,key2, actual,expected);
        else
            StdOut.format("countRangeTest: *Error*  Keys: %s, key1: %s  key2: %s     actual: %d expected: %dn", keyData, key1,key2, actual,expected);
    }
}
  

Комментарии:

1. Как это rank(Key) реализовано?

2. открытый класс SortedArrayST<Ключ расширяет сопоставимый<Ключ>, значение> { private static final int MIN_SIZE = 2; закрытый ключ[] ключи; // массив ключей private Value[] vals; // массив значений private int N = 0; // размер таблицы символов,

3. Недостаточно полезно. Можете ли вы обновить свой вопрос, чтобы добавить больше деталей?

4. Извините, реализация ранга здесь

5. Что такое a Key ?

Ответ №1:

Я вижу две проблемы, которые вместе могут объяснить ваши результаты. Во-первых, ваши две строки:

 count = secondkey - firstkey;
  

должно быть:

 count = secondkey - firstkey   1;
  

поскольку в любом диапазоне X ..X есть один ключ, а не 0. Это объясняет, почему вы получаете ‘4’, когда ожидаете получить ‘5’. Но это также означает, что вы получите «6», когда сейчас получаете «5». Итак, что-то еще не так….

Если в вашем rank методе, если вы когда-нибудь выйдете из while цикла, вы вернетесь lo , то есть сейчас > hi , поэтому вы вернете число, которое слишком велико. В этом случае вы хотите вернуться hi . Ваш двоичный поиск в остальном кажется нормальным с первого взгляда. Не имея всего вашего кода, я фактически ничего не могу запустить.

Комментарии:

1. Здравствуйте, я обновил приведенный выше код, чтобы вы могли его протестировать. Я попытался добавить 1 и изменить возврат на hi, но, похоже, это не исправило результат на 1 больше, чем должно быть.