Каковы ловушки в реализации двоичного поиска?

Моя цель здесь - создать массив JTextFields, в котором есть keylistener. Этот keylistener должен помещать в JTextField

blockquote>

ничего, кроме чисел, которые должны быть введены). Короткий ответ, таким образом, не используется KeyListener, он не будет фиксировать варианты использования пользователя вставка текста в поле или если поле обновляется программно

Вместо этого вы хотите использовать DocumentFilter, например

public class IntFilter extends DocumentFilter {

    @Override
    public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {

        StringBuilder buffer = new StringBuilder(text.length());
        for (int index = 0; index < text.length(); index++) {
            if (Character.isDigit(text.charAt(index))) {
                buffer.append(text.charAt(index));
            }
        }
        super.insertString(fb, offset, buffer.toString(), attr);
        ValidationListener listener = getValidationListener();
    }

    @Override
    public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String string, AttributeSet attr) throws BadLocationException {
        if (length > 0) {
            fb.remove(offset, length);
        }
        insertString(fb, offset, string, attr);
    }
}

См. Реализация фильтра документов для более подробной информации и Примеры DocumentFilter для других примеров

Также следует изменить цвет фона JTextField, если введенный номер не является int

blockquote>

Вы можете выполнить проверку по почте с помощью InputVerifier, но это может не соответствовать вашим потребностям.

Это создает проблему. DocumentFilter, не должен заботиться о поле, к которому он применяется, но поскольку он выполняет проверку, он будет знать, когда что-то пошло не так, поэтому нам нужно, чтобы фильтр предоставлял уведомление, когда проверка не удалась. .

Во-первых, нам нужен какой-то обратный вызов, который говорит нам, когда проверка не прошла или прошла ...

public interface ValidationListener {

    public void validationFailed();

    public void validationPassed();
}

Затем нам нужно обновить фильтр, чтобы поднять эти уведомления на основе его правила ...

public class IntFilter extends DocumentFilter {

    private ValidationListener validationListener;

    public void setValidationListener(ValidationListener validationListener) {
        this.validationListener = validationListener;
    }

    public ValidationListener getValidationListener() {
        return validationListener;
    }

    @Override
    public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {

        boolean validationFailed = false;
        StringBuilder buffer = new StringBuilder(text.length());
        for (int index = 0; index < text.length(); index++) {
            if (Character.isDigit(text.charAt(index))) {
                buffer.append(text.charAt(index));
            } else {
                validationFailed = true;
            }
        }
        super.insertString(fb, offset, buffer.toString(), attr);
        ValidationListener listener = getValidationListener();
        if (listener != null) {
            if (validationFailed) {
                listener.validationFailed();
            } else {
                listener.validationPassed();
            }
        }
    }

    @Override
    public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String string, AttributeSet attr) throws BadLocationException {
        if (length > 0) {
            fb.remove(offset, length);
        }
        insertString(fb, offset, string, attr);
    }
}

Затем нам нужно определить нашу реализацию ValidationListener для выполнения необходимых действий ...

public class DefaultValidationHandler implements ValidationListener {

    private JTextField field;

    public DefaultValidationHandler(JTextField field) {
        this.field = field;
    }

    public JTextField getField() {
        return field;
    }

    @Override
    public void validationFailed() {
        getField().setBackground(Color.RED);
    }

    @Override
    public void validationPassed() {
        getField().setBackground(UIManager.getColor("TextField.background"));
    }

}

Здесь слушатель поддерживает ссылка на поле, которое мы хотим контролировать

. Затем мы связываем его вообще ...

JTextField field = new JTextField(10);
DefaultValidationHandler handler = new DefaultValidationHandler(field);
IntFilter filter = new IntFilter();
filter.setValidationListener(handler);
((AbstractDocument)field.getDocument()).setDocumentFilter(filter);

Filter [/g5]

