我会很快进入正题。史密斯数基本上是: 合数,其各位数字之和是它的质因数(不包括 1)的各位数字之和。 (素数被排除在外,因为它们通常满足这个条件)。史密斯数的一个例子是野兽数 666=2·3·3·37,因为 6+6+6=2+3+3+(3+7)=18。
我尝试过:
- 在 for 循环中,我首先获得当前数字的 (i) 位之和
- 在同一个循环中,我尝试获取数字的质因数数字之和。
- 我做了另一种方法来检查 for 循环中要处理的当前数字是否为素数,如果是素数,则将其排除
但是我的代码似乎不起作用,你们能帮忙吗?
public static void main(String[] args) {
smithInrange(1, 50);
}
public static void smithInrange(int start_val, int end_val) {
for (int i = start_val; i < end_val; i++) {
if(!isPrime(i)) { //since we banned prime numbers from this process i don't include them
int for_digit_sum = i, digit = 0, digit_sum = 0, for_factor_purpose = i, smith_sum = 0;
int first = 0, second = 0, last = 0;
// System.out.println("current number is" + i);
while (for_digit_sum > 0) { // in this while loop i get the sum of current number's digits
digit = for_digit_sum % 10;
digit_sum += digit;
for_digit_sum /= 10;
}
// System.out.println("digit sum is"+digit_sum);
while (for_factor_purpose % 2 == 0) { // i divide the current number to 2 until it became an odd number
first += 2;
for_factor_purpose /= 2;
}
// System.out.println("the first sum is " + first);
for (int j = 3; j < Math.sqrt(for_factor_purpose); j += 2) {
while (for_factor_purpose % j == 0) { // this while loop is for getting the digit sum of every prime
// factor that j has
int inner_digit = 0, inner_temp = j, inner_digit_sum = 0;
while (inner_temp > 0) {
inner_digit = inner_temp % 10;
second += inner_digit;
inner_temp /= 10;
}
// System.out.println("the second sum is " + second);
for_factor_purpose /= j;
}
}
int last_temp = for_factor_purpose, last_digit = 0, last_digit_sum = 0;
if (for_factor_purpose > 2) {
while (last_temp > 0) {
last_digit = last_temp % 10;
last += last_digit;
last_temp /= 10;
}
// System.out.println("last is " + last);
}
smith_sum = first + second + last;
// System.out.println("smith num is "+ smith_sum);
// System.out.println(smith_sum);
if (smith_sum == digit_sum) {
System.out.println("the num founded is" + i);
}
}
}
}
public static boolean isPrime(int i) {
int sqrt = (int) Math.sqrt(i) + 1;
for (int k = 2; k < sqrt; k++) {
if (i % k == 0) {
// number is perfectly divisible - no prime
return false;
}
}
return true;
}
输出是: 成立人数为4 成立人数为9 成立人数为22 成立人数为25 成立人数为27 成立人数为49
这个范围(1 和 50)之间的史密斯数是多少: 4、22 和 27
编辑:我发现问题是: Math.sqrt(for_factor_ Purpose) 看来我应该加 1 以消除平方数。感谢你们,我从其他角度看到了解决方案。 继续编码!
最佳答案
打印史密斯数的主循环。
for (int i = 3; i < 10000; i++) {
if (isSmith(i)) {
System.out.println(i + " is a Smith number.");
}
}
确定所提供的数是否为史密斯数的测试方法。仅当最后一个素数的大小小于所测试的数字时,素数列表才会增加。
static boolean isSmith(int v) {
int sum = 0;
int save = v;
int lastPrime = primes.get(primes.size() - 1);
if (lastPrime < v) {
genPrimes(v);
}
outer:
for (int p : primes) {
while (save > 1) {
if (save % p != 0) {
continue outer;
}
sum += sumOfDigits(p);
save /= p;
}
break;
}
return sum == sumOfDigits(v) && !primes.contains(v);
}
对数字的数字求和的帮助方法。
static int sumOfDigits(int i) {
return String.valueOf(i).chars().map(c -> c - '0').sum();
}
还有素数生成器。它使用创建时的列表来确定给定的 数字是素数。
static List<Integer> primes = new ArrayList<>(List.of(2, 3));
static void genPrimes(int max) {
int next = primes.get(primes.size() - 1);
outer:
while (next <= max) {
next += 2;
for (int p : primes) {
if (next % p == 0) {
continue outer;
}
if (p * p > next) {
break;
}
}
primes.add(next);
}
}
}
关于java - 查找给定范围内的史密斯数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59243649/