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:
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:
- Iterate over the characters of the string.
- Check if the string contains any character other than { ‘I’, ‘V’, ‘X’, ‘L’, ‘C’, ‘D’, ‘M’ } or not. If found to be true, then print “Invalid”.
- Otherwise, sort the string in descending order with respect to the decimal value of the characters of the string.
- Now convert the roman value to equivalent decimal and store it in a variable, say X.
- Now find the equivalent roman value of the decimal number X and store it in a variable, say Y.
- Now print the string S if S is found to be equal to Y. Otherwise print “Invalid”.
Below is the implementation of the above approach:
// 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 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<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 |
# Python program for the above approach # Function to find decimal # value of a roman character from functools import cmp_to_key
def mycmp(a, b):
return - charVal(a) + charVal(b)
def charVal(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 def romanToDec(S):
# Stores the decimal value
# of the string S
res = 0
# Stores the size of the S
n = len (S)
# Update res
res = charVal(S[n - 1 ])
# Traverse the string
for i in range (n - 2 , - 1 , - 1 ):
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 def DecToRoman(number):
# Stores the string
res = ""
# Stores all the digit values of a roman digit
num = [ 1 , 4 , 5 , 9 , 10 , 40 , 50 ,
90 , 100 , 400 , 500 , 900 , 1000 ]
sym = [ "I" , "IV" , "V" , "IX" ,
"X" , "XL" , "L" , "XC" ,
"C" , "CD" , "D" , "CM" , "M" ]
i = 12
# Iterate while number
# is greater than 0
while (number > 0 ):
div = number / / num[i]
number = number % num[i]
while (div > 0 ):
res + = sym[i]
div - = 1
i - = 1
# Return res
return res
# Function to find largest roman # value possible by rearranging # the characters of the string def findLargest(S):
arr = [ 'I' , 'V' , 'X' , 'L' , 'C' , 'D' , 'M' ]
# Stores all roman characters
st = set ()
for x in arr:
st.add(x)
s = [ 0 for i in range ( len (S))]
for i in range ( len (S)):
s[i] = S[i]
# Traverse the string
for x in s:
# If X is not found
if (x not in st):
return "Invalid"
s.sort(key = cmp_to_key(mycmp))
ss = ""
for ch in s:
ss + = ch
# Stores the decimal value
# of the roman number
N = romanToDec(ss)
# Find the roman value equivalent
# to the decimal value of N
R = DecToRoman(N)
if (ss ! = R):
return "Invalid"
# Return result
return ss
# Driver Code # Input S = "MCMIV"
N = len (S)
print (findLargest(S))
# This code is contributed by Shinjanapatra |
using System;
using System.Collections.Generic;
class Program {
// 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[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;
}
// 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" };
// Iterate while number
// is greater than 0
int i = 12;
while (number > 0) {
int div = number / num[i];
number = number % num[i];
while (div-- > 0) {
res += sym[i];
}
i--;
}
return res;
}
// Function to find largest roman
// value possible by rearranging
// the characters of the string
static string FindLargest( string S)
{
// Stores all roman characters
char [] arr = { 'I' , 'V' , 'X' , 'L' , 'C' , 'D' , 'M' };
// Traverse the string
HashSet< char > st = new HashSet< char >();
foreach ( char x in arr) st.Add(x);
char [] s = new char [S.Length];
for ( int i = 0; i < S.Length; i++)
s[i] = S[i];
foreach ( char x in s)
{
if (!st.Contains(x))
return "Invalid" ;
}
Array.Sort(s, delegate ( char x, char y) {
return CharVal(y) - CharVal(x);
});
string ss = "" ;
foreach ( char ch in 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 ss;
}
// Driver code
static void Main( string [] args)
{
string S = "MCMIV" ;
Console.WriteLine(FindLargest(S));
}
} // This code is contributed by phasing17. |
<script> // Javascript program for the above approach // Function to find decimal // value of a roman character function charVal(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 function romanToDec(S) {
// Stores the decimal value
// of the string S
let res = 0;
// Stores the size of the S
let n = S.length;
// Update res
res = charVal(S[n - 1]);
// Traverse the string
for (let 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 function DecToRoman(number) {
// Stores the string
let res = "" ;
// Stores all the digit values of a roman digit
let num = [1, 4, 5, 9, 10, 40, 50,
90, 100, 400, 500, 900, 1000];
let sym = [ "I" , "IV" , "V" , "IX" ,
"X" , "XL" , "L" , "XC" ,
"C" , "CD" , "D" , "CM" , "M" ];
let i = 12;
// Iterate while number
// is greater than 0
while (number > 0) {
let div = Math.floor(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 function findLargest(S) {
let arr = [ 'I' , 'V' , 'X' , 'L' , 'C' , 'D' , 'M' ];
// Stores all roman characters
let st = new Set();
for (let x of arr)
st.add(x);
let s = new Array(S.length);
for (let i = 0; i < S.length; i++)
s[i] = S[i];
// Traverse the string
for (let x of s) {
// If X is not found
if (!st.has(x))
return "Invalid" ;
}
s.sort((a, b) => -charVal(a) + charVal(b))
let ss = "" ;
for (let ch of s)
ss += ch;
// Stores the decimal value
// of the roman number
let N = romanToDec(ss);
// Find the roman value equivalent
// to the decimal value of N
let R = DecToRoman(N);
if (ss != R)
return "Invalid" ;
// Return result
return ss;
} // Driver Code // Input let S = "MCMIV" ;
let N = S.length; document.write(findLargest(S)); // This code is contributed by Saurabh Jaiswal </script> |
MMCVI
Time Complexity: O(N*log(N))
Auxiliary Space: O(1)