Это [20] Некоторые улучшения могут включать передачу ссылки DocumentFilter назад с помощью методов ValidationListener, вы можете использовать это для поиска поле, которое вызвало событие и обновило его, уменьшив количество обработчиков, ght необходимо создать, например.

Например

Обновлен ValidationListener

public interface ValidationListener {

    public void validationFailed(DocumentFilter filter);

    public void validationPassed(DocumentFilter filter);
}

Обновлен IntFilter

public class IntFilter extends DocumentFilter {

    private ValidationListener validationListener;

    public void setValidationListener(ValidationListener validationListener) {
        this.validationListener = validationListener;
    }

    public ValidationListener getValidationListener() {
        return validationListener;
    }

    @Override
    public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {

        boolean validationFailed = false;
        StringBuilder buffer = new StringBuilder(text.length());
        for (int index = 0; index < text.length(); index++) {
            if (Character.isDigit(text.charAt(index))) {
                buffer.append(text.charAt(index));
            } else {
                validationFailed = true;
            }
        }
        super.insertString(fb, offset, buffer.toString(), attr);
        ValidationListener listener = getValidationListener();
        if (listener != null) {
            if (validationFailed) {
                listener.validationFailed(this);
            } else {
                listener.validationPassed(this);
            }
        }
    }

    @Override
    public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String string, AttributeSet attr) throws BadLocationException {
        if (length > 0) {
            fb.remove(offset, length);
        }
        insertString(fb, offset, string, attr);
    }
}

Пример реализации ...

public class TestPane extends JPanel {

    private Map fields;

    public TestPane() {

        fields = new HashMap<>(25);
        ValidationListener listener = new ValidationListener() {

            @Override
            public void validationFailed(DocumentFilter filter) {
                JTextField field = fields.get(filter);
                if (field != null) {
                    field.setBackground(Color.RED);
                }
            }

            @Override
            public void validationPassed(DocumentFilter filter) {
                JTextField field = fields.get(filter);
                if (field != null) {
                    field.setBackground(UIManager.getColor("TextField.background"));
                }
            }
        };

        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        for (int index = 0; index < 10; index++) {
            JTextField field = new JTextField(10);
            IntFilter filter = new IntFilter();
            filter.setValidationListener(listener);
            ((AbstractDocument) field.getDocument()).setDocumentFilter(filter);
            fields.put(filter, field);
            add(field, gbc);
        }

    }

}
49
задан joeforker 2 February 2009 в 19:47
поделиться

4 ответа

Вот некоторые, о которых я могу думать:

  • Ошибки диапазона , при определении границы следующего интервала
  • Обработка дублирующихся объектов , если Вы, предполагает для возврата первого равного объекта в массиве, но вместо этого возвратила последующий равный объект
  • Числовые потери значимости/переполнение , когда вычислительные индексы, с огромными массивами
  • Рекурсивный по сравнению с нерекурсивный реализация, проектное решение, которое необходимо рассмотреть

, Являются ими, что Вы имеете в виду?

30
ответ дан Zach Scrivena 7 November 2019 в 21:32
поделиться

Read это . Реализация двоичного поиска Java скрыла ошибку в течение почти десятилетия, прежде чем кто-либо нашел его.

ошибка является целочисленным переполнением. Это не вызвало людей проблемы, потому что едва ли кто-то искал достаточно большие структуры данных.

15
ответ дан Dan Dyer 7 November 2019 в 21:32
поделиться

Если у Вас есть книга Жемчуга Программирования поблизости, необходимо проверить главу 4.

edit2: Как указано в комментариях, можно загрузить черновую главу, я упомянул веб-сайт Автора: http://www.cs.bell-labs.com/cm/cs/pearls/sketch04.html

7
ответ дан Tiago 7 November 2019 в 21:32
поделиться

Отказ полагать, что при вычислении средней точки между двумя индексами, суммируя высокие и низкие значения может привести к целочисленному переполнению.

Ссылка

1
ответ дан tvanfosson 7 November 2019 в 21:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: