Bird
Raised Fist0
DSA Cprogramming

Roman to Integer Conversion in DSA C

Choose your learning style10 modes available
Mental Model
Roman numerals are letters that represent values. We add or subtract these values to get the number.
Analogy: Think of Roman numerals like money coins. Usually, you add their values, but if a smaller coin is before a bigger coin, you subtract it like giving change.
R O M A N -> I N T E G E R

Example: M -> 1000
Example: IV -> 4 (5 - 1)

Letters: I(1) -> V(5) -> X(10) -> L(50) -> C(100) -> D(500) -> M(1000)
Dry Run Walkthrough
Input: Roman numeral: "MCMIV"
Goal: Convert "MCMIV" to its integer value 1904
Step 1: Read 'M' (1000), add 1000
Total = 1000
Why: Start with first letter value
Step 2: Read 'C' (100), next is 'M' (1000), since 100 < 1000, subtract 100
Total = 1000 - 100 = 900
Why: Smaller before bigger means subtract
Step 3: Read 'M' (1000), add 1000
Total = 900 + 1000 = 1900
Why: Add value when current is not smaller than next
Step 4: Read 'I' (1), next is 'V' (5), since 1 < 5, subtract 1
Total = 1900 - 1 = 1899
Why: Smaller before bigger means subtract
Step 5: Read 'V' (5), add 5
Total = 1899 + 5 = 1904
Why: Add last value
Result:
Total = 1904
Annotated Code
DSA C
#include <stdio.h>
#include <string.h>

int value(char r) {
    switch(r) {
        case 'I': return 1;
        case 'V': return 5;
        case 'X': return 10;
        case 'L': return 50;
        case 'C': return 100;
        case 'D': return 500;
        case 'M': return 1000;
        default: return 0;
    }
}

int romanToInt(char *s) {
    int total = 0;
    int i = 0;
    int len = strlen(s);
    while (i < len) {
        int curr = value(s[i]);
        int next = (i + 1 < len) ? value(s[i + 1]) : 0;
        if (curr < next) {
            total += (next - curr);  // subtract smaller before bigger
            i += 2;                // skip next as processed
        } else {
            total += curr;         // add current value
            i++;
        }
    }
    return total;
}

