Removing leading zeroes from an array of integers

I have an array of integers that may result in many leading zeros such as

 
 000000000000000001234


when I want just the "1234"

Bonus question:
if i have all 9's for my array of 20 integers, and I add 1 to it, how can I make i catch the integer overflow?

here's my code
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
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

void initialize(int digits[], int size);//initializes all elements, sets everything to '0'
void addition(int digits1[], int digits2[], int size);//add elements of the arrays
void subtraction(int digits1[], int digits2[], int size);//subtract elements of the arrays
void display(int digits[], int size);//displays the array


int main()
{
	string number1;
	string number2;
	char math;
	
	while (true) {

		cout << "Enter an expression:\n";
		cin >> number1 >> math >> number2;

		//check for sentintal
		if (number1 == "0" && math == '%' && number2 == "0") {
			break;
			return 0;
		}

		const int SIZE = 20;
		int digits1[SIZE];
		int digits2[SIZE];

		//sets all values in both arrays to '0'
		initialize(digits1, SIZE);
		initialize(digits2, SIZE);

		//takes the characters of the inputted string and places them into the arrays
		for (int i = 0; i < number1.length(); i++) {
			digits1[SIZE - (i + 1)] = number1[number1.length() - (i + 1)] - '0';
		}
		for (int i = 0; i < number2.length(); i++) {
			digits2[SIZE - (i + 1)] = number2[number2.length() - (i + 1)] - '0';
		}
		

		//conditional operations
		if (math == '+') {
			addition(digits1, digits2, SIZE);
			display(digits1, SIZE);

			cout << endl;
		}
		else if (math == '-') {
			subtraction(digits1, digits2, SIZE);
			display(digits1, SIZE);
			cout << endl;
		}
		else {
			cout << "Invalid Operator\n";
			return 0;
		}
	}
	
    return 0;
}


void initialize(int digits[], int size) {
	for (int i = 0; i < size; i++) {
		digits[i] = 0;
	}
}

void addition(int digits1[], int digits2[], int size) {
	for (int i = size - 1; i > 0; --i) {
		int sum = digits1[i] + digits2[i];
		if (sum >= 10) {
			digits1[i - 1]++;
			sum = sum - 10;
		}
		digits1[i] = sum;
	}
}


void subtraction(int digits1[], int digits2[], int size) { 
	for (int i = size - 1; i > 0; --i) {
		int difference = digits1[i] - digits2[i];
		if (difference < 0) {
			digits1[i - 1]--;
			difference = difference + 10;
		}
		digits1[i] = difference;
	}
}

void display(int digits[], int size) {
	for (int i = 0; i < size; i++) {
		cout << digits[i] << ' ';
	}
}

Last edited on
using std::find_if:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <algorithm>
#include <iterator>

int main()
{
    int ar[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4};
    auto itr = std::find_if(std::begin(ar), std::end(ar), [](const int n) {return n != 0;});
    if (itr != std::end(ar))
    {
        while (itr != std::end(ar))
        {
            std::cout << *itr << " ";
            ++itr;
        }
        std::cout << "\n";
    }
    else
    {
        std::cout << "No non-zero elements in the array \n";
    }
}

re the bonus, if the sum is greater than 20 digits (or whatever) then you have to declare a new array dynamically
Hello Chamat,

I do not yet understand the use of the arrays, but it works. If you want to skip the leading zeros add this line before the "cout" in the "display" function if (digits[i] == 0) continue;.

Hope that helps,

Andy
Andy - OP wants to remove leading 0's only, with if (digits[i] == 0) continue;. non-leading 0's will also be avoided
I think you should read user input of the number into a string, then use the std::string::find_first_not_of() function to find the first character not a '0' and erase all characters before that character. Simple.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>


int main(int argc, char *argv[])
{
    std::string number = "00001234", number2 = "1234";
    
    number.erase(0, number.find_first_not_of('0')); // remove leading zeros
    number2.erase(0, number2.find_first_not_of('0')); // won't remove anything
    
    std::cout << number << '\n' << number2 << "\n\n";
    
    std::cout << std::stoi(number) << '\n' << std::stoi(number2) << '\n'; // convert string to int
    
    return 0;
}


Of course, if the string is "0" or "00000" then everything is erased. To fix this you can do this:
1
2
3
4
5
const std::string::size_type pos = number.find_first_not_of('0');
if (pos != std::string::npos)
    number.erase(0, pos);
else
    number = "0";
Last edited on
I don't think I can work these solution with an array of integers.

I'm trying to convert my array into a string but I'm doing something wrong.

Here's the function in progress that I have right now

1
2
3
4
5
6
7
string toString(int digits[], int size){
	string number = " ";
	for(int i = 0; i < size - 1; i++){
		number[i] = digits[i];
	}
	return number;
}


I also tried using
 
itoa(digits[i]) 


but there aren't enough arguments and I have no idea how to implement it.
Last edited on
Chamat wrote:
I don't think I can work these solution with an array of integers.

You can first remove the zeros in the string, and then convert the string into an array of integars.
1
2
3
4
	string number = " ";
	for(int i = 0; i < size - 1; i++){
		number[i] = digits[i];
	}

number has a length of 1, so accessing anything over an index of 0 will cause undefined behaviour. Also, with your current loop condition, you won't convert the last digit.

1
2
3
4
5
6
7
string toString(int digits[], int size){
    string number;
    for(int i = 0; i < size; i++){
        number += digits[i] + '0';
    }
    return number;
}
I'd also give vectors a chance, for example (very basic):
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
124
125
126
127
128
129
130
131
132
#include <cmath>
#include <iostream>
#include <limits>
#include <string>
#include <vector>

constexpr char ALLOWEDOPERATIONS[] = "+-";

//add elements of the arrays
void addition(std::vector<int>& digits1, std::vector<int>& digits2);

//subtract elements of the arrays
void subtraction(std::vector<int>& digits1, std::vector<int>& digits2);

void display(const std::vector<int>& digits);

int main()
{
    std::string all_op = std::string(ALLOWEDOPERATIONS);
    char mathexpr = '+'; // need to be a legitimate operand at the beginning
    while (all_op.find(mathexpr) != std::string::npos) {
        int number1 {0}, number2 {0};
        mathexpr = {};

        while(number1 < 1 || number2 < 1) {
            std::cout << "Please, enter an expression: ";
            std::cin >> number1 >> mathexpr >> number2;

            if(all_op.find(mathexpr) == std::string::npos) {
                std::cout << "Unknown operation requested. Exiting now\n";
                return 0; // not an error
            }

            // Can't deal with negative numbers
            if (number1 < 1 || number2 < 1) {
                std::cout << "Sorry, no number less than 1.\n";
            }
        }

        std::vector<int> digits1, digits2;

        // std::log10 will inform us on how many digits are there in number1
        auto numofdigits = (unsigned int)(std::log10(number1)+1);
        for(unsigned i{0}; i<numofdigits; i++) {
            digits1.push_back(number1 % 10);
            number1 /= 10;
        }

        numofdigits = (unsigned int)(std::log10(number2)+1);
        for(unsigned i{0}; i<numofdigits; i++) {
            digits2.push_back(number2 % 10);
            number2 /= 10;
        }

        switch(mathexpr) {
        case '+':
            addition(digits1, digits2);
            break;
        case '-':
            subtraction(digits1, digits2);
            break;
        default:
            std::cout << "Invalid operation requested. Exiting...\n";
            return 0;
            break; // for future development
        }
        std::cout << "\nResult: ";
        display(digits1);
        std::cout << '\n';
    }

    return 0;
}

void addition(std::vector<int>& digits1, std::vector<int>& digits2)
{
    // digits1 and digits2 could be of different length, so we need to determin
    // the shortest
    size_t shortest = digits1.size() < digits2.size() ?
                        digits1.size() : digits2.size();

    for(size_t i = 0; i < shortest; i++) {
        int sum = digits1.at(i) + digits2.at(i);
        if (sum > 9) {
            if(i+1 >= digits1.size()) {
                digits1.push_back(1);
            } else {
                digits1[i+1]++;
            }
            sum = sum - 10;
        }
        digits1[i] = sum;
    }
}

void subtraction(std::vector<int>& digits1, std::vector<int>& digits2)
{
    // digits1 and digits2 could be of different length, so we need to determin
    // the shortest
    size_t shortest = digits1.size() < digits2.size() ?
                        digits1.size() : digits2.size();

    for (size_t i = 0; i < shortest; i++) {
        int difference = digits1[i] - digits2[i];
        if (difference < 0) {
            digits1.at(i+1)--;
            difference = difference + 10;
        }
        digits1[i] = difference;
    }

    // Pop out leading zeroes, if any.
    bool nonzerofound {false};
    std::vector<int>::iterator firstel = digits1.end();
    for(int i = int(digits1.size()-1); i>=0; i--) {
        if(digits1.at(i) != 0) {
            nonzerofound = true;
        } else if(nonzerofound != true){
            // no digit different from 0 found yet
            firstel--;
        }
        std::cout << '\n';
    }
    digits1.erase(firstel, digits1.end());
}

void display(const std::vector<int>& digits)
{
    for(int i = int(digits.size()-1); i>=0; i--) {
        std::cout << digits.at(i);
    }
}

I'd also give vectors a chance, for example (very basic):
1
2
    while (all_op.find(mathexpr) != std::string::npos) {
        int number1 {0}, number2 {0};

The point of OP's program was to extend the range of ints using std::strings and arrays. Your code kind of defeats the purpose so you may as well just use the native addition/subtraction operators.
Last edited on
You know OP, if you want to just handle much larger numbers, then make your own class. In the class define how you add, subtract, multiply, divide, error check, remove leading zeros, etc., with functions.

Then overload operators such as =, +, -, *, /, %, +=, =+, *=, /=, %=, etc., so you can use your class like an int (you can even define how the bit wise operations are done and overload operators for them). The only difference for large numbers would be something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// necessary standard libraries...

// your large number class
class large_number
{
    // implementation large number handling
}

int main(int argc, char *argv[])
{
    large_number x;
    
    // overlord assignment operator
    x = "12345678901234567890123456789"; // assign/initialize using a string
    
    std::cout << x << '\n'; // in the class define a friend function that overloads the << operator to print
    
    return 0;
}

The difference would be that you would probably have to use strings to handle the large numbers. Assigning, adding, initializing, etc., would be done using strings (you could convert them into integral types if they are small enough_.
Last edited on
Since you're using a fixed length array, you can't remove the digits. What you can do is modify your display function to skip the leading zeros.

Right now your code assumes that the numbers are of equal length. To see this, try adding 2 to 300. I think you'll get 500 instead of 302. The way to get around this is to store the least significant digit at position 0 and work up from there. Now position 0 is always the 1's digit, position 1 is always the 10's digit, etc.

You can tell if the number overflows by keeping a separate carry (or borrow) variable:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void addition(int digits1[], int digits2[], int size) {
	int sum=0;
	int carry=0;
	for (int i = 0; i<size; ++i) {
		int sum = digits1[i] + digits2[i] + carry;
		if (sum >= 10) {
			carry = 1;
			sum -= 10;
		else {
			carry = 0;
		}
		digits1[i] = sum;
	}
	if (carry) {
		cout << "overflow\n";
	}
}


Topic archived. No new replies allowed.