Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package sk.upjs.ics.agilnaRuka.romanCalculator;
- import java.util.HashSet;
- public class GeneralRomanNumberConverter {
- public static final int ROMAN_NUMBER_IS_INCORRECT = -9999;
- public static final int ROMAN_DIGITS_NOT_VALID = -9999;
- public static final String OUT_OF_INTERVAL = "OUT_OF_INTERVAL";
- public static final int LAST_SYMBOL_IN_ROMAN_DIGITS_DEFAULT = -9999;
- public static final int SMALLEST_NUMBER_ALLOWED = 1;
- public static final char NUMBER_NOT_IN_ROMAN_DIGITS = '$';
- public static final int SYMBOL_NOT_IN_ROMAN_DIGITS = -9999;
- public static final int NUMBER_NOT_FROM_ROMAN_DIGITS = -9999;
- // pomocna metoda pouzita pri integerToRoman, pre skratenie zapisu
- String repeatChar(char character, int repetionNumber) {
- String result = "";
- for (int i = 0; i < repetionNumber; i++) {
- result = result + character;
- }
- return result;
- }
- // -- pomocne metody na otestovanie korektnosti RomanDigits zaciatok
- boolean isEachUppercaseEnglishLetter(String RomanDigits) {
- for (int i = 0; i < RomanDigits.length(); i++) {
- if (Character.isUpperCase(RomanDigits.charAt(i)) == false) {
- return false;
- }
- }
- return true;
- }
- boolean isEachCharacterUnique(String RomanDigits) {
- HashSet<Character> hashSet = new HashSet<>();
- for (int i = 0; i < RomanDigits.length(); i++) {
- char character = RomanDigits.charAt(i);
- if (hashSet.contains(character)) {
- return false;
- } else {
- hashSet.add(character);
- }
- }
- return true;
- }
- boolean areRomanDigitsValid(String RomanDigits) {
- if (RomanDigits == null || RomanDigits.isEmpty() || !isEachCharacterUnique(RomanDigits)
- || !isEachUppercaseEnglishLetter(RomanDigits)) {
- return false;
- }
- return true;
- }
- // --pomocne metody na otestovanie korektnosti RomanDigits koniec
- // -- pomocne metody pre skratenie zapisu isNumberInRomanDigits
- int lastSymbolOfRomanDigitsValue(String RomanDigits) {
- if (areRomanDigitsValid(RomanDigits)) {
- if ((RomanDigits.length() - 1) % 2 == 0) {
- return (int) Math.pow(10, (RomanDigits.length() - 1) / 2);
- } else {
- return (int) (Math.pow(10, (RomanDigits.length() - 1 + 1) / 2) / 2);
- }
- }
- return LAST_SYMBOL_IN_ROMAN_DIGITS_DEFAULT;
- }
- int removeAllowedNumberOfTailingZeroes(int number, String RomanDigits) {
- for (int i = 0; i < (RomanDigits.length() - 1) / 2; i++) {
- if (number % 10 == 0) {
- number = number / 10;
- }
- }
- return number;
- }
- // -- pomocne metody pre skratenie zapisu isNumberInRomanDigits
- // pomocna metoda
- int getHighestPossibleValue(String RomanDigits) {
- if (areRomanDigitsValid(RomanDigits)) {
- int result = 0;
- int lastSymbolValue = lastSymbolOfRomanDigitsValue(RomanDigits);
- if (Integer.toString(lastSymbolValue).startsWith("1")) {
- result = lastSymbolValue * 4 - 1;
- }
- if (Integer.toString(lastSymbolValue).startsWith("5")) {
- result = (lastSymbolValue * 2 - (lastSymbolValue / 5) - 1);
- }
- return result;
- }
- return ROMAN_DIGITS_NOT_VALID;
- }
- // -- pomocne metody na overenie ci sa dane cislo alebo znak vyskytuje v
- // RomanDigits
- boolean isSymbolInRomanDigits(char symbol, String RomanDigits) {
- if (RomanDigits == null) {
- return false;
- }
- return (RomanDigits.indexOf(symbol) >= 0);
- }
- boolean isNumberInRomanDigits(int number, String RomanDigits) {
- if (areRomanDigitsValid(RomanDigits) == false) {
- return false;
- }
- int numberCopy = number;
- int lastSymbolValue = lastSymbolOfRomanDigitsValue(RomanDigits);
- number = removeAllowedNumberOfTailingZeroes(number, RomanDigits);
- if ((number == 1 || number == 5) && numberCopy <= lastSymbolValue) {
- return true;
- }
- return false;
- }
- // -- pomocne metody na overenie ci sa dane cislo alebo znak vyskytuje v
- // RomanDigits
- // pomocna metoda na overenie, ci sa RomanNumber sklada iba z RomanDigits
- boolean isNumberFromRomanDigits(String RomanDigits, String RomanNumber) {
- for (int i = 0; i < RomanNumber.length(); i++) {
- if (isSymbolInRomanDigits(RomanNumber.charAt(i), RomanDigits) == false) {
- return false;
- }
- }
- return true;
- }
- // -- pomocne metody
- char getSymbolOfValue(int number, String RomanDigits) {
- if (isNumberInRomanDigits(number, RomanDigits) == false) {
- return NUMBER_NOT_IN_ROMAN_DIGITS;
- }
- String numberAsString = Integer.toString(number);
- int numberLength = Integer.toString(number).length(); // numberAsString.length();
- int result = 0;
- if (numberAsString.startsWith("1")) {
- result = (numberLength - 1) * 2;
- }
- if (numberAsString.startsWith("5")) {
- result = (numberLength * 2) - 1;
- }
- return RomanDigits.charAt(result);
- }
- int getValueOfSymbol(char symbol, String RomanDigits) {
- if (isSymbolInRomanDigits(symbol, RomanDigits) == false) {
- return SYMBOL_NOT_IN_ROMAN_DIGITS;
- }
- int symbolPositionInAlphabet = RomanDigits.indexOf(symbol);
- if (symbolPositionInAlphabet % 2 == 0) {
- return (int) Math.pow(10, symbolPositionInAlphabet / 2);
- } else {
- return (int) (Math.pow(10, (symbolPositionInAlphabet + 1) / 2) / 2);
- }
- }
- // -- pomocne metody
- // prevedie romanNumber, ale vrati hodnotu pri nekorektnom zapise
- int RomanNumeralsConverterWithoutValidation(String romanNumber, String RomanDigits) {
- int result = 0;
- int symbolValue = 0;
- int nextSymbolValue = 0;
- for (int i = 0; i < romanNumber.length(); i++) { // i = index
- symbolValue = getValueOfSymbol(romanNumber.charAt(i), RomanDigits);
- if (symbolValue == SYMBOL_NOT_IN_ROMAN_DIGITS) {
- return symbolValue;
- }
- if (i + 1 < romanNumber.length()) {
- nextSymbolValue = getValueOfSymbol(romanNumber.charAt(i + 1), RomanDigits);
- if (symbolValue >= nextSymbolValue) {
- result = result + symbolValue;
- } else {
- result = result + nextSymbolValue - symbolValue;
- i++;
- }
- } else {
- result = result + symbolValue;
- i++;
- }
- }
- return result;
- }
- // vzdy vrati rimske cislo v korektnej podobe
- String integerToRoman(int number, String RomanDigits) {
- if (getHighestPossibleValue(RomanDigits) < number || number < SMALLEST_NUMBER_ALLOWED) {
- return OUT_OF_INTERVAL;
- }
- int divider = (int) Math.pow(10, Integer.toString(number).length() - 1);
- String romanNumber = "";
- while (number > 0) {
- int lastDigit = number / divider;
- if (lastDigit <= 3) {
- romanNumber += repeatChar(getSymbolOfValue(divider, RomanDigits), lastDigit);
- } else if (lastDigit == 4) {
- romanNumber += ("" + getSymbolOfValue(divider, RomanDigits)
- + getSymbolOfValue(divider * 5, RomanDigits));
- } else if (5 <= lastDigit && lastDigit <= 8) {
- romanNumber += (getSymbolOfValue(divider * 5, RomanDigits)
- + repeatChar(getSymbolOfValue(divider, RomanDigits), lastDigit - 5));
- } else if (lastDigit == 9) {
- romanNumber += ("" + getSymbolOfValue(divider, RomanDigits)
- + getSymbolOfValue(divider * 10, RomanDigits));
- }
- number = number % divider;
- divider /= 10;
- }
- return romanNumber;
- }
- // ak je RomanNumber v korektnej forme vrat jeho hodnotu, inak -9999
- int RomanNumeralsConverter(String RomanDigits, String RomanNumber) {
- if (areRomanDigitsValid(RomanDigits) == false) {
- return ROMAN_DIGITS_NOT_VALID;
- }
- if (isNumberFromRomanDigits(RomanDigits, RomanNumber) == false) {
- return NUMBER_NOT_FROM_ROMAN_DIGITS;
- }
- int valueOfRomanNumber = RomanNumeralsConverterWithoutValidation(RomanNumber, RomanDigits);
- String correctFormOfRomanNumber = integerToRoman(valueOfRomanNumber, RomanDigits);
- if (RomanNumber.equals(correctFormOfRomanNumber)) {
- return valueOfRomanNumber;
- }
- return ROMAN_NUMBER_IS_INCORRECT;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement