Roman Numeral C++ Programming Conversion Issue - c++

I am currently developing some code that is used to convert an inputted integer to ROMAN numerals. It is working how it should be except for the cases where I am using the character I, it isn't adding them up correctly. I have done the same syntax as the other characters which work so I am baffled as to why it doesn't work for the "I" character. Here is a snippet of what I have:
else if(roman_Numeral == 'V')
{
roman_Numeral = cin.peek();
if(numerals.find(roman_Numeral, 2) != std::string::npos)
{
arabic_Numeral = arabic_Numeral - 5;
continue;
}
else
{
arabic_Numeral = arabic_Numeral + 5;
continue;
}
}
else if(roman_Numeral == 'I')
{
roman_Numeral = cin.peek();
if(numerals.find(roman_Numeral), 2 != std::string::npos)
{
arabic_Numeral = arabic_Numeral -1;
break;
}
else
{
arabic_Numeral += 1 ;
continue;
}
}
else
break;
}
cout << arabic_Numeral << endl;
return 0;
The other characters, such as M, C, D etc are similar in layout, however with I obviously the desired output for something such as VI is 6 and it outputs 4. Any help would be appreciated.
The complete code is:
#include <string>
#include <iostream>
using namespace std;
std::string numerals = "IVXLCDM";
int main()
{
char roman_Numeral;
int arabic_Numeral = 0;
cout << "Enter the Roman Numeral in Capital letters (e.g. CCXIX) : ";
while(cin.get(roman_Numeral))
{
if(roman_Numeral == 'M')
arabic_Numeral = arabic_Numeral + 1000;
else if(roman_Numeral == 'D')
{
roman_Numeral = cin.peek();
if(numerals.find(roman_Numeral, 5) != std::string::npos)
{
arabic_Numeral = arabic_Numeral - 500;
continue;
}
else
{
arabic_Numeral = arabic_Numeral + 500;
continue;
}
}
else if(roman_Numeral == 'C')
{
roman_Numeral = cin.peek();
if(numerals.find(roman_Numeral, 4) != std::string::npos)
{
arabic_Numeral = arabic_Numeral - 100;
continue;
}
else
{
arabic_Numeral = arabic_Numeral + 100;
continue;
}
}
else if(roman_Numeral == 'L')
{
roman_Numeral = cin.peek();
if(numerals.find(roman_Numeral, 3) != std::string::npos)
{
arabic_Numeral = arabic_Numeral - 50;
continue;
}
else
{
arabic_Numeral = arabic_Numeral + 50;
continue;
}
}
else if(roman_Numeral == 'X')
{
roman_Numeral = cin.peek();
if(numerals.find(roman_Numeral, 2) != std::string::npos)
{
arabic_Numeral = arabic_Numeral - 10;
continue;
}
else
{
arabic_Numeral = arabic_Numeral + 10;
continue;
}
}
else if(roman_Numeral == 'V')
{
roman_Numeral = cin.peek();
if(numerals.find(roman_Numeral, 2) != std::string::npos)
{
arabic_Numeral = arabic_Numeral - 5;
continue;
}
else
{
arabic_Numeral = arabic_Numeral + 5;
continue;
}
}
else if(roman_Numeral == 'I')
{
roman_Numeral = cin.peek();
if(numerals.find(roman_Numeral), 2 != std::string::npos)
{
arabic_Numeral = arabic_Numeral -1;
break;
}
else
{
arabic_Numeral += 1 ;
continue;
}
}
else
break;
}
cout << arabic_Numeral << endl;
return 0;
}
I initially found the code online and will be making additional changes later on. Currently the most of the test combinations of my code works. It's just implementing the I's so I can get test for singular cases of I such as III = 3, etc. III currently outputs -1 which is obviosuly not correct. I believe the issue is soemthing to do with the way it adds them together but not entirely sure. I am fairly new to coding after all.
Kind regards.

Your observation is correct. The code indeed has a bug for the 'I' section. Just read the code carefully and try to compare it with other working sections. Hint: missing parenthesis ;)

Related

GetLine Function For C-String Not Working Properly

