-2

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
    } 
}






}
2
  • 6
    Please post text and code, not images.
    – jarmod
    Commented Jun 11 at 17:31
  • 2
    A switch statement seems well suited to this problem. Commented Jun 11 at 17:40

1 Answer 1

4
  • 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.

3
  • 1
    Might want to just declare int vals[256]; and then use assignments like: vals['X'] = 10;
    – Chris
    Commented Jun 11 at 18:09
  • 1
    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 };
    – Chris
    Commented Jun 11 at 18:24
  • 2
    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. Commented Jun 12 at 2:46

Not the answer you're looking for? Browse other questions tagged or ask your own question.