Разбивает строку, которая включает фамилию, имя и инициал в Java - PullRequest
0 голосов
/ 18 апреля 2020

Вопрос:

Разбиение строки, включающей фамилию, имя и инициал в Java.

Мой код:

    int index = 0;

    String first = "", last= "", initial= "";


    for ( int i = 0; i < name.length(); i++) {
        if (name.charAt(i) == ',') {
             last = name.substring(0,i);
             index = i+1;
          }
        else if(name.charAt(i) ==' ') {
            first = name.substring(index,i);    
        }
        else if(name.charAt(i) == '.') {
            initial = name.substring(i-1, i);
        }
    }

    return (first + " " +initial+ " " + last);
}

Я не могу выяснить, что я делаю не так. Я потратил более 5 часов, пытаясь понять это, и мне нужна помощь.

При запуске тесты кажутся неудачными.

Что я получаю в консоли:

 stringReformat demo1.  the substring(1,5) is: eato
 stringReformat demo2.  the character in position 4 is NOT a comma, it is: o
Failed  testStringReformat:  Expected: (Alex P Keaton)  Actual ( Alex P Keaton) 
 stringReformat demo1.  the substring(1,5) is: teem
 stringReformat demo2.  the character in position 4 is NOT a comma, it is: m
Failed  testStringReformat:  Expected: (Lois Steem)  Actual (  Steem) 
 stringReformat demo1.  the substring(1,5) is: oyd,
 stringReformat demo2.  the character in position 4 is a comma
Failed  testStringReformat:  Expected: (Luke A Boyd)  Actual ( Luke A.   A Boyd) 
 stringReformat demo1.  the substring(1,5) is: ssen
 stringReformat demo2.  the character in position 4 is NOT a comma, it is: n
Failed  testStringReformat:  Expected: (Lotta B Essen)  Actual ( Lotta B Essen) 
 stringReformat demo1.  the substring(1,5) is: itte
 stringReformat demo2.  the character in position 4 is NOT a comma, it is: e
Failed  testStringReformat:  Expected: (Candace B Rittenoff)  Actual ( Candace B Rittenoff) 
 stringReformat demo1.  the substring(1,5) is: arly
 stringReformat demo2.  the character in position 4 is NOT a comma, it is: y
Failed  testStringReformat:  Expected: (Stu Early)  Actual (  Early) 
 stringReformat demo1.  the substring(1,5) is: eato
 stringReformat demo2.  the character in position 4 is NOT a comma, it is: o
Failed  testStringReformat:  Expected: (Alex P Keaton)  Actual ( Alex P Keaton) 
 stringReformat demo1.  the substring(1,5) is: rupt
 stringReformat demo2.  the character in position 4 is NOT a comma, it is: t
Failed  testStringReformat:  Expected: (Vera A Bruptly)  Actual ( Vera A. A Bruptly) 
 stringReformat demo1.  the substring(1,5) is: atso
 stringReformat demo2.  the character in position 4 is NOT a comma, it is: o
Failed  testStringReformat:  Expected: (Wanda Y Datso)  Actual ( Wanda Y Datso) 
 stringReformat demo1.  the substring(1,5) is: ilve
 stringReformat demo2.  the character in position 4 is NOT a comma, it is: e
Failed  testStringReformat:  Expected: (I O Silver)  Actual ( I O Silver) 
 finished stringReformat tests
Finished tests

1 Ответ

0 голосов
/ 18 апреля 2020

Код, который вы написали, не пройдет все тесты, и нет способа исправить это, не изменив «как это работает». Проблема в том, что пробелы нельзя использовать для разделения или разделения различных частей. Если строка типа "Steem, Lois" не заканчивается символом пробела, метод просто вернет " Steem", что неверно. Также, если строка заканчивается на " " после начальной точки, она будет содержать начальную букву внутри имени.

Я предоставил вам два разных решения.

Предположим, у нас есть строка с следующий формат "{lastname}, {firstname} {initial}.", где начальное необязательно. Эта строка передается методу StringFormat, поэтому мы предполагаем, что аргумент правильно сформирован.

Первое решение удаляет пробелы, извлекает начальное, если оно заканчивается точкой, а затем извлекает имя и фамилию. Все это делается с помощью манипуляции со строками.

public static String StringReformat(String name) {
    String initial = null, first, last;

    //Removes all whitespaces
    name = name.replaceAll("\\s", "");

    //Checks if there is initial and extracts it
    if(name.endsWith(".")) {
        initial = name.substring(name.length() - 2, name.length() - 1);
        name = name.substring(0, name.length() - 2);
    }

    //Gets first and last name
    String[] tokens = name.split(",");
    first = tokens[1];
    last = tokens[0];

    if(initial != null) {
        return first + " " + initial + " " + last;
    } else {
        return first + " " + last;
    }
}

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

public static String StringReformat(String name) {
    Pattern pattern = Pattern.compile(
        "([a-zA-Z]+)\\s*,\\s*([a-zA-Z]+)\\s*(?:([A-Z])\\.)?");

    Matcher matcher = pattern.matcher(name.trim());
    if(matcher.matches()) {
        String last = matcher.group(1);
        String first = matcher.group(2);
        String initial = matcher.group(3);

        if(initial != null) {
            return first + " " + initial + " " + last;
        } else {
            return first + " " + last;
        }
    }

    throw new IllegalArgumentException("Invalid name argument format!");
}

Второе решение лучше и более «управляемо», но труднее понять, если вы новичок.

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