Search code examples
ccalculation

Program that converts roman numerals to numbers in C language


i am trying to make program for roman numbers converter. in C language But we have some rules.

U can see value of chars in this photo

Letters are written from left to right and from largest to smallest value. Example u want to write 1907.But we cant use same letter 4 times.and for the value 900 we should think of it as 1000-100.its write like that CM Not like MC.

and some examples example

my most important problem is how ı can change string letter to value

thank u

my example with description 
my example with description

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

void main() {

/*
Roma Rakamları Ve Değerleri

I = 1
V = 5
X = 10
L = 50
C = 100
D = 500
M = 1000

*/

/*
Soru 1-
MCMVII
MMXI
XC
MCMXC

değerlei sırasi ile kaçtır

*/
int I = 1;
int V = 5;
int X = 10;
int L = 50;
int C = 100;
int D = 500;
int M = 1000;

char que1[] = "MCMVII";
char que2[] = "MMXI";
char que3[] = "XC";
char que4[] = "MCMXC";

for (int i = 0; i < strlen(que1)-1; i++)
{
    if (que1[i]>que1[i+1])
    {
        printf("%c",que1[i]);
        //Then I will collect the letters one by one myself.
    }else if (que1[i]<que1[i+1])
    {
        printf("%c",que1[i+1]);
        i++;
        //i skipped (i+1).letter
    } 
}






}

Solution

    • You need to keep track of the previous value (i.e., prev).
    • If the current value was bigger than previous value, subtract it from the result twice so that we wouldn't count it twice.

    Code

    #include <stdio.h>
    #include <string.h>
    
    int romanToInt(char *s) {
      int vals[26];
      vals['I' - 'A'] = 1;
      vals['V' - 'A'] = 5;
      vals['X' - 'A'] = 10;
      vals['L' - 'A'] = 50;
      vals['C' - 'A'] = 100;
      vals['D' - 'A'] = 500;
      vals['M' - 'A'] = 1000;
    
      int res = 0;
      int prev = 0;
    
      for (int i = 0; s[i] != '\0'; i++) {
        int curr = vals[s[i] - 'A'];
        res += curr;
        if (curr > prev) {
          res -= 2 * prev;
        }
        prev = curr;
      }
    
      return res;
    }
    
    int main() {
      char que1[] = "MCMVII";
      char que2[] = "MMXI";
      char que3[] = "XC";
      char que4[] = "MCMXC";
    
      printf("%s: %d\n", que1, romanToInt(que1));
      printf("%s: %d\n", que2, romanToInt(que2));
      printf("%s: %d\n", que3, romanToInt(que3));
      printf("%s: %d\n", que4, romanToInt(que4));
    }
    
    

    Prints

    MCMVII: 1907
    MMXI: 2011
    XC: 90
    MCMXC: 1990
    

    Or we can loop through in reverse:

    • We set the prev value to one.
    • We add the current value to the result if the current value was larger and equal to the previous value.
    • We subtract the current value otherwise.
    #include <stdio.h>
    #include <string.h>
    
    int romanToInt(char *s) {
      int vals[256] = {['I'] = 1,   ['V'] = 5,   ['X'] = 10,  ['L'] = 50,
                       ['C'] = 100, ['D'] = 500, ['M'] = 1000};
    
      int res = 0;
      int prev = 1;
    
      for (int i = strlen(s) - 1; i >= 0; i--) {
        int curr = vals[s[i]];
        if (curr < prev) {
          res -= curr;
        } else {
          res += curr;
        }
        prev = curr;
      }
    
      return res;
    }
    
    int main() {
      char que1[] = "MCMVII";
      char que2[] = "MMXI";
      char que3[] = "XC";
      char que4[] = "MCMXC";
    
      printf("%s: %d\n", que1, romanToInt(que1));
      printf("%s: %d\n", que2, romanToInt(que2));
      printf("%s: %d\n", que3, romanToInt(que3));
      printf("%s: %d\n", que4, romanToInt(que4));
    }
    

    Comments

    • @Chris: Might want to just declare int vals[256]; and then use assignments like: vals['X'] = 10;.

    • @Chris: Also suggest initializing your vals array this way: int vals[256] = { ['I'] = 1, ['V'] = 5, ['X'] = 10, ['L'] = 50, ['C'] = 100, ['D'] = 500, ['M'] = 1000 };.

    • @Jonathan Leffler: This works OK on valid inputs, but isn't so good at spotting invalid inputs. It doesn't have a way to report on invalid inputs, even. It seems to assume that char has the same range as unsigned char; if char has the same range as signed char, then negative characters are going to index the vals array out of bounds. It quietly ignores invalid characters. It might be sensible to allow for lower-case Roman numerals; they are widely used too.