Как мне перевести строки, используя Java? - PullRequest
3 голосов
/ 04 октября 2010

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

Учитывая исходный массив, в котором каждая запись установлена ​​в свое значение, например, hex '37 'появилось бы в 56-й записи (позволяя 00 быть первым), затем пользователь мог бы заменить любые символы, требуемые в строке перевода.

eg1 Я хочу отобразить строку с "A" для буквенных символов, «N» для числовых символов, «B» для пробелов и «X» для чего-либо еще.Таким образом, «SL5 3QW» становится «AANBNAA».

eg2.Я хочу перевести некоторые символы, такие как «œ» (x'9D ') в «oe» (x'6F65'), «ß» в «ss», «å» в «a» и т. Д.

Как получить числовое значение из символа входной строки, чтобы использовать его в качестве индекса в массиве перевода?

Это просто с функцией CODE в Excel и простым в ассемблере IBM, но я не могу отследить метод в Java.

Ответы [ 5 ]

5 голосов
/ 04 октября 2010

Это немного не по теме, но если вы хотите сделать всеобъемлющую работу по переводу символов, вы не можете просто использовать String.charAt(int).Кодовые точки Unicode больше 65535 представлены в строках Java как два последовательных значения char.

Чистый способ справиться с этим - использовать String.codepointAt(int) для извлечения каждой кодовой точки и String.offsetByCodePoints(int, int) для перехода по позициям кодовой точки.*

3 голосов
/ 04 октября 2010

Последняя версия Unicode содержит более 107000 символов. Массив из 256 записей не сможет его обрезать.

Тем не менее, вы можете получить кодовую точку по индексу в строке, используя метод String.codepointAt(int index).

Возможно, вы также захотите использовать Character.isWhitespace(int codepoint), Character.isDigit(int codepoint) и т. Д.

См. Также http://download.oracle.com/javase/6/docs/api/java/lang/String.html и http://download.oracle.com/javase/6/docs/api/java/lang/Character.html

2 голосов
/ 04 октября 2010

HashMap<String, String> должно работать просто отлично.Нет необходимости перерабатывать такую ​​простую проблему.

1 голос
/ 04 октября 2010

Есть разные способы ответить на этот вопрос.Возможно, самый простой способ - это найти ответы на каждую из проблем в отдельности:


Задача 1:

eg1 Я хочу отобразить строку с "A" длябуквенные символы, «N» для числовых символов, «B» для пробелов и «X» для чего-либо еще.Таким образом, «SL5 3QW» становится «AANBNAA».

Простое решение:

public static String map(final String input){
    final char[] out = new char[input.length()];
    for(int i = 0; i < input.length(); i++){
        final char c = input.charAt(i);
        final char t;
        if(Character.isDigit(c)){
            t = 'N';
        } else if(Character.isWhitespace(c)){
            t = 'B';
        } else if(Character.isLetter(c)){
            t = 'A';
        } else{
            t = 'X';
        }
        out[i] = t;
    }
    return new String(out);
}

Тест:

public static void main(final String[] args){
    System.out.println(map("SL5 3QW"));
}

Выход:

AANBNAA


Задача 2:

eg2.Я хочу перевести некоторые символы, такие как «œ» (x'9D ') в «oe» (x'6F65'), «ß» в «ss», «å» в «a» и т. Д.

Решение:

Это стандартная функциональность, для этого следует использовать API нормализатора.См. эти предыдущие ответы для справки.


Общая картина

Но, если подумать, существует, конечно, более общее решениетвоя проблема.Давайте посмотрим, сколько отрицательных голосов я получу за это любителями if / else.Определите интерфейс преобразователя, который принимает определенные символы и / или классы символов и сопоставляет их с другими символами:

public interface CharTransformer{
    boolean supports(char input);
    char transform(char input);
}

А теперь определите метод, который можно вызывать с помощью строки и набора таких преобразователей.Для каждого отдельного символа каждый преобразователь будет запрошен, чтобы видеть, поддерживает ли он этот символ.Если он это сделает, пусть он сделает трансформацию.Если для персонажа не найден Трансформер, выведите исключение.

public static String mapWithTransformers(final String input,
    final Collection<? extends CharTransformer> transformers){
    final char[] out = new char[input.length()];
    for(int i = 0; i < input.length(); i++){
        final char c = input.charAt(i);
        char t = 0;
        boolean matched = false;
        for(final CharTransformer tr : transformers){
            if(tr.supports(c)){
                matched = true;
                t = tr.transform(c);
                break;
            }
        }
        if(!matched){
            throw new IllegalArgumentException("Found no Transformer for char: "
                + c);
        }
        out[i] = t;
    }
    return new String(out);
}

Еще одна вещь: Карты

Примечание: Другие предложили использовать Карту.Хотя я не думаю, что стандартная карта подходит для этой задачи, вы можете использовать MapMaker.makeComputingMap (функция) в Guava для вычисления замен по мере необходимости (и автоматического их кэширования).Таким образом, у вас будет лениво инициализированная карта кэширования.

1 голос
/ 04 октября 2010

Как говорит Кристоффер, для символов Unicode недостаточно 256-элементного массива.

Одним из способов является использование HashMap<Character,String>, сопоставляющего каждый символ с требуемым переведенным значением, и использование String.charAt() для извлечения каждого символа по очереди. Вы также можете посмотреть на некоторые методы класса Character, такие как isDigit() и isLetter(), чтобы выполнить некоторую работу; это может быть проще, чем составление отображения для каждой «буквы» (возможно, на нескольких языках).

Используя HashMap, вам нужно только определить сопоставления для символов, которые вы хотите перевести. Для тех, у которых нет сопоставления (hashmap возвращает null), вы можете либо указать значение по умолчанию, либо пропустить их без изменений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...