【问题标题】:How can I sort array elements by number of divisors?如何按除数对数组元素进行排序?
【发布时间】:2016-10-11 18:32:11
【问题描述】:

我的问题是我在做一些练习时遇到了障碍。 问题的根源是我必须编写一个程序,该程序按每个元素的除数的数量对数组进行降序排序,但是当两个元素具有相同数量的除数时,它应该对这些值进行升序排序。 到目前为止我的代码:

#include <iostream>
#include <fstream>

using namespace std;

int cntDiv(int n)   //get number of divisors
{
    int lim = n;
    int c = 0;
    if(n == 1)
        return 1;
    for(int i = 1; i < lim; i++)
    {
        if(n % i == 0)
        {
            lim = n / i;
            if(lim != i)
                c++;
            c++;
        }
    }
    return c;
}

int main()
{
    ifstream fin("in.txt");
    int n, i, j;
    fin >> n;
    int v[n];
    for(i = 0; i < n; i++)
        fin >> v[i];

    int div[n];
    for(i = 0; i < n; i++)
        div[i] = cntDiv(v[i]);

    for(i = 0; i < n - 1; i++)
    {
        for(j = i + 1; j < n; j++)
        {
            if(div[i] < div[j] && div[i] != div[j]) //if the number of divisors are different
            {
                int t = v[i];
                v[i] = v[j];
                v[j] = t;

                t = div[i];
                div[i] = div[j];
                div[j] = t;
            }
            if(div[i] == div[j] && v[i] > v[j]) //if the number of divisors are the same
            {
                int t = v[i];
                v[i] = v[j];
                v[j] = t;
            }
        }
    }

    for(i = 0; i < n; i++)
    {
        cout << v[i] << " ";
    }
    return 0;
}

在.txt:

5
12 20 4 100 13

输出:

100 12 20 4 13

虽然它适用于这个和许多其他。对于更大的输入,它会超过0.1s 的时间限制。有什么建议我应该如何重写排序? (我写冒泡排序是因为我无法通过快速排序实现按属性排序数组)

【问题讨论】:

  • 这不是咨询网站。并且没有语言 C/C++。您的代码是 C++,而不是 C!重新表现:你自己已经回答了你的问题。
  • “我无法通过快速排序实现按属性排序数组”——我不明白这是什么意思。为什么不能实现快速排序?
  • 其实我什么都听不懂。英语不是他的母语
  • 如果你的程序运行正常但超过了时间限制,这可能是一个“挑战问题”。其中许多的想法是天真的解决方案将花费太长时间,而真正的任务是找到一种巧妙的方法来解决它。这就是挑战。
  • 您可以将std::sort 与自定义比较器一起使用(可能还有一个额外的索引向量)。

标签: c++ arrays performance sorting


【解决方案1】:

使用结构数组。该结构将包含原始值和一个除数容器:

struct Number_Attributes
{
  int number;
  std::list<int> divisors;
};

然后你可以编写一个自定义的比较器函数并传递给std::sort

bool Order_By_Divisors(const Number_Attributes& a,
                       const Number_Attributes& b)
{
  return a.divisors.size() < b.divisors.size();
}

那么排序就变成了:

#define ARRAY_CAPACITY (20U)
Number_Attributes the_array[ARRAY_CAPACITY];
//...
std::sort(&array[0], &array[ARRAY_CAPACITY], Order_By_Divisors);

除数的生成留给 OP 练习。

【讨论】:

  • 比较器稍微复杂一点:它应该处理相同大小的divisors
【解决方案2】:

使用std::sort 重写您的代码:

std::vector<std::pair<int, int>> customSort(const std::vector<int>& v)
{
    std::vector<std::pair<int, int>> ps;
    ps.reserve(v.size());

    // We don't have zip sort :/
    // So building the pair
    for (auto e : v)
    {
        ps.emplace_back(e, cntDiv(e)); 
    }
    std::sort(ps.begin(), ps.end(), [](const auto&lhs, const auto& rhs) {
        // descending number of divisors, increasing value
        return std::make_tuple(-lhs.second, lhs.first)
             < std::make_tuple(-rhs.second, rhs.first);
    });
    return ps;
}

int main()
{
    const std::vector<int> v = {12, 20, 4, 100, 13};
    const auto res = customSort(v);

    for(const auto& p : res)
    {
        std::cout << p.first << " ";
    }
}

Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    • 2015-06-28
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    • 2020-10-19
    • 2015-10-18
    相关资源
    最近更新 更多