int main() {
    char roman[] = "MCMIV";
    int result = romanToInt(roman);
    printf("%d\n", result);
    return 0;
}
int curr = value(s[i]);
get current Roman numeral value
int next = (i + 1 < len) ? value(s[i + 1]) : 0;
get next Roman numeral value if exists
if (curr < next) {
check if smaller before bigger to subtract
total += (next - curr);
add difference for subtractive pair
i += 2;
skip next character as processed
} else {
otherwise add current value
total += curr;
add current value to total
i++;
move to next character
OutputSuccess
1904
Complexity Analysis
Time: O(n) because we scan the Roman numeral string once
Space: O(1) because we use fixed extra space for variables
vs Alternative: This is more efficient than checking all substrings or using maps repeatedly, as it processes characters in one pass
Edge Cases
Empty string
Returns 0 because no numerals to convert
DSA C
while (i < len) {
Single character like 'I'
Returns value of single numeral correctly
DSA C
total += curr;
Invalid characters
Returns 0 for invalid characters due to default case in value()
DSA C
default: return 0;
When to Use This Pattern
When you see a problem asking to convert Roman numerals to numbers, use the subtractive rule pattern where smaller values before bigger ones mean subtraction.
Common Mistakes
Mistake: Always adding values without checking if smaller numeral comes before bigger one
Fix: Add condition to subtract when current numeral is smaller than next numeral
Mistake: Not skipping the next character after processing a subtractive pair
Fix: Increment index by 2 when subtractive pair is processed
Summary
Converts Roman numeral strings to integer values by adding or subtracting letter values.
Use when you need to interpret Roman numerals as numbers in code.
Remember smaller numeral before bigger means subtract, otherwise add.

Practice

(1/5)
1. What is the main rule to convert Roman numerals to integers?
Example: IV = 4, VI = 6
easy
A. Multiply values of all symbols
B. Add values of symbols, subtract if a smaller symbol is before a larger one
C. Add values only if symbols are in alphabetical order
D. Subtract values of all symbols

Solution

  1. Step 1: Understand Roman numeral rules

    Roman numerals add values of symbols, but if a smaller symbol appears before a larger one, it is subtracted.
  2. Step 2: Apply rule to example

    For IV, I (1) is before V (5), so subtract 1 from 5 = 4. For VI, V (5) before I (1), so add 5 + 1 = 6.
  3. Final Answer:

    Add values of symbols, subtract if a smaller symbol is before a larger one -> Option B
  4. Quick Check:

    IV = 4, VI = 6 [OK]
Hint: Subtract when smaller symbol precedes larger one [OK]
Common Mistakes:
  • Always adding without subtraction
  • Multiplying symbols instead of adding
  • Ignoring order of symbols
2. Which of the following C code snippets correctly initializes a map for Roman numeral values?
easy
A. int values = {'I':1, 'V':5, 'X':10};
B. int values[] = {I=1, V=5, X=10};
C. int values[26] = {['I'-'A']=1, ['V'-'A']=5, ['X'-'A']=10};
D. int values[3] = {1, 5, 10};

Solution

  1. Step 1: Understand C array initialization for character keys

    In C, to map characters to values, an array indexed by character offset is used, e.g., values['I'-'A'] = 1.
  2. Step 2: Check each option

    int values[26] = {['I'-'A']=1, ['V'-'A']=5, ['X'-'A']=10}; uses correct syntax for sparse initialization. Options B and C use invalid syntax for C. int values[3] = {1, 5, 10}; initializes array without mapping to characters.
  3. Final Answer:

    int values[26] = {['I'-'A']=1, ['V'-'A']=5, ['X'-'A']=10}; -> Option C
  4. Quick Check:

    Correct C syntax for char-indexed array [OK]
Hint: Use array with char offset for mapping in C [OK]
Common Mistakes:
  • Using dictionary syntax not valid in C
  • Not indexing array by character offset
  • Initializing array without specifying indices
3. What is the output of this C code snippet?
char *s = "MCMXCIV";
int values[26] = {['I'-'A']=1, ['V'-'A']=5, ['X'-'A']=10, ['L'-'A']=50, ['C'-'A']=100, ['D'-'A']=500, ['M'-'A']=1000};
int result = 0, i = 0;
while (s[i]) {
  int curr = values[s[i]-'A'];
  int next = values[s[i+1]-'A'];
  if (next > curr) result -= curr;
  else result += curr;
  i++;
}
printf("%d", result);
medium
A. Error
B. 1904
C. 1494
D. 1994

Solution

  1. Step 1: Trace each character and apply addition/subtraction

    String: M(1000), C(100), M(1000), X(10), C(100), I(1), V(5). Check pairs:
    M(1000) next C(100) -> 100 < 1000? No, add 1000
    C(100) next M(1000) -> 1000 > 100, subtract 100
    M(1000) next X(10) -> 10 < 1000, add 1000
    X(10) next C(100) -> 100 > 10, subtract 10
    C(100) next I(1) -> 1 < 100, add 100
    I(1) next V(5) -> 5 > 1, subtract 1
    V(5) next 0, add 5
  2. Step 2: Calculate total

    1000 - 100 + 1000 - 10 + 100 - 1 + 5 = 1994
  3. Final Answer:

    1994 -> Option D
  4. Quick Check:

    MCMXCIV = 1994 [OK]
Hint: Subtract when next symbol is larger [OK]
Common Mistakes:
  • Adding all values without subtraction
  • Off-by-one error accessing next character
  • Incorrect mapping of Roman symbols
4. Find the bug in this C code for Roman to Integer conversion:
int romanToInt(char *s) {
  int values[26] = {['I'-'A']=1, ['V'-'A']=5, ['X'-'A']=10, ['L'-'A']=50, ['C'-'A']=100, ['D'-'A']=500, ['M'-'A']=1000};
  int result = 0, i = 0;
  while (s[i]) {
    int curr = values[s[i]-'A'];
    int next = values[s[i+1]-'A'];
    if (curr < next) result += curr;
    else result -= curr;
    i++;
  }
  return result;
}
medium
A. The addition and subtraction logic is reversed
B. Array indexing causes out-of-bounds error
C. Values array is not initialized correctly
D. Function does not handle empty string

Solution

  1. Step 1: Analyze addition and subtraction conditions

    Code adds current value if curr < next, else subtracts. This is opposite of Roman rules where smaller before larger means subtract.
  2. Step 2: Correct logic

    It should subtract curr if curr < next, else add curr.
  3. Final Answer:

    The addition and subtraction logic is reversed -> Option A
  4. Quick Check:

    Subtract when smaller before larger [OK]
Hint: Subtract if current < next, else add [OK]
Common Mistakes:
  • Swapping add and subtract conditions
  • Ignoring last character's next value
  • Not initializing values array properly
5. Given the Roman numeral string "XLIX", which of the following C functions correctly returns its integer value?
hard
A. int romanToInt(char *s) { int values[26] = {['I'-'A']=1, ['V'-'A']=5, ['X'-'A']=10, ['L'-'A']=50}; int res=0,i=0; while(s[i]) { int curr=values[s[i]-'A'], next=values[s[i+1]-'A']; if(curr
B. int romanToInt(char *s) { int values[26] = {['I'-'A']=1, ['V'-'A']=5, ['X'-'A']=10, ['L'-'A']=50}; int res=0,i=0; while(s[i]) { int curr=values[s[i]-'A'], next=values[s[i+1]-'A']; if(curr>next) res-=curr; else res+=curr; i++; } return res; }
C. int romanToInt(char *s) { int values[26] = {['I'-'A']=1, ['V'-'A']=5, ['X'-'A']=10, ['L'-'A']=50}; int res=0,i=0; while(s[i]) { int curr=values[s[i]-'A']; res+=curr; i++; } return res; }
D. int romanToInt(char *s) { int values[26] = {['I'-'A']=1, ['V'-'A']=5, ['X'-'A']=10, ['L'-'A']=50}; int res=0,i=0; while(s[i]) { int curr=values[s[i]-'A'], next=values[s[i+1]-'A']; if(curr<=next) res-=curr; else res+=curr; i++; } return res; }

Solution

  1. Step 1: Check logic for subtraction and addition

    int romanToInt(char *s) { int values[26] = {['I'-'A']=1, ['V'-'A']=5, ['X'-'A']=10, ['L'-'A']=50}; int res=0,i=0; while(s[i]) { int curr=values[s[i]-'A'], next=values[s[i+1]-'A']; if(curr
  2. Step 2: Verify with example "XLIX"

    X(10) < L(50) subtract 10
    L(50) > I(1) add 50
    I(1) < X(10) subtract 1
    X(10) no next add 10
    Total = -10 + 50 - 1 + 10 = 49
  3. Final Answer:

    Option A correctly returns 49 for "XLIX" -> Option A
  4. Quick Check:

    Subtract if smaller before larger [OK]
Hint: Subtract if current < next, else add [OK]
Common Mistakes:
  • Using <= instead of < for subtraction
  • Adding all values without subtraction
  • Incorrect comparison operators
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard