Form minimum number from the given sequence of I's and D's

Viewed 3092

Given a sequence consisting of 'I' and 'D' where 'I' denotes increasing sequence and 'D' denotes the descreasing sequence. Write a program that decodes the given sequence to construct minimum number without repeated digits. The digits should start from 1 i.e. there should be no zeroes.

   Input: D        Output: 21
   Input: I        Output: 12
   Input: DD       Output: 321
   Input: II       Output: 123
   Input: DIDI     Output: 21435
   Input: IIDDD    Output: 126543
   Input: DDIDDIID Output: 321654798 

My python code works. I translated it into C++ but the C++ version doesn't work. I don't understand why.

Python code (Works):

s = input()
ans = [1]
count = 0
for i in s:
    if i == 'I':
        count = 0
        k = len(ans)
        ans.append(k + 1)
    else:
        count += 1
        tmp = ans[-1]
        for i in range(-1, -1 - count, -1):
            ans[i] += 1
        ans.append(tmp)
for i in ans:
    print(i, end = "")

C++ code (Doesn't work i.e. doesn't give the correct output)

#include <bits/stdc++.h>

using namespace std;

vector<int> digits(string s){
    vector<int> ans = {1};
    int count = 0;
    for (char const &c : s){
        if (c == 'I'){
            count = 0;
            int k = ans.size();
            ans.push_back(k + 1);
        }
        else{
            count ++;
            int tmp = ans.back();
            for (int i = ans.size() - 1; i > ans.size() - 1 - count; i--){
                ans[i] += 1;
            }
            ans.push_back(tmp);
        }
    }
   return ans; 
}

int main(){
    string s;
    cin >> s;
    vector<int> ans = digits(s);
    for (int i = 0; i < ans.size(); i++){
        cout << ans[i];
    }
    return 0;
}

Eg - When I input DD in the C++ code, it gives 111, but it should output 321.

1 Answers

ans.size() in C++ returns a size_t, which is unsigned (either 32-bit or 64-bit depending on your configuration). You can simply cast ans.size() to an int to fix your issue, like so:

for ( int i = static_cast<int>(ans.size()) - 1; i > static_cast<int>(ans.size()) - 1 - count; i-- )

Using a debugger, you could check that you never actually got into the for-loop's body, for your input.

As NotAProgrammer notes, unsigned-to-signed conversion may be implementation defined, but this should work in most (all?) cases for your examples. From [conv.integral]/3:

If the destination type is signed, the value is unchanged if it can be represented in the destination type; otherwise, the value is implementation-defined.

Related