来自给定数字块C ++的最大可能数字

时间:2012-04-30 23:46:33

标签: c++ string numbers digits

对于给定数量的数字块(块数大于2且小于1000),请输出最大可能的数字。

这是一个小例子:

输入:

5 // Number of blocks of digits

9 // first block

98 // second

90 // third

5 // fourth

9 // fifth

输出:

9998905 // The biggest possible number

我对这个问题有点了解,我找到了算法,看起来它适用于任何组合,但我在使用C ++编写代码时遇到问题

这是算法:

首先我将它们作为字符串输入,因为我可以更容易地使用特定的数字。 然后我将每个数字的第一个数字与每个数字的第一个数字进行比较。并按升序排序。 如果第一个数字相同,我正在检查第二个数字,依此类推到最后的数字。 如果两个数字有不同的长度而较小的是另一个的子串,我在较大的数字前面订购较小的数字。

正如我之前所说,这个算法运行正常,但我需要代码,因为我遇到了问题。

这是我迄今为止的工作:

#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];
    }
}

但是这些代码只能按升序打印,而不是最大的可能数字。 这是上一个例子的输出:9890995

1 个答案:

答案 0 :(得分:2)

您的算法不正确:您不能按字典顺序对块进行排序,因为它们的长度不同。 9应该被认为大于98,但它在字典上是较小的(出于与字典中“卡通”之前的“汽车”排序相同的原因)。

编辑:

正如asaelr在评论中所建议的那样,比较两个数字块的一种方法是将它们双向粘合在一起(A+BB+A; +表示连接),并检查订单会产生更大的数字。如果A+B大于B+A,请保留当前订单;否则,切换数字。

当比较这样的数字的函数传递给std::sort时,会产生正确的结果。

以下是这个简单算法的实现:

#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;
}