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?
3 Answers 3
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.
-
\$\begingroup\$ I am not sure abut its performance, but it compiles... \$\endgroup\$Victor– Victor2014年03月10日 08:44:42 +00:00Commented 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
orpush_back
. If you're worried aboutmax
, replace it with a conditional (although it's almost guaranteed to get inlined). \$\endgroup\$Apples– Apples2014年03月10日 19:15:03 +00:00Commented Mar 10, 2014 at 19:15
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.
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' );
}