7
\$\begingroup\$

I have the following two vectors in C++11:

vector<unsigned char> left = { 1, 2, 3, 4, 5, 6 }; // it is meant to represent the number: 123456
vector<unsigned char> right = { 1, 2, 3, 4 }; // meant to be number: 1234

After a function processes them, they become:

left = { 6, 5, 4, 3, 2, 1 };
right = { 4, 3, 2, 1 };

Now, I need to complete the shorter one with zeros at the end until they are equal in size(). I have thefollowing method:

void bigint::process_operands( vector<unsigned char> & left, vector<unsigned char> & right )
{
 size_t left_size = left.size();
 size_t right_size = right.size();
 if( left_size < right_size )
 {
 size_t size_diff = right_size - left_size;
 for( size_t i = 0; i != size_diff; ++i )
 left.push_back( '0' );
 } else if( right_size < left_size )
 {
 size_t size_diff = left_size - right_size;
 for( size_t i = 0; i != size_diff; ++i )
 right.push_back( '0' );
 }
}

Is there any better implementation?

asked Mar 9, 2014 at 9:42
\$\endgroup\$

3 Answers 3

7
\$\begingroup\$

How about something like this:

auto sz = std::max(left.size(), right.size());
left.resize(sz, '0');
right.resize(sz, '0');

.resize() will resize the container to the given size, and fill the new elements (if any) with the given value.

answered Mar 9, 2014 at 20:29
\$\endgroup\$
2
  • \$\begingroup\$ I am not sure abut its performance, but it compiles... \$\endgroup\$ Commented Mar 10, 2014 at 8:44
  • 1
    \$\begingroup\$ @Victor What are you unsure about? It's at least as efficient as (probably more than) using back_inserter or push_back. If you're worried about max, replace it with a conditional (although it's almost guaranteed to get inlined). \$\endgroup\$ Commented Mar 10, 2014 at 19:15
11
\$\begingroup\$

Firstly, given that you're using vector without namespace qualification (that is, not as std::vector), I assume you have a using namespace std; in this code. This is generally a bad idea, but especially so in this case. You use vector<unsigned char> & right (and vector<unsigned char> left), however, there is a std::right (and a std::left) defined in <ios>. This could potentially lead to some very confusing compiler errors.

Using a few tricks from <algorithm>, we can shorten the above code considerably.

void bigint::process_operands(vector<unsigned char> & left_, vector<unsigned char> & right_)
{
 auto& shorter = (left_.size() < right_.size()) ? left_ : right_;
 std::fill_n(std::back_inserter(shorter), std::abs(left_.size() - right_.size()), '0');
}

This is much more terse, but I find that using the standard library actually makes this code easier to read and more clear as to exactly what it is doing.

answered Mar 9, 2014 at 11:12
\$\endgroup\$
0
5
\$\begingroup\$

I’d just like to point out a very short version of your own code. It is certainly not as C++ish as a vector::insert or fill_n solution, but what it does is pretty obvious.

void bigint::process_operands( vector<unsigned char> & left, vector<unsigned char> & right )
{
 while (left.size() < right.size())
 left.push_back( '0' );
 while (right.size() < left.size())
 right.push_back( '0' );
}
answered Mar 9, 2014 at 18:05
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.