0

I was trying to solve this question:

Create a program that converts Roman numbers (such as MCMLIV) to Arabic numbers (1954) and back.

Roman numerals are read from left to right, as you add or subtract the value of each symbol.

If a value is lower than the following value, it will be subtracted. Otherwise it will be added.

For example, we want to convert the Roman numeral MCMLIV to an Arabic number:

M = 1000 must be added, because the following letter C =100 is lower. C = 100 must be subtracted because the following letter M =1000 is greater. M = 1000 must be added, because the following letter L = 50 is lower. L = 50 must be added, because the following letter I =1 is lower. I = 1 must be subtracted, because the following letter V = 5 is greater. V = 5 must be added, because there are no more symbols left.

We can now calculate the number: 1000 - 100 + 1000 + 50 - 1 + 5 = 1954

My code is:

#include <iostream>
#include <string>
using namespace std;
#include <vector>

vector<char> alphas = {'I','V', 'X', 'L', 'C', 'D', 'M'};
vector<int> values = {1, 5, 10, 50, 100, 500, 1000};


int getpos(char c){
    int index = -1;
    for (auto p: alphas){
        index += 1;
        if (p== c)
            return index;
    }
}


int main()
{

    string s; int num, ans;
    cout << "Please enter the Roman Numeral" << endl;
    cin >> s;

    int size = s.size();
    for (int i = 1; i < size; i++){
        if (values[getpos(s[i-1])] > values[getpos(s[i])]){
        // If i add a std::cout statement here, it starts giving you the correct answer!
            ans += values[getpos(s[i-1])];}
        else{
            ans -= values[getpos(s[i-1])];}

}
        ans += values[getpos(s[s.size()-1])];
        cout << ans << endl;
}

Input: MCMLIV

Output: 1956(Incorrect)

In the next code, I make a subtle difference:

for (int i = 1; i < size; i++){
        cout << " I am comparing " << values[getpos(s[i-1])] << " and " << values[getpos(s[i])] << endl;
        if (values[getpos(s[i-1])] > values[getpos(s[i])]){
            ans += values[getpos(s[i-1])];}
        else{
            ans -= values[getpos(s[i-1])];}

Please enter the Roman Numeral

Input:MCMLIV

Output: I am comparing 1000 and 100
I am comparing 100 and 1000
I am comparing 1000 and 50
I am comparing 50 and 1
1954 (Correct answer!)

And now the gives you the correct answer!

So how can a std::cout statement change the output of the program!?

K Kimash
  • 87
  • 1
  • 2
  • 9
  • 1
    `getpos` will not return anything if there is no such element in `alphas` that's equal to `c`. This will be undefined behaviour, if invoked, which may result in *any* kind of output. – Fureeish Sep 15 '19 at 15:59
  • @Fureeish There's not 'c' but 'C' is there! And why is it returning the correct answer if i am just adding a std::cout statement!? – K Kimash Sep 15 '19 at 16:05
  • I was talking about this `c`: `int getpos(char c)`. The name of the argument. Like I said - potential undefined behaviour may lead to anything happening. For example, the code seeming to work if you add additional `std::cout <<` calls. – Fureeish Sep 15 '19 at 16:06
  • @KKimash Undefined Behaviour is undefined. It can do literally anything, and there's no way to predict what it will do. – Yksisarvinen Sep 15 '19 at 16:06
  • 1
    Unrelated: `s[s.size()-1]` could be `s.back()` – user4581301 Sep 15 '19 at 16:10
  • your "ans" variable is not initialized. So it can have any value. depend on many reason its value can be changed. One reason is actual code. So changing code anywhere may have impact on initial value of ans. Best solution is initializing ans to 0. It will work every time. – amald Sep 16 '19 at 09:16
  • Please try to avoid `using namespace std;` because it is considered bad practice. See [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/q/1452721) – L. F. Sep 16 '19 at 10:29

0 Answers0