Largest Roman Numeral Possible by Rearranging Characters of a Given String


The characters represent Roman numbers: 'I', 'V', 'X', 'L', 'C', 'D', and 'M'. We will be given a string that may contain another character also (all the characters will be uppercase English alphabets) and we have to find the largest Roman numerical number possible by altering the position of the characters of the given string, also if it is not possible to get one, then we will return invalid as the answer.

Input 1

string str = “VICML”

Output

MCLVI

Explanation

In the given string we have M have the greater value followed by the C, and then all the characters have the values in descending order, so we just printed it in sorted descending order.

Input

"MLCIU"

Output

Invalid 

Explanation

In the given string we have the character 'U' which is not present in the Roman numbers. So, we will return an invalid string.

Approach

We have seen the examples above, now let us move to the implementation part:

For the implementation of the required code, we are going to create many functions, that will help us to find the particular set of things/values that we require:

  • First, the function is to find the value of the Roman character and to find if the current character is a valid Roman character or not. This function takes a single character as the input and will return the value of the character if it is valid otherwise -1.

  • The next function is to convert the Roman number string to a decimal number. This function will take a single string as the parameter and will return an integer as the return value.

  • We will have a similar function to the previous one but just the opposite, that is decimal to Roman, this function will take a decimal or integer value as the parameter and will return the string that represents the Roman value.

  • We will use the sort function to sort the string and we will update the sort function by using the compare function to sort the characters in the decreasing value of characters.

  • A helper function is needed to traverse over the string to find whether the string is valid or not and then sort the current string. After that will check the decimal representation of the current string value by using the functions.

Example

#include <bits/stdc++.h>
using namespace std;
// function to create the value of Roman characters if the character is not present in Roman then return -1
int romanVal(char ch){
   if (ch == 'I'){
      return 1;
   }
   else if (ch == 'X'){
      return 10;
   }
   else if (ch == 'V'){
      return 5;
   }
   else if (ch == 'D'){
      return 500;
   }
   else if(ch == 'C'){
      return 100;
   }
   else if(ch == 'L'){
      return 50;
   }
   else if(ch == 'M'){
      return 1000;
   }
   else{
      // given number is invalid 
      return -1;
   }
}
// function to get the decimal value from the given Roman value 
int romanToDec(string str){
   int ans = 0; // variable to store the final answer 
   int len = str.size(); // length of the final string 	
   ans = romanVal(str[len - 1]); // initializing the value of result variable
   // Traversing over the given string
   for (int i = len - 2; i>= 0; i--){
      if (romanVal(str[i]) <romanVal(str[i + 1])){
      ans -= romanVal(str[i]);
      }
      else{
      ans += romanVal(str[i]);
      }
   }
   return ans; // return the final answer 
}
// function for converting the decimal value to roman 
string decToRoman(int num){
   string ans = ""; // variable to store the final answer 
   // array to store all the numeric values that can be represented in the roman 
   int decVals[] = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
   // array to store all the roman values that equivalent to the given decimal values  
   string romVals[] = { "I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD" , "D", "CM", "M" };
   int idx = 12; // starting from the last index 
   while (num> 0){
      int cur = num / decVals[idx];
      num = num % decVals[idx];
      while (cur--) {
         ans += romVals[idx];
      }
      idx--;
   }
   return ans; // return the final answer 
}
// compare function to sort the string in the decreasing order
bool cmp(char a, char b){
   // getting values of both the current characters 
   int val_a = romanVal(a);
   int val_b = romanVal(b);
   return (val_a>val_b);
}
// creating function to find the largest possible result
string findString(string str){	
   // traversing over the string to check if any invalid character is present or not 
   for(int i=0; i<str.length(); i++){
      if(romanVal(str[i]) == -1){
         // if romalValue is -1 means chracter is invalid 
         return "Invalid";
      }
   }
   sort(str.begin(), str.end(), cmp);
   int num = romanToDec(str);
   string rom = decToRoman(num);
   if (str != rom){
      return "Invalid";
   }
   return rom; // returning the result 
}
int main(){
   string str = "VICML"; // given string 
   cout << "Given String: " << str << endl;	
   cout << "Largest Roman Numeral possible by rearranging characters of a given string: ";
   // calling to the function 
   cout<<findString(str)<<endl;
   return 0;
} 

Output

Given String: VICML
Largest Roman Numeral possible by rearranging characters of a given string: MCLVI

Time and Space Complexity

The time complexity of the above code is O(N*log(N)), where N is the size of the given string

The space complexity of the above code is O(N), because we are using another string to store the result. 

Conclusion

In this tutorial, we have implemented a program to find the string which represents the greatest possible Roman number by updating the position of the characters. If the given string is not valid then we can return invalid as the answer. We have implemented a code that works with the O(N*log(N)) time complexity and O(N) space complexity.

Updated on: 11-Jul-2023

54 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements