0

I have written a code for this problem:

Given a list of non negative integers, arrange them such that they form the largest number.

For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330.

Note: The result may be very large, so you need to return a string instead of an integer.

What basically I am trying to achieve in this code is to use radix sort logic on most significant digit first and arranging it as per decreasing order. Later I am doing for second most significant digit and so on. I have used std::sort() function by passing a vector of pairs, where first of the pair is the value and second of the pair is the index. The following is my code:

bool radixOrder(pair<int,int> p1, pair<int,int> p2)
{
    int val1=p1.first;
    int e1=p1.second;
    int val2=p2.first;
    int e2=p2.second;
    if(val1==val2 && e1==e2)
    {
        return val1==val2;
    }
    else if(((val1/e1)%10) == ((val2/e2)%10))
    {
        while(val1/e1 == val2/e2)
        {
            if(e1/10!=0)
                e1=e1/10;
            if(e2/10!=0)
                e2=e2/10;
        }
        return (val1/e1)%10 > (val2/e2)%10;
    }
    else
    {
        return (val1/e1)%10 > (val2/e2)%10;
    }
}

vector<pair<int,int> > createVNew(vector<int>& v)
{
    vector<pair<int,int> > temp;
    for(int i=0; i<v.size(); i++)
    {
        cout << i << endl;
        int val=v[i], e=1;
        if(v[i]==0)
        {
            temp.push_back(make_pair(val, 1));
        }
        else
        {
            while((e/v[i])==0)
                e*=10;
            if(e!=v[i])
            {
                temp.push_back(make_pair(val,e/10));
            }
            else if(e==v[i])
            {
                temp.push_back(make_pair(val,e));
            }
        }
    }
    return temp;
}

string largestNumber(vector<int>& v)
{
    int e=1;
    vector< pair<int,int> > vnew=createVNew(v);
    sort(vnew.begin(), vnew.end(), radixOrder);
    stringstream s;
    for(int i=0; i<vnew.size(); i++)
    {
        s<<vnew[i].first;
    }
    return s.str();
}

largestNumber(..) is my function which is returning the desired string. Now This code works fine for most non zero inputs that I could try. But when input is a long vector of 0's, something like:

[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

it is giving floating point exception.

I have tried finding the solution, but havent been able to. I am a beginner in cpp, and any help would be great.

Community
  • 1
  • 1
user2223211
  • 165
  • 1
  • 2
  • 7

1 Answers1

3

Your radixSort function violates the Compare requirements, namely irreflexivity (that is, radixOrder(x, x) must return false but it returns true because the execution goes to the first if branch).

So you get a classic example of undefined behavior here. I believe that piece of code should be rewritten somehow like

if (e1==e2)
{
    return val1 > val2;
}

Though, I would solve the problem just by sorting the input numbers as strings in reverse order.

Anton Savin
  • 40,838
  • 8
  • 54
  • 90
  • Thank a lot. I just have one more question, why did the code crashed only for large inputs and not smaller ones? Also, just this one out of curiosity, but how did you get to this conclusion that comparator must be wrong? I was trying to search it a lot, but didn't got anywhere near it. It was genius of you @Anton Savin :) – user2223211 Jun 15 '15 at 09:43
  • 1
    @user2223211 No problem. To answer why in this particular case it crashes only for large inputs you have to debug into the `sort` implementation. – Anton Savin Jun 15 '15 at 09:49
  • 1
    @user2223211: `std::sort` generally works recursively: to sort a sequence, break it into two sets and sort those, then merge the two halves. Now it turns out this is not efficient for small sets. Splitting a sequence of two elements in two halves of one element each is obviously not efficient. So `std::sort` typically is optimized for small collections, and that optimization most likely calls your predicate in different ways. – MSalters Jun 15 '15 at 13:24