For given number of blocks of digits (number of blocks is bigger than 2 and smaller than 1000), print the biggest possible number.
Here's a little example:
input:
5 // Number of blocks of digits
9 // first block
98 // second
90 // third
5 // fourth
9 // fifth
output:
9998905 // The biggest possible number
I work a little bit on this problem and i have found the algorithm and it seems like it's working for any combination, but i'm having problem with writing a code in C++
Here's the algorithm:
First i input them as a strings, because i can muc easier use specific digits. Then i'm comparing every number's first digit with the every number's first digit. And order them in ascending order. If the first digits are same, i'm checking the second digits and so on to the last digits. If in case the two number have different lengths and the smaller is substring to the other, i order the smaller in front of the bigger number.
As i said before, this algorithm work fine, but i need the code, because i'm having problem with it.
Here's my work until now:
#include <iostream>
#include <string>>
using namespace std;
int main()
{
int nums, maxsl = 0;
cin >> nums;
string s[nums];
for(int i = 0; i<nums; i++)
{
cin >> s[i];
if(s[i].length() > maxsl)
{
maxsl = s[i].length();
}
}
for(int i = 0; i<nums; i++)
{
for(int j = 0; j<nums; j++)
{
for(int k = 0; k<=maxsl; k++)
{
if(k<=s[i].length() && k<= s[j].length())
{
if(s[i][k]>s[j][k])
{
string t = s[i];
s[i] = s[j];
s[j] = t;
}
}
else
{
if(s[i].length() > s[j].length())
{
string t = s[i];
s[i] = s[j];
s[j] = t;
}
}
}
}
}
for(int i = 0; i<nums; i++)
{
cout << s[i];
}
}
But with these code it only print them in ascending order, not the biggest posible number. Here's the output for previous example: 9890995
Your algorithm is not correct: you cannot just sort your blocks lexicographically, because they are of different length. 9 should be considered greater than 98, but it is smaller lexicographically (for the same reason as "car" sorts ahead of "cartoon" in a dictionary).
EDIT :
As asaelr suggested in a comment, one way to compare two blocks of digits is gluing them together both ways (A+B
and B+A
; +
means concatenation), and checking with order produces a larger number. If A+B
is bigger than B+A
, keep the current order; otherwise, switch the numbers.
When a function that compares numbers like this is passed to std::sort
, the correct result is produced.
Here is an implementation of this simple algorithm:
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace std;
bool ahead_of(string left, string right) {
// Try gluing the blocks both ways, and return true or false
// based on which order produced a bigger result.
string a = left+right;
string b = right+left;
return a > b;
}
int main() {
int n;
// Read the number of items
cin >> n;
vector<string> items;
// Read the items themselves
for (int i = 0 ; i != n ; i++) {
string s;
cin >> s;
items.push_back(s);
}
// Sort using the custom comparer
sort(items.begin(), items.end(), ahead_of);
// Copy the result to the output
ostream_iterator<string> out_it (cout, "");
copy( items.begin(), items.end(), out_it );
return 0;
}