Advertisement
LukacikPavel

ConverteTruchuUpraveny

Nov 30th, 2018
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.60 KB | None | 0 0
  1. package sk.upjs.ics.agilnaRuka.romanCalculator;
  2.  
  3. import java.util.HashSet;
  4.  
  5. public class GeneralRomanNumberConverter {
  6.  
  7.     public static final int ROMAN_NUMBER_IS_INCORRECT = -9999;
  8.     public static final int ROMAN_DIGITS_NOT_VALID = -9999;
  9.     public static final String OUT_OF_INTERVAL = "OUT_OF_INTERVAL";
  10.     public static final int LAST_SYMBOL_IN_ROMAN_DIGITS_DEFAULT = -9999;
  11.     public static final int SMALLEST_NUMBER_ALLOWED = 1;
  12.     public static final char NUMBER_NOT_IN_ROMAN_DIGITS = '$';
  13.     public static final int SYMBOL_NOT_IN_ROMAN_DIGITS = -9999;
  14.     public static final int NUMBER_NOT_FROM_ROMAN_DIGITS = -9999;
  15.  
  16.     // pomocna metoda pouzita pri integerToRoman, pre skratenie zapisu
  17.     String repeatChar(char character, int repetionNumber) {
  18.         String result = "";
  19.         for (int i = 0; i < repetionNumber; i++) {
  20.             result = result + character;
  21.         }
  22.         return result;
  23.     }
  24.  
  25.     // -- pomocne metody na otestovanie korektnosti RomanDigits zaciatok
  26.     boolean isEachUppercaseEnglishLetter(String RomanDigits) {
  27.         for (int i = 0; i < RomanDigits.length(); i++) {
  28.             if (Character.isUpperCase(RomanDigits.charAt(i)) == false) {
  29.                 return false;
  30.             }
  31.         }
  32.         return true;
  33.     }
  34.  
  35.     boolean isEachCharacterUnique(String RomanDigits) {
  36.         HashSet<Character> hashSet = new HashSet<>();
  37.         for (int i = 0; i < RomanDigits.length(); i++) {
  38.             char character = RomanDigits.charAt(i);
  39.             if (hashSet.contains(character)) {
  40.                 return false;
  41.             } else {
  42.                 hashSet.add(character);
  43.             }
  44.         }
  45.         return true;
  46.     }
  47.  
  48.     boolean areRomanDigitsValid(String RomanDigits) {
  49.         if (RomanDigits == null || RomanDigits.isEmpty() || !isEachCharacterUnique(RomanDigits)
  50.                 || !isEachUppercaseEnglishLetter(RomanDigits)) {
  51.             return false;
  52.         }
  53.         return true;
  54.     }
  55.     // --pomocne metody na otestovanie korektnosti RomanDigits koniec
  56.  
  57.     // -- pomocne metody pre skratenie zapisu isNumberInRomanDigits
  58.     int lastSymbolOfRomanDigitsValue(String RomanDigits) {
  59.         if (areRomanDigitsValid(RomanDigits)) {
  60.             if ((RomanDigits.length() - 1) % 2 == 0) {
  61.                 return (int) Math.pow(10, (RomanDigits.length() - 1) / 2);
  62.             } else {
  63.                 return (int) (Math.pow(10, (RomanDigits.length() - 1 + 1) / 2) / 2);
  64.             }
  65.         }
  66.         return LAST_SYMBOL_IN_ROMAN_DIGITS_DEFAULT;
  67.     }
  68.  
  69.     int removeAllowedNumberOfTailingZeroes(int number, String RomanDigits) {
  70.         for (int i = 0; i < (RomanDigits.length() - 1) / 2; i++) {
  71.             if (number % 10 == 0) {
  72.                 number = number / 10;
  73.             }
  74.         }
  75.  
  76.         return number;
  77.     }
  78.     // -- pomocne metody pre skratenie zapisu isNumberInRomanDigits
  79.  
  80.     // pomocna metoda
  81.     int getHighestPossibleValue(String RomanDigits) {
  82.         if (areRomanDigitsValid(RomanDigits)) {
  83.             int result = 0;
  84.             int lastSymbolValue = lastSymbolOfRomanDigitsValue(RomanDigits);
  85.             if (Integer.toString(lastSymbolValue).startsWith("1")) {
  86.                 result = lastSymbolValue * 4 - 1;
  87.             }
  88.             if (Integer.toString(lastSymbolValue).startsWith("5")) {
  89.                 result = (lastSymbolValue * 2 - (lastSymbolValue / 5) - 1);
  90.             }
  91.             return result;
  92.         }
  93.         return ROMAN_DIGITS_NOT_VALID;
  94.     }
  95.  
  96.     // -- pomocne metody na overenie ci sa dane cislo alebo znak vyskytuje v
  97.     // RomanDigits
  98.     boolean isSymbolInRomanDigits(char symbol, String RomanDigits) {
  99.         if (RomanDigits == null) {
  100.             return false;
  101.         }
  102.         return (RomanDigits.indexOf(symbol) >= 0);
  103.     }
  104.  
  105.     boolean isNumberInRomanDigits(int number, String RomanDigits) {
  106.         if (areRomanDigitsValid(RomanDigits) == false) {
  107.             return false;
  108.         }
  109.  
  110.         int numberCopy = number;
  111.         int lastSymbolValue = lastSymbolOfRomanDigitsValue(RomanDigits);
  112.         number = removeAllowedNumberOfTailingZeroes(number, RomanDigits);
  113.  
  114.         if ((number == 1 || number == 5) && numberCopy <= lastSymbolValue) {
  115.             return true;
  116.         }
  117.  
  118.         return false;
  119.     }
  120.     // -- pomocne metody na overenie ci sa dane cislo alebo znak vyskytuje v
  121.     // RomanDigits
  122.  
  123.     // pomocna metoda na overenie, ci sa RomanNumber sklada iba z RomanDigits
  124.     boolean isNumberFromRomanDigits(String RomanDigits, String RomanNumber) {
  125.         for (int i = 0; i < RomanNumber.length(); i++) {
  126.             if (isSymbolInRomanDigits(RomanNumber.charAt(i), RomanDigits) == false) {
  127.                 return false;
  128.             }
  129.         }
  130.         return true;
  131.     }
  132.  
  133.     // -- pomocne metody
  134.     char getSymbolOfValue(int number, String RomanDigits) {
  135.         if (isNumberInRomanDigits(number, RomanDigits) == false) {
  136.             return NUMBER_NOT_IN_ROMAN_DIGITS;
  137.         }
  138.  
  139.         String numberAsString = Integer.toString(number);
  140.         int numberLength = Integer.toString(number).length(); // numberAsString.length();
  141.         int result = 0;
  142.  
  143.         if (numberAsString.startsWith("1")) {
  144.             result = (numberLength - 1) * 2;
  145.         }
  146.         if (numberAsString.startsWith("5")) {
  147.             result = (numberLength * 2) - 1;
  148.         }
  149.         return RomanDigits.charAt(result);
  150.     }
  151.  
  152.     int getValueOfSymbol(char symbol, String RomanDigits) {
  153.         if (isSymbolInRomanDigits(symbol, RomanDigits) == false) {
  154.             return SYMBOL_NOT_IN_ROMAN_DIGITS;
  155.         }
  156.  
  157.         int symbolPositionInAlphabet = RomanDigits.indexOf(symbol);
  158.         if (symbolPositionInAlphabet % 2 == 0) {
  159.             return (int) Math.pow(10, symbolPositionInAlphabet / 2);
  160.         } else {
  161.             return (int) (Math.pow(10, (symbolPositionInAlphabet + 1) / 2) / 2);
  162.         }
  163.     }
  164.     // -- pomocne metody
  165.  
  166.     // prevedie romanNumber, ale vrati hodnotu pri nekorektnom zapise
  167.     int RomanNumeralsConverterWithoutValidation(String romanNumber, String RomanDigits) {
  168.  
  169.         int result = 0;
  170.         int symbolValue = 0;
  171.         int nextSymbolValue = 0;
  172.  
  173.         for (int i = 0; i < romanNumber.length(); i++) { // i = index
  174.             symbolValue = getValueOfSymbol(romanNumber.charAt(i), RomanDigits);
  175.             if (symbolValue == SYMBOL_NOT_IN_ROMAN_DIGITS) {
  176.                 return symbolValue;
  177.             }
  178.             if (i + 1 < romanNumber.length()) {
  179.                 nextSymbolValue = getValueOfSymbol(romanNumber.charAt(i + 1), RomanDigits);
  180.                 if (symbolValue >= nextSymbolValue) {
  181.                     result = result + symbolValue;
  182.                 } else {
  183.                     result = result + nextSymbolValue - symbolValue;
  184.                     i++;
  185.                 }
  186.             } else {
  187.                 result = result + symbolValue;
  188.                 i++;
  189.             }
  190.         }
  191.         return result;
  192.     }
  193.  
  194.     // vzdy vrati rimske cislo v korektnej podobe
  195.     String integerToRoman(int number, String RomanDigits) {
  196.  
  197.         if (getHighestPossibleValue(RomanDigits) < number || number < SMALLEST_NUMBER_ALLOWED) {
  198.             return OUT_OF_INTERVAL;
  199.         }
  200.         int divider = (int) Math.pow(10, Integer.toString(number).length() - 1);
  201.         String romanNumber = "";
  202.  
  203.         while (number > 0) {
  204.             int lastDigit = number / divider;
  205.             if (lastDigit <= 3) {
  206.                 romanNumber += repeatChar(getSymbolOfValue(divider, RomanDigits), lastDigit);
  207.             } else if (lastDigit == 4) {
  208.                 romanNumber += ("" + getSymbolOfValue(divider, RomanDigits)
  209.                         + getSymbolOfValue(divider * 5, RomanDigits));
  210.             } else if (5 <= lastDigit && lastDigit <= 8) {
  211.                 romanNumber += (getSymbolOfValue(divider * 5, RomanDigits)
  212.                         + repeatChar(getSymbolOfValue(divider, RomanDigits), lastDigit - 5));
  213.             } else if (lastDigit == 9) {
  214.                 romanNumber += ("" + getSymbolOfValue(divider, RomanDigits)
  215.                         + getSymbolOfValue(divider * 10, RomanDigits));
  216.             }
  217.             number = number % divider;
  218.             divider /= 10;
  219.         }
  220.         return romanNumber;
  221.     }
  222.  
  223.     // ak je RomanNumber v korektnej forme vrat jeho hodnotu, inak -9999
  224.     int RomanNumeralsConverter(String RomanDigits, String RomanNumber) {
  225.         if (areRomanDigitsValid(RomanDigits) == false) {
  226.             return ROMAN_DIGITS_NOT_VALID;
  227.         }
  228.         if (isNumberFromRomanDigits(RomanDigits, RomanNumber) == false) {
  229.             return NUMBER_NOT_FROM_ROMAN_DIGITS;
  230.         }
  231.  
  232.         int valueOfRomanNumber = RomanNumeralsConverterWithoutValidation(RomanNumber, RomanDigits);
  233.         String correctFormOfRomanNumber = integerToRoman(valueOfRomanNumber, RomanDigits);
  234.         if (RomanNumber.equals(correctFormOfRomanNumber)) {
  235.             return valueOfRomanNumber;
  236.         }
  237.         return ROMAN_NUMBER_IS_INCORRECT;
  238.     }
  239. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement