我正在做一项涉及“相当好”数字的作业。任务将其描述为:
“相当好”的数字是一个整数,其“坏”——其除数之和与数字本身之差的大小——不大于指定值。例如,如果最大坏值设置为3,则有12个“相当好”小于100的数字:2、3、4、6、8、10、16、18、20、28、32和64;您的任务是编写一个C程序quitegood,用于确定小于指定值的指定最大不良数。当程序执行时,极限值和最大不良数被指定为命令行参数
该任务要求我编写一个程序,该程序打印具有指定坏度限制的完美数字,最高可达一百万。因此,相当好1000000 1的命令行参数应该打印2 4 6 8 16 28 32 64 128 256 496 512 1024 2048 4096 8128 8192 16384 32768 65536 131072 262144 524288。
我已经让它与以下代码一起工作
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
const int limit = argc > 1 ? atoi(argv[1]) : 1000000;
const int badness = argc > 2 ? atoi(argv[2]) : 10;
for(int number = 2; number < limit; number++) {
int sum = 1;
for (int factor = 2; factor < number; factor++){
if (number % factor == 0) {
sum += factor;
}
}
if (number >= (sum - badness) && number <= (sum + badness)) {
cout << number << " ";
}
}
return 0;
}
唯一的问题是,这段代码太慢,无法找到高达100万的“非常好”数字。有什么方法可以优化这一点吗?
谢谢你
如果f是n的因子,那么n/f也是(尽管当f是n的平方根时,f和n/f是相同的因子)。因此,您可以通过仅计算因子到sqrt(number)来使代码更快,然后当您找到一个时还包括匹配的因子编号/因子(平方根情况除外)。
for (int factor = 2; factor * factor <= number; factor++){
if (number % factor == 0) {
sum += factor;
if (factor * factor != number) {
sum += number / factor;
}
}
}
如果limit
为100万,并且badness
1,则此代码在我的机器上以1.554s的速度运行。在等待原始代码完成几分钟后,我觉得很无聊。
为了使代码更快,您可以找到数字的质因式分解,并使用基于质因式分解的除数之和公式。
即使不预先计算素数,使用这种方法在我的机器上也能以0.713秒的速度运行。这是我的代码,可以从number
计算sum
:
int n = number;
int i = 2;
while (n > 1) {
if (i * i > n) {
sum *= (n + 1);
break;
}
int pp = i;
while (n % i == 0) {
pp *= i;
n /= i;
}
sum *= (pp - 1) / (i - 1);
i += 1;
}
sum -= number;
它找到所有素数幂,这些素数幂除以number
,并将每个p^m
乘以sum
(p^(m1)-1)/(p-1)。与第一个解决方案一样,当i*i时,它会提前停止
在一般情况下,它比第一个解决方案快得多,因为尽管我们仍在进行试验分割,
n
随着主因子的发现而变小。
如果您已经预计算了一个足够大的素数列表(也就是说,它至少包括一个大于极限平方根的素数),您可以在计算
sum
时再次提高效率:
int n = number;
for (int i = 0; primes[i] * primes[i] <= n; ++i) {
int pp = primes[i];
while (n % primes[i] == 0) {
pp *= primes[i];
n /= primes[i];
}
sum *= (pp - 1) / (primes[i] - 1);
}
if (n > 1) sum *= (n + 1);
sum -= number;
在我的机器上,以这种方式计算总和的代码运行时间为0.189秒。
问题内容: 我在尝试搜索字符串中的子字符串时遇到问题。该子字符串可能在字符串中也可能不在字符串中。 我知道是否可以完成的两种方法是: 正则表达式 但是,还有其他“优化”方式吗?你会怎么做? Ruby可以提供更好的答案吗?由于我们使用jRuby,因此答案可以是Ruby或Java。 问题答案: 在Ruby中,使用方法: 返回。
问题内容: Python方法返回给定对象的元组。有相应的逆函数吗?如果不是,是否有一种简单的方法来计算给定的年份,星期数和星期几? 问题答案: Python 3.8添加了fromisocalendar()方法: Python的3.6添加的,并指示: 原始答案 我最近不得不自己解决此问题,并提出了以下解决方案: 一些测试用例:
问题内容: 我有一个大的,里面有三个little 。它们每个都有33%的宽度,但这会引起一些对齐问题,因为3 * 33%!= 100%。像这样在CSS中代表完美三分之一的最佳方法是什么?也许只有33.33%? 问题答案: 现在,现代浏览器已广泛支持此功能,您可以使用: 或者,如果您的浏览器不支持,可以将其用作备用:
问题内容: 我有一套清单: 我要s1∩s2∩s3 … 我可以编写一个函数来执行一系列成对的操作,等等。 有没有推荐,更好或内置的方法? 问题答案: 从python版本2.6开始,您可以对使用多个参数,例如 如果这些集合在列表中,则表示为: 这里是列表扩展 请注意,是 不是 一个静态的方法,但这种使用功能符号应用第一套交叉口列表的其余部分。因此,如果参数列表为空,则将失败。
当且仅当“字符串中的所有不同字符重复相同次数”时,称字符串为良好字符串。 现在,给定一个长度为n的字符串,我们必须在这个字符串中进行的最小更改次数是多少,这样字符串就变得正常了。 注意:我们只允许使用小写英文字母,我们可以将任何字母更改为任何其他字母。 示例:让String为yyxzzxxx 那么这里的答案是2。 说明:一种可能的解决方案YYXYXX。我们已将2“z”更改为2“y”。现在“x”和“
问题内容: 我正在寻找Java中字符串查找和替换的最佳方法。 这句话是这样的:“我叫米兰,人们把我称为米兰·瓦西奇”。 我想用Milan Vasic代替字符串Milan,但是在我已经拥有Milan Vasic的地方,不应该这样。 搜索/替换后的结果应为:“我叫Milan Vasic,人们称我为Milan Vasic”。 我曾尝试使用indexOf()以及Pattern / Matcher组合,