I'm working on a project for my computer science class, and for whatever reason, once my code gets to my cin.getline code it just ends and doesn't allow me to enter anything in and I don't know why. I think the problem has something to do with the "null" character at the end of a c-string, but I'm not quite sure as it was working fine until I added the "Determining Whether to CODE or DECODE section" and the if statement. This code isn't fully complete yet, I just need to fix whatever is causing this to move on though.
So essentially, it works without the whole section above it and the if statement. But once I add those, my cin.getline function doesn't work. However, if I do a cin >> line, it will work even with the code above it. I need the getline function because I will be writing it to a file, and I also need to grab those sexy spaces ' '.
#include <iostream>
#include <cstring>
#include <string>
#include <ctime>
#include <fstream>
using namespace std;
//Function Prototypes:
string fileAddress(string);
void swap(char &, char &);
string code(int, char [], char [], char []);
//Main Function:
int main()
{
//Alphabet Section:
//------------------------------------------------------------------------------------------------------------------
//Declaring Variables Relating to Alphabet:
int size = 29;
char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ., ";
char sAlphabet[size];
int x;
int y;
//Copying Alphabet & Outputting Test Value:
strcpy(sAlphabet, alphabet);
//Scrambling Alphabet
unsigned seed = time(0);
srand(seed);
for(int i = 0; i < 10000; i++)
{
//Initializing Random Numbers to Swap:
x = rand()%29;
y = rand()%29;
//Swapping Values
swap(sAlphabet[x], sAlphabet[y]);
}
//Testing Scrambled Alphabet:
cout << sAlphabet << endl << endl;
//------------------------------------------------------------------------------------------------------------------
//Determining Whether to CODE or DECODE Section:
//------------------------------------------------------------------------------------------------------------------
//Response Variables:
string response;
//Gathering Choice From User:
cout << "If you wish to code a message, please type CODE." << endl;
cout << "If you wish to decode a message, please type DECODE.";
cin >> response;
//------------------------------------------------------------------------------------------------------------------
//Writing Coded Message to File Section:
//------------------------------------------------------------------------------------------------------------------
if(response == "CODE")
{
//Code Variables:
int length = 100;
char line[length];
char cline[length];
string codedLine;
//Gathering Line from User:
cout << "Please enter a message in all CAPS that you wish to code.";
cin.getline(line, length);
//Copying Line:
strcpy(cline, line);
//Gathering length of Line:
length = strlen(line);
codedLine = code(length, line, cline, sAlphabet);
cout << line << endl;
cout << codedLine<< endl;
}
else
cout << "You suck";
return 0;
}
//Creating Swap Function:
void swap(char &value1, char &value2)
{
char temp;
temp = value1;
value1 = value2;
value2 = temp;
}
string code(int length, char line[], char cline[], char sAlphabet[])
{
for(int i = 0; i < length; i++)
{
//Letter A:
if(line[i] == 'A')
{
cline[i] = sAlphabet[0];
}
//Letter B:
else if(line[i] == 'B')
{
cline[i] = sAlphabet[1];
}
//Letter C:
else if(line[i] == 'C')
{
cline[i] = sAlphabet[2];
}
//Letter D:
else if(line[i] == 'D')
{
cline[i] = sAlphabet[3];
}
//Letter E:
else if(line[i] == 'E')
{
cline[i] = sAlphabet[4];
}
//Letter F:
else if(line[i] == 'F')
{
cline[i] = sAlphabet[5];
}
//Letter G:
else if(line[i] == 'G')
{
cline[i] = sAlphabet[6];
}
//Letter H:
else if(line[i] == 'H')
{
cline[i] = sAlphabet[7];
}
//Letter I:
else if(line[i] == 'I')
{
cline[i] = sAlphabet[8];
}
//Letter J:
else if(line[i] == 'J')
{
cline[i] = sAlphabet[9];
}
//Letter K:
else if(line[i] == 'K')
{
cline[i] = sAlphabet[10];
}
//Letter L:
else if(line[i] == 'L')
{
cline[i] = sAlphabet[11];
}
//Letter M:
else if(line[i] == 'M')
{
cline[i] = sAlphabet[12];
}
//Letter N:
else if(line[i] == 'N')
{
cline[i] = sAlphabet[13];
}
//Letter O:
else if(line[i] == 'O')
{
cline[i] = sAlphabet[14];
}
//Letter P:
else if(line[i] == 'P')
{
cline[i] = sAlphabet[15];
}
//Letter Q:
else if(line[i] == 'Q')
{
cline[i] = sAlphabet[16];
}
//Letter R:
else if(line[i] == 'R')
{
cline[i] = sAlphabet[17];
}
//Letter S:
else if(line[i] == 'S')
{
cline[i] = sAlphabet[18];
}
//Letter T
else if(line[i] == 'T')
{
cline[i] = sAlphabet[19];
}
//Letter U:
else if(line[i] == 'U')
{
cline[i] = sAlphabet[20];
}
//Letter V:
else if(line[i] == 'V')
{
cline[i] = sAlphabet[21];
}
//Letter W:
else if(line[i] == 'W')
{
cline[i] = sAlphabet[22];
}
//Letter X:
else if(line[i] == 'X')
{
cline[i] = sAlphabet[23];
}
//Letter Y:
else if(line[i] == 'Y')
{
cline[i] = sAlphabet[24];
}
//Letter Z:
else if(line[i] == 'Z')
{
cline[i] = sAlphabet[25];
}
//Character Period:
else if(line[i] == '.')
{
cline[i] = sAlphabet[26];
}
//Character Comma:
else if(line[i] == ',')
{
cline[i] = sAlphabet[27];
}
//Character Space:
else if(line[i] == ' ')
{
cline[i] = sAlphabet[28];
}
else
cout << "Error" << endl;
}
return cline;
}
The output should be allowing myself to write in the line of code and see it back scrambled, which the scrambler works.
I fixed it using the ignore function for the \n character found in the thread that R Sahu posted.
I basically just added:
cin.ignore(std::numeric_limits::max(), '\n')
before my cin.getline.

