Help with loops & if statements

I need to create a program where given an integer n (input from the user), the program determines the equivalent of n in the roman numeral system. The user will provide a value of n greater than 0 and less than 4000.

the solution must use

* 1 or 2 loops at most
* 1, 2, 3 or 4 switch instructions at most, and each switch can have up to 5 cases, including the default case
* less than 11 if statements
* no strings!!

I used this code however there are too many loops and if statements how could i reduce it to fit the requirements
thank you

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <iostream>
using namespace std;



int main()
{


double n;
int intn, m, d, c, l, x, v, i, p;


cout << "Enter n ";
cin >> n;
intn = (int)n;


if (intn >= 1000)
{
    m = intn / 1000;
    n = 0;
		{
		for (p; p < m; p++)
		cout << "M";
		}
	intn = intn%1000;
}


if (intn >= 900)
{
	cout << "CM";
	intn = intn%900;
}
	else if (intn >= 500)
    {
			{
			d = intn / 500;
			p = 0;
			for (p; p < d; p++)
			cout << "D";
			}
        intn = intn%500;
    }


if (intn >= 400)
{
	cout << "CD";
	intn = intn%400;
}
    else if (intn >= 100)
	{
		    {
            c = intn / 100;
            p = 0;
            for (p; p < c; p++)
            cout << "C";
			}
		intn = intn%100;
	}


if (intn >= 90)
{
cout << "XC";
intn = intn%90;
}


	else if (intn >= 50)
	{
			{
            l = intn / 50;
			p = 0;
            for (p; p < l; p++)
            cout << "L";
			}
		intn = intn%50;
	}
if (intn >= 40)
{
cout << "XL";
intn = intn%40;
}


	else if (intn >= 10)
	{
			{
            x = intn / 10;
            p = 0;
            for (p; p < x; p++)
            cout << "X";
			}
		intn = intn%10;
	}


if (intn >= 9)
{
cout << "IX";
intn = intn%9;
}


	else if (intn >= 5)
	{
			{
            v = intn / 5;
            p = 0;
            for (p; p < v; p++)
            cout << "V";
			}
		intn = intn%5;
	}
if (intn >= 4)
{
cout << "IV";
intn = intn%4;
}
	else if (intn >= 1)
	{
           i = intn;
           p = 0;
           for (p; p < i; p++)
           cout << "I";
	}




return 0;


}
Last edited on
if you stare at -> https://i.pinimg.com/736x/54/59/a9/5459a94e8ac5ac75341780952fca954e--roman-numeral--romans.jpg

long enough, you notice a pattern.

I = 1
II = 2
III = 3
IIII != 4 ?!
V = 5

VI = 6
VII = 7
VIII = 8
VIIII != 9 ?!

X = 10

so now you can model that pattern with the right checks and recursion.

//PSEUDO CODE
1
2
3
4
5
6
7
8
if
(number >= 4)
    {
         return composition + (number >= 5)  "V" + recursion(decrease number by 5)
                                          :  "IV" + recursion(decrease number by 4);
    }

while (number > 0) { composition += "I"; number--; }


so if I input 3, the if check fail and the while loop build a string of "III"
if I input 4, the if succed, the second case of the ternary operator is choosen, my string become "IV", number become 0 and the while add nothing to it

if I input 7, the if will pick up the "V", and the 2 remaining digits will be handled by the while in the recursive call

so you would have a similar case above the 4, checking for 9 and 10, then one more above checking for 40 and 50 and so on for the other "breaking points" where the symbols change

For this to work though, you also need to know about recursion :)


Last edited on
I actually tested it and it print this, 11 line recursive function :)
You don't need any for loop or modulus operations or divisions if you do it this way


1 : I        11: XI       21: XXI      31: XXXI     41: XLI      51: LI       61: LXI
2 : II       12: XII      22: XXII     32: XXXII    42: XLII     52: LII      62: LXII
3 : III      13: XIII     23: XXIII    33: XXXIII   43: XLIII    53: LIII     63: LXIII
4 : IV       14: XIV      24: XXIV     34: XXXIV    44: XLIV     54: LIV      64: LXIV
5 : V        15: XV       25: XXV      35: XXXV     45: XLV      55: LV       65: LXV
6 : VI       16: XVI      26: XXVI     36: XXXVI    46: XLVI     56: LVI      66: LXVI
7 : VII      17: XVII     27: XXVII    37: XXXVII   47: XLVII    57: LVII     67: LXVII
8 : VIII     18: XVIII    28: XXVIII   38: XXXVIII  48: XLVIII   58: LVIII    68: LXVIII
9 : IX       19: XIX      29: XXIX     39: XXXIX    49: XLIX     59: LIX      69: LXIX
10: X        20: XX       30: XXX      40: XL       50: L        60: LX       70: LXX
Last edited on
I'll show you my two implementations with the purpose of learning in mind, so don't copy this on your homework exercise, that would be cheating.

Straightforward implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
string toRoman(int number)
{
int currNumber;
string currString;

if      (number >= 1000) { currNumber = 1000; currString = "M"; }
else if (number >= 900 ) { currNumber = 900 ; currString = "CM"; }
else if (number >= 500 ) { currNumber = 500 ; currString = "D"; }
else if (number >= 400 ) { currNumber = 400 ; currString = "CD"; }
else if (number >= 100 ) { currNumber = 100 ; currString = "C"; }
else if (number >= 90  ) { currNumber = 90  ; currString = "XC"; }
else if (number >= 50  ) { currNumber = 50  ; currString = "L"; }
else if (number >= 40  ) { currNumber = 40  ; currString = "XL"; }
else if (number >= 10  ) { currNumber = 10  ; currString = "X"; }
else if (number >= 9   ) { currNumber = 9   ; currString = "IX"; }
else if (number >= 5   ) { currNumber = 5   ; currString = "V"; }
else if (number >= 4   ) { currNumber = 4   ; currString = "IV"; }
else if (number >= 1)    { currNumber = 1; currString = "I"; }
else { return ""; }

return currString + _toRoman(number - currNumber);
}


Alternative implementation (does the same thing of the one above, has a tradeoff between number of lines and readability)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
string toRoman(int number)
{
	string str; int currVal;
	map<char, int> romans{ {'M',1000} , {'D',500}, {'C',100}, {'L',50}, {'X',10}, {'V',5}, {'I',1} };
	if      (number >= 1000) { str = "M"; }
	else if (number >= 900 ) { str = "CM"; }
	else if (number >= 400 ) { str = "CD"; }
	else if (number >= 90  ) { str = "XC"; }
	else if (number >= 40  ) { str = "XL"; }
	else if (number >= 9   ) { str = "IX"; }
	else if (number >= 4   ) { str = "IV"; }
	else if (number >= 1)    { str = "I"; }
	else { return ""; }

	str = (str.size() == 2 && number >= romans[str[1]]) ? string{ str[1] } : str;
	int currVal = (str.size() == 2) ? romans[str[1]] - romans[str[0]] : romans[str[0]];

	return str + toRoman(number - currVal);
}


Test:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
	cout << left;
	for (size_t row = 1; row <= 10; row++)
	{
		for (size_t col = 0; col < 7; col++)
		{
			int value = row + (col * 10);
			cout << setw(2) << value << ": " << setw(7) << toRoman(value) << setw(2) << " ";
		}
		cout << endl;
	}
	
	return 0;
}
Last edited on
Topic archived. No new replies allowed.