Largest Roman Numeral possible by rearranging characters of a given string

• Last Updated : 10 Jun, 2021

Given a string S of length N, the task is to print the highest roman number possible by rearranging the characters of the given string, if the given string is a valid roman number. If found to be not possible, then print “Invalid”.

Examples:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: S = “MCMIV”
Output: MMCVI
Explanation: The given string S is valid Roman numeral. Rearranging characters to obtain the string “MMCVI” generates the highest roman numeral possible using given set of characters.

Input: S = “XCYVM”
Output: Invalid

Approach: The idea is to use the sorting by the second element. Follow the steps below to solve the problem:

Below is the implementation of the above approach:

C++

 `// C++ implementation of the above approach``#include ``using` `namespace` `std;` `// Function to find decimal``// value of a roman character``int` `charVal(``char` `c)``{``    ``if` `(c == ``'I'``)``        ``return` `1;``    ``if` `(c == ``'V'``)``        ``return` `5;``    ``if` `(c == ``'X'``)``        ``return` `10;``    ``if` `(c == ``'L'``)``        ``return` `50;``    ``if` `(c == ``'C'``)``        ``return` `100;``    ``if` `(c == ``'D'``)``        ``return` `500;``    ``if` `(c == ``'M'``)``        ``return` `1000;` `    ``return` `-1;``}` `// Function to convert string representing``// roman number to equivalent decimal value``int` `romanToDec(string S)``{``    ``// Stores the decimal value``    ``// of the string S``    ``int` `res = 0;` `    ``// Stores the size of the S``    ``int` `n = S.size();` `    ``// Update res``    ``res = charVal(S[n - 1]);` `    ``// Traverse the string``    ``for` `(``int` `i = n - 2; i >= 0; i--) {` `        ``if` `(charVal(S[i]) < charVal(S[i + 1]))``            ``res -= charVal(S[i]);``        ``else``            ``res += charVal(S[i]);``    ``}` `    ``// Return res``    ``return` `res;``}` `// Function to convert decimal``// to equivalent roman numeral``string DecToRoman(``int` `number)``{``    ``// Stores the string``    ``string res = ``""``;` `    ``// Stores all the digit values of a roman digit``    ``int` `num[] = { 1, 4, 5, 9, 10, 40, 50,``                  ``90, 100, 400, 500, 900, 1000 };` `    ``string sym[]``        ``= { ``"I"``, ``"IV"``, ``"V"``, ``"IX"``, ``"X"``, ``"XL"``, ``"L"``,``            ``"XC"``, ``"C"``, ``"CD"``, ``"D"``, ``"CM"``, ``"M"` `};` `    ``int` `i = 12;` `    ``// Iterate while number``    ``// is greater than 0``    ``while` `(number > 0) {` `        ``int` `div` `= number / num[i];``        ``number = number % num[i];``        ``while` `(``div``--) {``            ``res += sym[i];``        ``}``        ``i--;``    ``}` `    ``// Return res``    ``return` `res;``}` `// Function to sort the string``// in descending order of values``// assigned to characters``bool` `compare(``char` `x, ``char` `y)``{``    ``// Return character with``    ``// highest decimal value``    ``int` `val_x = charVal(x);``    ``int` `val_y = charVal(y);` `    ``return` `(val_x > val_y);``}` `// Function to find largest roman``// value possible by rearranging``// the characters of the string``string findLargest(string S)``{``    ``// Stores all roman characters``    ``set<``char``> st = { ``'I'``, ``'V'``, ``'X'``, ``'L'``, ``'C'``, ``'D'``, ``'M'` `};` `    ``// Traverse the string``    ``for` `(``auto` `x : S) {` `        ``// If X is not found``        ``if` `(st.find(x) == st.end())``            ``return` `"Invalid"``;``    ``}``    ``sort(S.begin(), S.end(), compare);` `    ``// Stores the decimal value``    ``// of the roman number``    ``int` `N = romanToDec(S);` `    ``// Find the roman value equivalent``    ``// to the decimal value of N``    ``string R = DecToRoman(N);` `    ``if` `(S != R)``        ``return` `"Invalid"``;` `    ``// Return result``    ``return` `S;``}` `// Driver Code``int` `main()``{``    ``string S = ``"MCMIV"``;``    ``cout << findLargest(S);``}`

Java

 `// Java program for the above approach``import` `java.io.*;``import` `java.lang.*;``import` `java.util.*;` `class` `GFG{` `// Function to find decimal``// value of a roman character``static` `int` `charVal(``char` `c)``{``    ``if` `(c == ``'I'``)``        ``return` `1``;``    ``if` `(c == ``'V'``)``        ``return` `5``;``    ``if` `(c == ``'X'``)``        ``return` `10``;``    ``if` `(c == ``'L'``)``        ``return` `50``;``    ``if` `(c == ``'C'``)``        ``return` `100``;``    ``if` `(c == ``'D'``)``        ``return` `500``;``    ``if` `(c == ``'M'``)``        ``return` `1000``;` `    ``return` `-``1``;``}` `// Function to convert string representing``// roman number to equivalent decimal value``static` `int` `romanToDec(String S)``{``    ` `    ``// Stores the decimal value``    ``// of the string S``    ``int` `res = ``0``;` `    ``// Stores the size of the S``    ``int` `n = S.length();` `    ``// Update res``    ``res = charVal(S.charAt(n - ``1``));` `    ``// Traverse the string``    ``for``(``int` `i = n - ``2``; i >= ``0``; i--)``    ``{``        ``if` `(charVal(S.charAt(i)) <``            ``charVal(S.charAt(i + ``1``)))``            ``res -= charVal(S.charAt(i));``        ``else``            ``res += charVal(S.charAt(i));``    ``}` `    ``// Return res``    ``return` `res;``}` `// Function to convert decimal``// to equivalent roman numeral``static` `String DecToRoman(``int` `number)``{``    ` `    ``// Stores the string``    ``String res = ``""``;` `    ``// Stores all the digit values of a roman digit``    ``int` `num[] = { ``1``,  ``4``,   ``5``,   ``9``,   ``10``,  ``40``,  ``50``,``                  ``90``, ``100``, ``400``, ``500``, ``900``, ``1000` `};` `    ``String sym[] = { ``"I"``,  ``"IV"``, ``"V"``,  ``"IX"``,``                     ``"X"``,  ``"XL"``, ``"L"``, ``"XC"``,``                     ``"C"``,  ``"CD"``, ``"D"``,  ``"CM"``, ``"M"` `};` `    ``int` `i = ``12``;` `    ``// Iterate while number``    ``// is greater than 0``    ``while` `(number > ``0``)``    ``{``        ``int` `div = number / num[i];``        ``number = number % num[i];``        ` `        ``while` `(div-- > ``0``)``        ``{``            ``res += sym[i];``        ``}``        ``i--;``    ``}` `    ``// Return res``    ``return` `res;``}` `// Function to find largest roman``// value possible by rearranging``// the characters of the string``static` `String findLargest(String S)``{``    ``char` `arr[] = { ``'I'``, ``'V'``, ``'X'``, ``'L'``, ``'C'``, ``'D'``, ``'M'` `};` `    ``// Stores all roman characters``    ``Set st = ``new` `HashSet<>();``    ``for``(``char` `x : arr)``        ``st.add(x);` `    ``Character s[] = ``new` `Character[S.length()];``    ``for``(``int` `i = ``0``; i < S.length(); i++)``        ``s[i] = S.charAt(i);` `    ``// Traverse the string``    ``for``(``char` `x : s)``    ``{``        ` `        ``// If X is not found``        ``if` `(!st.contains(x))``            ``return` `"Invalid"``;``    ``}` `    ``Arrays.sort(s, ``new` `Comparator()``    ``{``        ``@Override``        ``public` `int` `compare(Character x, Character y)``        ``{``            ``return` `charVal(y) - charVal(x);``        ``}``    ``});` `    ``String ss = ``""``;``    ``for``(``char` `ch : s)``        ``ss += ch;` `    ``// Stores the decimal value``    ``// of the roman number``    ``int` `N = romanToDec(ss);` `    ``// Find the roman value equivalent``    ``// to the decimal value of N``    ``String R = DecToRoman(N);` `    ``if` `(!ss.equals(R))``        ``return` `"Invalid"``;` `    ``// Return result``    ``return` `ss;``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``    ` `    ``// Input``    ``String S = ``"MCMIV"``;``    ``int` `N = S.length();` `    ``System.out.println(findLargest(S));``}``}` `// This code is contributed by Kingash`
Output:
`MMCVI`

Time Complexity: O(N*log(N))
Auxiliary Space: O(1)

My Personal Notes arrow_drop_up