Stuck in while loop when change to c++

i'm trying to rewrite this code in c++ which create a bitcoin mini private key
using System;
using System.Text;
using Org.BouncyCastle.Security;
public string CreateRandomMinikey(){
string keytotry = "S6c56bnXQiBjk9mqSYE7ykVQ7NzrQA";
char[] chars = keytotry.ToCharArray();
char[] charstest = (keytotry + "?").ToCharArray();
while (Util.ComputeSha256(utf8.GetBytes(charstest))[0] != 0) {// hash sha256 the key & check if the first character was '0'
// As long as key doesn't pass typo check, increment it.
for (int i = chars.Length - 1; i >= 0; i--) {
char c = chars[i];
if (c == '9') {
charstest[i] = chars[i] = 'A';
break;
} else if (c == 'H') {
charstest[i] = chars[i] = 'J';
break;
} else if (c == 'N') {
charstest[i] = chars[i] = 'P';
break;
} else if (c == 'Z') {
charstest[i] = chars[i] = 'a';
break;
} else if (c == 'k') {
charstest[i] = chars[i] = 'm';
break;
} else if (c == 'z') {
charstest[i] = chars[i] = '2';
// No break - let loop increment prior character.
} else {
charstest[i] = chars[i] = ++c;
break;
}
}
}
string result = new string(chars);//expect S6c56bnXQiBjk9mqSYE7ykVQ7NzrRy
return result;
}
Here my code when i transform into c++
#include "stdafx.h"
#include <string.h>
#include <iostream>
#include <cstring>
#include "sha256.h"
using namespace std;
int main()
{
string input = "S6c56bnXQiBjk9mqSYE7ykVQ7NzrQA";
string inputcharstest = input+"?";
char * chars = new char[input.size() + 1];
strcpy(chars, input.c_str());//convert input to char array
char * charstest = new char[inputcharstest.size() + 1];
strcpy(charstest, inputcharstest.c_str());// convert inputcharstest to char array
string output = sha256(inputcharstest); //hash sha256 inputcharstest to check typo
while (output[0] != '0') {
for (int i = strlen(chars) - 1; i >= 0; i--) {
char c = chars[i];
if (c == '9') {
charstest[i] = chars[i] = 'A';
break;
}
else if (c == 'H') {
charstest[i] = chars[i] = 'J';
break;
}
else if (c == 'N') {
charstest[i] = chars[i] = 'P';
break;
}
else if (c == 'Z') {
charstest[i] = chars[i] = 'a';
break;
}
else if (c == 'k') {
charstest[i] = chars[i] = 'm';
break;
}
else if (c == 'z') {
charstest[i] = chars[i] = '2';
}
else {
charstest[i] = chars[i] = ++c;
break;
}
}
}
string result = string(chars); //expect S6c56bnXQiBjk9mqSYE7ykVQ7NzrRy
cout << "input('" << input << "'):" << result << endl;
return 0;
}
This is the result i expected
The code was stuck & return blank when i run it on console application, i debug & find out it was stuck in while loop forever. May i ask if there're any problem with this & how do i fix it?
Here you are changing the content of the string every time:
char[] charstest = (keytotry + "?").ToCharArray();
while (Util.ComputeSha256(utf8.GetBytes(charstest))[0] != 0) {
charstest changes in every run through the loop, so the test in the while can terminate at some point. In the C++ code, however, you're not doing that:
string output = sha256(inputcharstest); //hash sha256 inputcharstest to check typo
while (output[0] != '0') {
Here, you're only doing the hash once before the loop, and then not again in the loop. The loop doesn't change output at all and neither does it break out of the while, so if output[0] != '0' is true the first time, it will always be true, thus the infinite loop.

C++ Arabic numbers to Roman Numeral's & vice versa

I am writing a C++ program that converts between Arabic and Roman numbering systems. I wrote one program that converts Arabic to Roman and have another program that converts Roman to Arabic.
The problem is that I can't figure out how to merge them into one single program so that the user can input an Arabic or Roman number and as a result, the program would convert said number to the other.
My question is HOW can I merge these two programs into one?
Code for Roman to Arabic
#include <iostream>
using namespace std;
int main()
{
char roman_Numeral;
int arabic_Numeral = 0;
cout << "Enter the Roman Numeral in Capital letters (e.g. CCXIX) : ";
while (cin.get(roman_Numeral))
{
if (arabic_Numeral > 100)
{
cout << "\nInvalid Value. Number must be between I and C" << endl;
return 0;
}
else if (roman_Numeral == 'C')
{
roman_Numeral = cin.peek();
if (roman_Numeral == 'M' || roman_Numeral == 'D')
{
arabic_Numeral = arabic_Numeral - 100;
}
else
{
arabic_Numeral = arabic_Numeral + 100;
}
}
else if (roman_Numeral == 'L')
{
roman_Numeral = cin.peek();
if (roman_Numeral == 'M' || roman_Numeral == 'D'
|| roman_Numeral == 'C')
{
arabic_Numeral = arabic_Numeral - 50;
continue;
}
else
{
arabic_Numeral = arabic_Numeral + 50;
continue;
}
}
else if (roman_Numeral == 'X')
{
roman_Numeral = cin.peek();
if (roman_Numeral == 'M' || roman_Numeral == 'D'
|| roman_Numeral == 'C' || roman_Numeral == 'L')
{
arabic_Numeral = arabic_Numeral - 10;
continue;
}
else
{
arabic_Numeral = arabic_Numeral + 10;
continue;
}
}
else if (roman_Numeral == 'V')
{
roman_Numeral = cin.peek();
if (roman_Numeral == 'M' || roman_Numeral == 'D'
|| roman_Numeral == 'C' || roman_Numeral == 'L'
|| roman_Numeral == 'X')
{
arabic_Numeral = arabic_Numeral - 5;
continue;
}
else
{
arabic_Numeral = arabic_Numeral + 5;
continue;
}
}
else if (roman_Numeral == 'I')
{
roman_Numeral = cin.peek();
if (roman_Numeral == 'M' || roman_Numeral == 'D'
|| roman_Numeral == 'C' || roman_Numeral == 'L'
|| roman_Numeral == 'X' || roman_Numeral == 'V')
{
arabic_Numeral = arabic_Numeral - 1;
continue;
}
else
{
arabic_Numeral = arabic_Numeral + 1;
continue;
}
}
else
break;
}
cout << arabic_Numeral << endl;
return 0;
}
Code for Arabic to Roman
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
#define MAX_INPUT 100 // These constants hold high and low integer numbers,
#define MIN_INPUT 1
#define ARRAY_SIZE 4 // and the array size declarator.
string convert(int digit, string low, string mid, string high);
int main()
{
string answers[ARRAY_SIZE] = { "", "", "", "" }; //An array of string to hold the output from the convert function.
int accumulator = 0; // Variable to hold number of arabic numbers converted.
int userNum = 0;
string strUserNum;
do
{
cout << "";
cout << "Enter an arabic number between 1 and 100: ";
cin >> strUserNum;
userNum = std::stoi(strUserNum);
if (userNum == 0 || userNum > MAX_INPUT)
{
cout << "\nInvalid Value. Number must be between 1 and 100" << endl;
return 0;
}
else if (userNum == 'end')
{
cout << "Exiting program:";
break;
}
int thous = userNum / 1000;
int hund = userNum % 1000 / 100;
int tens = userNum % 100 / 10;
int ones = userNum % 10 / 1;
answers[0] = convert(thous, "M", "M", "M");
answers[1] = convert(hund, "C", "D", "M");
answers[2] = convert(tens, "X", "L", "C");
answers[3] = convert(ones, "I", "V", "X");
cout << answers[0] << answers[1] << answers[2];
cout << answers[3] << endl;
cout << endl;
break;
} while (userNum != 'end');
system("PAUSE");
return 0;
}
string convert(int digit, string low, string mid, string high)
{
if (digit == 1)
{
return low;
}
if (digit == 2)
{
return low + low;
}
if (digit == 3)
{
return low + low + low;
}
if (digit == 4)
{
return low + mid;
}
if (digit == 5)
{
return mid;
}
if (digit == 6)
{
return mid + low;
}
if (digit == 7)
{
return mid + low + low;
}
if (digit == 8)
{
return mid + low + low + low;
}
if (digit == 9)
{
return low + high;
}
if (digit == 0)
{
return "";
}
}
Put code (that inside the main block) for Roman to Arabic into void procedureRomanToArabic()
The same for Roman to Arabic. Put it into void procedureArabicToRoman().
Remove remove ArabicToRoman do-while and move it to main.
void procedureRomanToArabic(){
char roman_Numeral;
int arabic_Numeral = 0;
//...
cout << arabic_Numeral << endl;
}
void procedureArabicToRoman()
{
string answers[ARRAY_SIZE] = { "", "", "", "" }; //An array of string to hold the output from the convert function.
int accumulator = 0; // Variable to hold number of arabic numbers converted.
int userNum = 0;
string strUserNum;
//remove do while here
cout << "";
cout << "Enter an arabic number between 1 and 100: ";
cin >> strUserNum;
//...
answers[2] = convert(tens, "X", "L", "C");
answers[3] = convert(ones, "I", "V", "X");
cout << answers[0] << answers[1] << answers[2];
cout << answers[3] << endl;
cout << endl;
}
int main(){
char type;
do{
cout<<"2 for Arabic to Roman, 1 for Roman to Arabic, or anything else for exit";
cin>>type;
if(type=='1')
procedureArabicToRoman();
else if(type =='2')
procedureRomanToArabic();
else break; //end program
} while(true);
}

Having issues converting numbers into roman numerals

for class I have to create a code so that it could ask the user for an integer between 1-99 and be able to print that integer in roman numerals. Issue is after creating my code it would only print the numbers fully up to 39. Once it hits 40 it give's no Roman Numeral output and then from 41-99 it wont print the tenth place value(Ex. 45 will come out as V). Here's my code at the moment.
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
int num;
int tenum;
int remnum;
string romnum;
string fromnum;
cout << "Enter a number between 1 and 99. \n";
cin >> num;
tenum = num / 10;
remnum = num % 10;
if (tenum == 9)
{
fromnum == "XC";
}
else if (tenum == 8)
{
fromnum == "LXXX";
}
else if (tenum == 7)
{
fromnum == "LXX";
}
else if (tenum == 6)
{
fromnum == "LX";
}
else if (tenum == 5)
{
fromnum == "L";
}
else if (tenum == 4)
{
fromnum == "XL";
}
else if (tenum == 3)
{
fromnum = "XXX";
}
else if (tenum == 2)
{
fromnum == "XX";
}
else if (tenum == 1)
{
fromnum == "X";
}
if (remnum == 9)
{
romnum = "IX";
}
else if (remnum == 8)
{
romnum = "VIII";
}
else if (remnum == 7)
{
romnum = "VII";
}
else if (remnum == 6)
{
romnum = "VI";
}
else if (remnum == 5)
{
romnum = "V";
}
else if (remnum == 4)
{
romnum = "IV";
}
else if (remnum == 3)
{
romnum = "III";
}
else if (remnum == 2)
{
romnum = "II";
}
else if (remnum == 1)
{
romnum = "I";
}
cout << tenum << endl;
cout << remnum << endl;
cout << fromnum;
cout << romnum << endl;
return 0;
}
You've mixed up == and =
change lines like
fromnum == "XL"
to
fromnum = "XL"
Demo
(I used a switch statement for brevity)
same answer with: Converting integer to Roman Numeral
#include <iostream>
#include <string>
std::string to_roman(int value)
{
struct romandata_t { int value; char const* numeral; };
static romandata_t const romandata[] =
{ 1000, "M",
900, "CM",
500, "D",
400, "CD",
100, "C",
90, "XC",
50, "L",
40, "XL",
10, "X",
9, "IX",
5, "V",
4, "IV",
1, "I",
0, NULL }; // end marker
std::string result;
for (romandata_t const* current = romandata; current->value > 0; ++current)
{
while (value >= current->value)
{
result += current->numeral;
value -= current->value;
}
}
return result;
}
int main()
{
for (int i = 1; i <= 4000; ++i)
{
std::cout << to_roman(i) << std::endl;
}
}
this code converts up to 1000. just take what you need and you are good to go!
from http://rosettacode.org/wiki/Roman_numerals/Encode#C.2B.2B

c++ Converting roman numerals to decimals

This program is a part of an exam I just took, that I had to write. I only got this far and couldn't get anywhere. Here is the prompt:"Write a Test Function toDecimal() that converts a roman numeral such as MMLXVII to it's decimal number representation. Use Main() to test the function. The toDecimal() function should have 2 arguments, the string array of roman numerals and a helper function. This helper function will return the numeric value of each of the letters used in roman numbers. Then convert the string arguments as so: Look at the first two characters,if the first is larger, convert the first and add it to the summation, then call the conversion function again with the second value and add both. IF the first character is lesser than the second subtract the first from the second, and add the result to the conversion of the string. without validation it will also convert strings like "IC". VAlidate the string arguement, if there is an error, call the error processing function. Provide at least two error processing functions and test toDecimal() with each. One could be adking the user to correct, the other may correct it."
I,X,C,M cannot be repeated more than 3 times in succession, D,L,V, can never be repeated in succession.I can only be subtracted from V and X,X can only be subtracted from L and C, C can only be subtracted from D and M. V, L, and D can never be subtracted.
I've lost about 2 days worth of sleep on this, tried writing it hundreds of different ways using and breaking the rules. This is the closest I've got on it.
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#include <cstring>
using namespace std;
bool checker(string roman);
// Adds each value of the roman numeral together
int toDecimal(string, bool* (*function)(string));
int convert(string roman, int i);
int main(){
string roman;
cout << "This program takes a roman numeral the user enters then converts it to decimal notation." << endl;
cout << "Enter a roman numeral: ";
cin >> roman;
transform(roman.begin(), roman.end(), roman.begin(), toupper);
cout << roman << " is equal to " << toDecimal(roman, *checker(roman)) << endl;
}
bool checker(string roman){
int length = roman.length();
for (int count = 0; count < length; count++){
string sub = roman.substr(count, count);
if(sub != "I" || sub != "V" || sub != "X" || sub != "L" || sub != "C" || sub != "D" || sub != "M"){
cout << "Error. Try Again"<< endl;
return false;
}
else if(convert(roman, count) == convert(roman, count-1) && convert(roman, count) == convert(roman, count+1)){
if (convert(roman,count) == 1 || convert(roman,count) == 10 || convert(roman,count) == 100 || convert(roman,count) == 1000)
if(convert(roman, count-1) == convert(roman, count-2) || convert(roman, count+1) == convert(roman, count+2)){
cout << "Error Try again" << endl;
return false;
}
else if (convert(roman,count) == 5 || convert(roman,count) == 50 || convert(roman,count) == 500){
cout << "Error Try again" << endl;
return false;
}
else return true;
}
}
return true;
}
int toDecimal(string s, bool*(checker) (string roman)){
/**map<char, int> roman;
roman['M'] = 1000;
roman['D'] = 500;
roman['C'] = 100;
roman['L'] = 50;
roman['X'] = 10;
roman['V'] = 5;
roman['I'] = 1;*/
checker(s);
int res = 0;
for (int i = 0; i < s.length() - 1; ++i){
int num = convert(s,i);
res += num;
/**if (roman[s[i]] < roman[s[i+1]])
res -= roman[s[i]];
else
res += roman[s[i]];
}
res += roman[s[s.size()-1]];*/}
return res;
}
int convert(string roman, int i){
enum romans {I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000};
int num = 0;
char c = roman[0];
switch(c){
case 'M':
num = M; break;
case 'D':
if(i + 1 != roman.size() && roman[i+1] == 'M'){
num = M - D;break;
}
else
num = D; break;
case 'C':
if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D'){
if(roman[i+1] == 'M') num = M - C; break;
if(roman[i+1] == 'D') num = D - C; break;
}
else
num = C; break;
case 'L':
if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'){
if(roman[i+1] == 'M') num = M - L; break;
if(roman[i+1] == 'D') num = D - L; break;
if(roman[i+1] == 'C') num = C - L; break;
}
else
num = L; break;
case 'X':
if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'|| roman[i+1] == 'L'){
if(roman[i+1] == 'M') num = M - X; break;
if(roman[i+1] == 'D') num = D - X; break;
if(roman[i+1] == 'C') num = C - X; break;
if(roman[i+1] == 'L') num = C - X; break;
}
num = X; break;
case 'V':
if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'|| roman[i+1] == 'L' || roman[i+1] == 'X'){
if(roman[i+1] == 'M') num = M - V; break;
if(roman[i+1] == 'D') num = D - V; break;
if(roman[i+1] == 'C') num = C - V; break;
if(roman[i+1] == 'L') num = L - V; break;
if(roman[i+1] == 'X') num = X - V; break;
}
num = V; break;
case 'I':
if ( i + 1 != roman.size() && roman[i + 1] != 'I'){
if(roman[i+1] == 'M') num = M - I; break;
if(roman[i+1] == 'D') num = D - I; break;
if(roman[i+1] == 'C') num = C - I; break;
if(roman[i+1] == 'L') num = L - I; break;
if(roman[i+1] == 'X') num = X - I; break;
}
num =1; break;
}
return num;
}
** I have added the help of people on here. This is an edit to show an progress/congress.
This is the code that I use to convert Roman (smaller than 3999) to Integer. You may check if it works for larger numbers.
int romanToInt(string s) {
map<char, int> roman;
roman['M'] = 1000;
roman['D'] = 500;
roman['C'] = 100;
roman['L'] = 50;
roman['X'] = 10;
roman['V'] = 5;
roman['I'] = 1;
int res = 0;
for (int i = 0; i < s.size() - 1; ++i)
{
if (roman[s[i]] < roman[s[i+1]])
res -= roman[s[i]];
else
res += roman[s[i]];
}
res += roman[s[s.size()-1]];
return res;
}
Hope this could help you.
The solution provided by Annie Kim works, but it uses a std::map, querying it several times for the same character, and I fail to see a reason for it.
int convert_roman_digit(char d)
{
switch (d)
{
case 'M': return 1000;
case 'D': return 500;
case 'C': return 100;
case 'L': return 50;
case 'X': return 10;
case 'V': return 5;
case 'I': return 1;
default: throw std::invalid_argument("Invalid digit");
}
}
int roman_to_int(const std::string& roman)
{
int result = 0, last_added = 0;
for (auto it = roman.rbegin(); it != roman.rend(); ++it)
{
const int value = convert_roman_digit(*it);
if (value >= last_added)
{
result += value;
last_added = value;
}
else
{
result -= value;
}
}
return result;
}
Caveat: the function happily accepts some invalid inputs (e.g. IMM) including "negative" numbers (e.g. IIIIIIIIIIIIIX), there are no overflow checks, and it throws. Feel free to improve it.
int romanToInt(string s)
{
unordered_map<char, int> roman;
roman['I'] = 1;
roman['V'] = 5;
roman['X'] = 10;
roman['L'] = 50;
roman['C'] = 100;
roman['D'] = 500;
roman['M'] = 1000;
int num = 0, prev = 0, curr;
for (int i = s.length() - 1; i >= 0; i--)
{
curr = roman[s[i]];
num += (curr >= prev ? 1 : -1) * curr;
prev = curr;
}
return num;
}