Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

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 <bits/stdc++.h>
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[] = { 14,   5,   9,   104050,
                  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<Character> 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<Character>()
    {
        @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
Recommended Articles
Page :

Start Your Coding Journey Now!