3

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

Stefan4024
  • 694
  • 1
  • 10
  • 21
  • What have you tried? Where do you get stuck when writing the code? Can you show us the code you've written so far? – Gareth McCaughan Apr 30 '12 at 23:49
  • 1
    Stackoverflow isn't here to hand out code. This question will be closed unless you edit it to tell us what you've tried and where you're really stuck (and "all of it" is not a good answer). – wkl Apr 30 '12 at 23:49
  • 1
    I put my code, so check it tell me where i am doing it wrong – Stefan4024 May 01 '12 at 00:01
  • Why not just use `qsort`? You're clearly putting them in the wrong order because the lone `9` is not coming first. – David Schwartz May 01 '12 at 00:07
  • 2
    This is a legitimate coding puzzle, a little on the easy side, but not entirely trivial. With the coding attempt in place, I think the question should be OK to reopen. – Sergey Kalinichenko May 01 '12 at 00:23
  • I personally see this working well with a vector, custom comparison predicate, and a stringstream. – chris May 01 '12 at 00:39
  • @chris i'm pretty new to c++ and i don't really understand vectors in c++, please explain me a little or write a solution to this problem – Stefan4024 May 01 '12 at 01:20

1 Answers1

2

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;
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • I don't see what is wrong with the algorithm, for example i'm comparing 9 and 98 i'm checking [9] and [9]8(first digits) and they have the same value, so i'm checking second, but because 9 has 1 digit, i'm swaping the place with 98 in case 98 is entered before 9, and if it's vice versa i'm doing nothing. – Stefan4024 May 01 '12 at 00:43
  • Your algorithm is wrong. check (for example) 5,57. – asaelr May 01 '12 at 00:48
  • I don't think so. Check this: 5 == 5 // comparing the frst digits Because 5 doesn't have second number i checking if 5 has smaller length than 57 and then swaping their places. If you're thinking 5,57 (decimal number), it's impossible, beacause, the blocks are only integers – Stefan4024 May 01 '12 at 00:50
  • I'll be really thankful if someone give me a better algorithm or with the same efficiency (although i really doubt in that) – Stefan4024 May 01 '12 at 00:54
  • @Stefan4024 I was talking to dasblinkenlight. according to his algorithm, 5 is above 57 (because `59>57`), but the largest possible number is 575, not 557. – asaelr May 01 '12 at 00:56
  • @Stefan4024 My suggest - to compare 2 numbers, "glue" them in both orders, and check how do you get larger answer. Now, you can apply any sort algorithm. – asaelr May 01 '12 at 00:57
  • @asaelr Thanks for the correction! Your algorithm works, [here is a link to it on ideone](http://ideone.com/2IrUV). – Sergey Kalinichenko May 01 '12 at 13:36
  • Algorithm and the code work fine for little number, but when you enter about 100 numbers and the value of numbers is 10000-100000 the result is wrong. – Stefan4024 May 03 '12 at 19:49
  • @Stefan4024 Oh, that's because of `int` overflow in `atoi`. See the edit for a correction that should make it work. – Sergey Kalinichenko May 03 '12 at 19:56