获取X个可以全部乘以的整数,以接近Y

时间:2015-08-26 00:44:25

标签: c# math multiplication factoring

很难在标题中解释,但基本上我创建了一个系统,输入一些数字N并输出两个数字(不包括1和N),它们可以相乘,尽可能接近N(过去而不是在。)

以下是一些例子:

  • 25→5& 5.
  • 40→5& 8.
  • 53→6& 9.
  • 13→2& 7。

我有一个方法Factor,它返回X sans 1和X的所有因子的列表。这段代码也不需要使用大数字,所以我通过检查是否在一个数字来测试素数素数列表。

执行此操作的代码在此处:

if (primes.Contains(N))
        N++;
List<int> facts = Factor(N);
double root = Math.Sqrt(N);
int cl1;
int cl2;
if (root == (int)root)
{
    cl1 = (int)root;
    cl2 = (int)root;
}
else if (N == 2)
{
    cl1 = 1;
    cl2 = 2;
}
else
{
    cl1 = facts.Aggregate((x, y) => Math.Abs(x - root) < Math.Abs(y - root) ? x : y);
    facts.Remove(cl1);
    cl2 = facts.Aggregate((x, y) => Math.Abs(x - root) < Math.Abs(y - root) ? x : y);
}

什么是一个很好的方法来概括这个,所以它可以提供三个输出,或四个或五个或九个? (显然我会用数组换出cl1cl2,但我的意思是代码方式)

1 个答案:

答案 0 :(得分:1)

获得N的所有因素是一项相当昂贵的操作。实际上这样做会更快(伪代码):

For p = floor(sqrt(N)); p>1; --p:    
  q = ceil(N/p);
  error = p*q-N; //always positive
  record=make_tuple(p,q,error);
  //... remember the records with the smallest error

维护记录列表的最佳方法取决于您想要的数量。拨打该号码。

如果它只是少数,那么你可以将它们放在一个列表中,每当列表大小达到2M时,按错误排序并截断为大小M.

如果它很多,则将它们放在首先出现最大错误的优先级队列中,并且每当大小为> M时,删除具有最高错误的那个。最后,您可以按相反的顺序将它们拉出来并向后填充输出数组