Професионална програма
Loading...
+ Нов въпрос
amanis avatar amanis 3 Точки

Mankind задача от Inheritance

Здравейте, някой може ли да хвърли едно око на тази задача. Тествам я мисля, че всичко си работи, обаче има нещо малко което не успявам да видя и в джъдж ми излиза следната грешка :

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
	at com.company.p3_Mankind.Main.main(Main.java:17)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at _$SandboxExecutor.main(_$SandboxExecutor.java:38)

 

 

Моето решение : https://github.com/dimhristov/OOP_Basics/tree/master/05_Inheritance_Exercise/src/com/company/p3_Mankind

 

условие: Задача 3 от https://softuni.bg/trainings/resources/officedocument/32076/exercise-problem-descriptions-java-oop-basics-june-2018/1976

 

judge: https://judge.softuni.bg/Contests/Practice/Index/226#2

Благодаря!

Тагове:
1
Module: Java Advanced
MartinBG avatar MartinBG 3852 Точки

Eexception-а е доста конкретен и е за този ред:

String facultyNumber = studentTokens[2];

Може да гръмне с тази грешка само ако studentTokens е с два елемента, което може да се получи при входни данни от типа на 

"Pesho 123456678" или "Ivan Ivanov", т.е. съставени само от два стринга.

Тъй като за Student са необходими 3, един от тях ще е null. В условието на задачата няма описан exception при невалиден входен стринг, т.е. трябва да хвърлим някой от exception-ите, описани за Human или Student. За да стане това, трябва да знаем кой елемент липсва (т.е. е null).

Това най-лесно може да стане с използването на regex с (named) групи за всяка от частите. Регекса трябва да е релаксиран (всяка от 3-те групи трябва да е опционална) за да бъде успешно мачването на стринга. При вземане на липсваща група се връща null, който после може да бъде подаден чрез конструктора и прихванат като невалиден аргумент от сетърите.

 

ПП

yes за добре зададен въпрос с всичко необходимо към него: проблем, код, условие на задачата и линк към Judge smiley

0
30/04/2020 00:26:35
amanis avatar amanis 3 Точки

Благодаря много за отговора :) Само че не ми е много ясно как да го направя това с регекса. Дали ще може малко повече инфо? Опитвах различни неща досега като добавих в maina  и в student класа проверки първо за да не ми гърми ако не въведа факултетен номер и после ако е null да ми хвърля грешка. Само че в условието на задачата не е описано каква грешка да хвърли при това положение. Гледах и урока от 2018 мисля където е решена задачата обаче там не правят тези проверки за Null и им минава. Предполагам тогава не е имало тези тестове в judge и се чудя дали условието евентуално не е леко променено да се казва какъв exception да хвърля.

Но все пак ми стана интересно как би могло да стане това с регексите. 

 

В края на краищата успях и да чийтна judge като хвърлиш Exception "Test Passed!" :D, но това разбира се не е решението което искам да достигна :)
 

Поздрави!

 

А и updatnah в горния линк в GitHub новите проверки, които правя които знам че не са ок разбира се 

1
MartinBG avatar MartinBG 3852 Точки

@amanis

Погледнах новото решение в github и ми изглежда ОК - все пак липсата на facultyNumber (т.е. null) си е невалиден facultyNumber и е нормално да се хвърли такъв exception.

Проверката за брой student елементи в main също е ОК, защото ни предпазва от хвърлянето ArrayIndexOutOfBoundsException. Друг е въпросът, че тази валидация е по-добре да се прави другаде, например във Factory клас, който приема стринга и връща инстанция на Student при валиден такъв или хвърля exception-a.

 

Относно регекса. Погледнах отново условието на задачата и за съжаление то не е достатъчно конкретно за да може да се направи разграничение между фамилия и факултетен номер (също стринг) на ниво регекс, което ни оставя с 4 възможни варианта:

- празен стринг

- има само първо име

- има първо име и фамилия

- има първо име, фамилия и факултетен номер

Горното и фактът, че същинската валидация на всеки елемент се прави при извикване на конструктора, обезсмисля използването на регекс, защото и .split("\\s+") + проверка колко елемента има в масива ни върши същата работа.

 

Нека променим малко условието, с цел да демонстрираме как може да се използва подходът с regex:

- първо име - задължително:  започва с главна буква и продължава само малки букви, дължина 4 - 8 символа

- фамилия - опция: започва с главна буква и продължава само малки букви, дължина поне 3 символа

- факултетен номер - опция: само цифри, дължина 5-10 символа

 

Следният регекс покрива горните условия (demo):

^(?<name>[A-Z][a-z]{3,7})(\s+(?<family>[A-Z][a-z]{2,}))?(\s+(?<facultyNumber>\d{5,10}))?$

Ето и пример как може да се използва (demo):

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MyClass {
    public static void main(String args[]) {
        final String regex = "^(?<name>[A-Z][a-z]{3,7})(\\s+(?<family>[A-Z][a-z]{2,}))?(\\s+(?<facultyNumber>\\d{5,10}))?$";
        final List<String> strings = List.of(
                "Valid All 12345",
                "Valid Names",
                "With 123456",
                "Name",
                "Long Familiiiiiiiiiiiiiiiii 12345",
                "Invalid Faculcy 111111111111111",
                "Invalid family 22222222",
                "invalid Name 33333333",
                "Verylongname Error",
                "InvaliD Name 44444",
                "Invalid FamilY 55555",
                "Name12345");

        final Pattern pattern = Pattern.compile(regex);

        strings.forEach(str -> {
            Matcher matcher = pattern.matcher(str);
            if (matcher.matches()) {
                String name = matcher.group("name");
                String family = matcher.group("family");
                String facultyNumber = matcher.group("facultyNumber");
                System.out.println("Name: " + name + ", Family: " + family + ", facultyNumber: " + facultyNumber); // note that missing parts are "null"
            } else {
                 System.out.println("Invalid student format: " + str); //throw new IllegalArgumentException("Invalid student format: " + str);
            }
        });
    }
}

Output:

Name: Valid, Family: All, facultyNumber: 12345
Name: Valid, Family: Names, facultyNumber: null
Name: With, Family: null, facultyNumber: 123456
Name: Name, Family: null, facultyNumber: null
Name: Long, Family: Familiiiiiiiiiiiiiiiii, facultyNumber: 12345
Invalid student format: Invalid Faculcy 111111111111111
Invalid student format: Invalid family 22222222
Invalid student format: invalid Name 33333333
Invalid student format: Verylongname Error
Invalid student format: InvaliD Name 44444
Invalid student format: Invalid FamilY 55555
Invalid student format: Name12345

 

0
30/04/2020 18:53:14
amanis avatar amanis 3 Точки

@MartinBG

Леле... много ти благодаря за подробния отговор и отделеното време. Определено ще го пробвам това с регекса :)

1