我写了一个简单的程序来计算可以对一个数字求平方根的最大次数,输入的是从num1到num2的间隔 例如: 如果输入为(1,20),则答案为2,因为16的平方根是4,而4的平方根是2。
int max = 0;
for (int i = num1; i <= num2; i++) {
boolean loop = true;
int count = 0;
int current = i;
if (i == 1) {
count++;
} else {
while (loop) {
double squareRoot = Math.sqrt(current);
if (isCurrentNumberPerfectSquare(squareRoot)) {
count++;
current = (int) squareRoot;
} else {
loop = false;
}
}
}
if (count > max) {
max = count;
}
}
return max;
static boolean isCurrentNumberPerfectSquare(double number) {
return ((number - floor(number)) == 0);
}
我得到了答案,但是想知道是否可以使用一些数学方法来改善这一点? 有什么建议吗?
答案 0 :(得分:0)
编辑-我的假设不正确。请参阅“第二”提供的答案。
您可以删除外部循环,可以直接使用num2确定具有最大递归平方根数的数字。
requiredNumber = square(floor(sqrt(num2)));
找到后,您只需要检查requiredNumber是否存在于[num1,num2]范围内即可。
所以重构代码看起来像这样,
int requiredNumber = Math.pow(floor(Math.sqrt(num2)),2);
int numberOfTimes=0;
if(requiredNumber>=num1) {
if (requiredNumber == 1) {
numberOfTimes=1;
} else{
while (isCurrentNumberPerfectSquare(requiredNumber)) {
numberOfTimes++;
}
}
}
答案 1 :(得分:0)
编辑4:对于更优化的方法,请检查我的其他答案。 如果有人想遵循我的思考过程,我就把这留在这里;)
编辑3: 使用质数是错误的,请改用最低非理想平方 范例[35,37]
编辑2: 现在,我想到了一种更好的方法,特别是如果您假设num1和num2覆盖更大的范围。
以最低的素数“非完美平方”开头,
计算适合您范围的最大完美平方。
如果找到一个,就完成了。
如果没有,请继续下一个素数“非完美平方”。
作为一个在较小范围内效果很好的示例:
我认为您可以改善外循环。无需测试每个数字。
如果知道最小的理想平方,则可以继续执行序列中的下一个理想平方。
例如: [16,26]
16 -> 4 -> 2 ==> 2 perfect squares
No neeed to test 17 to 24
25 -> 5 ==> 1 perfect square
以此类推...
@Chrisvin Jem 您的假设不正确,请参见上面的示例
编辑: 添加了一些代码
static int countPerfectSquares(int current) {
int count = 0;
while (true) {
double squareRoot = Math.sqrt(current);
if (isCurrentNumberPerfectSquare(squareRoot)) {
count++;
current = (int) squareRoot;
} else {
return count;
}
}
}
static boolean isCurrentNumberPerfectSquare(double number) {
return ((number - Math.floor(number)) == 0);
}
static int numPerfectSquares(int num1, int num2) {
int max = 0;
if (num1 == 1) {
max = 1;
}
int sqr = Math.max(2, (int) Math.floor(Math.sqrt(num1)));
int current = (int) Math.pow(sqr, 2);
if (current < num1) {
current = (int) Math.pow(++sqr, 2);
}
while (current <= num2) {
max = Math.max(countPerfectSquares(current), max);
current = (int) Math.pow(++sqr, 2);
}
return max;
}
答案 2 :(得分:0)
在这里,为了避免更多的困惑,我对这个主题的最终回答。 两种上述方法的组合。
“ Parameswar”正在寻找的是由最低底数组成的最大的完美正方形。
Step 1 -
To get that calculate the largest possible perfect square based on your num2 value.
If it is outside your range, you have no perfect square within.
Step 2 -
If it is within your range, you have to check all perfect square formed by a lower base value with a higher number of times.
Step 3 -
If you find one that is within your range, replace your result with the new result and proceed to check lower values. (go back to Step 2)
Step 4 -
Once the value you check is <= 2 you have already found the answer.
这里有一些示例实现:
static class Result {
int base;
int times;
}
static boolean isCurrentNumberPerfectSquare(double number) {
return ((number - Math.floor(number)) == 0);
}
private static int perfectSquare(int base, int times) {
int value = base;
for (int i = times; i > 0; i--) {
value = (int) Math.pow(base, 2);
}
return value;
}
private static Result calculatePerfectSquare(int perfectSquare) {
Result result = new Result();
result.base = (int) Math.sqrt(perfectSquare);
result.times = 1;
while (result.base > 2 && isCurrentNumberPerfectSquare(Math.sqrt(result.base))) {
result.base = (int) Math.sqrt(result.base);
result.times += 1;
}
System.out.println(perfectSquare + " -> " + result.base + " ^ " + result.times);
return result;
}
static int maxPerfectSquares(int num1, int num2) {
int largestPerfectSqr = (int) Math.pow(Math.floor(Math.sqrt(num2)), 2);
if (largestPerfectSqr < num1) {
return 0;
}
Result result = calculatePerfectSquare(largestPerfectSqr);
int currentValue = result.base;
while (currentValue > 2) {
// check lower based values
currentValue--;
int newValue = perfectSquare(currentValue, result.times + 1);
if (newValue >= num1 && newValue < num2) {
result = calculatePerfectSquare(newValue);
currentValue = result.base;
}
}
return result.times;
}