Java 优化代码以获得给定范围内可被整数整除的整数数

Java 优化代码以获得给定范围内可被整数整除的整数数,java,c++,math,division,Java,C++,Math,Division,给定范围x,y。我需要计算中间的所有数字,它们可以被n整除 我知道一个简单的方法就是在整个范围内循环 for(int i=x;i<=y;i++) if(i%n ==0) counter++; 用于(int i=x;i好吧,我不是大学教授,所以我没有为你保留一些令人惊讶的公式,但就我所知,检查这样一个数字列表的唯一方法是对它们进行迭代,最后你必须计算变量以检查它是否可除,现在有一种方法可以优化你的算法,对数字进行排序rs优先!这最初会很昂贵,但任何后续需要检查的数字都会快得多 我建议看看

给定范围x,y。我需要计算中间的所有数字,它们可以被n整除

我知道一个简单的方法就是在整个范围内循环

for(int i=x;i<=y;i++) if(i%n ==0) counter++; 

用于(int i=x;i好吧,我不是大学教授,所以我没有为你保留一些令人惊讶的公式,但就我所知,检查这样一个数字列表的唯一方法是对它们进行迭代,最后你必须计算变量以检查它是否可除,现在有一种方法可以优化你的算法,对数字进行排序rs优先!这最初会很昂贵,但任何后续需要检查的数字都会快得多

我建议看看排序算法,我会使用气泡排序,这将在谷歌上出现很多

至于排序的方法,你可以将数字排序成倍数列表,例如2 4 6 8都是2的倍数,因此你可以基本上检查列表中的第一个,其余的也可以立即被整除


请记住,也许有一种更有效的方法可以做到这一点,只要给我2美分

我相信你可以做到:

public static int numDivisible(int low, int high, int test) {
    return (high-low)/test;
}
好了。一个恒定时间的解决方案。因为你不需要确切地知道哪些数字是可除的,你不需要费心去迭代所有的数字

编辑:根据@Chaser324将其更改为以下内容

public static float numDivisible(float low, float high, float test) {
    return Math.ceil((high-low)/test);
}

编辑:一个小的输入错误,即将
文本
更改为
测试
,而不是重复每个数字,您可以尝试

public int test(int floor, int ceil, int n) {
    int a = (floor / n) + 1;
    int counter = 0;
    while (a * n <= ceil) {
        counter++;
        a++;
    }
    return counter;
}
公共内部测试(内部楼层、内部天花板、内部n){
int a=(楼层/n)+1;
int计数器=0;
而(a*n这是有效的:
(e+1-s)/d+(e%d<(s+d-1)%d)
(它使用C语义和整数算术,并假设起始值是非负的。s是起始值,e是结束值[含],d是除数。)

更新:更好的解决方案是
e/d-(s-1)/d
。这是受User448810启发的。这要求s为正;处理零或负s(或e)需要调整为向零的截断(我们希望此问题朝负无穷大)


负值更新:如果s您要求计算x和y之间的整数数量(x和y都包括在该范围内),则以下操作适用于s和e类型范围内的任何值n是可分割的,不需要任何循环,只有两个分区来计算答案。让我们考虑一个简单的例子:对于范围100到200,有多少个整数可以被7整除?

从范围的低端开始:100/7=14,余数为2。现在除数7减去余数2等于5,因此范围内可被7整除的最小数字为100+5=105

现在转到范围的高端:200/7=28,余数为4,因此范围中可被7整除的最大数字是200-4=196


因此,可以被7整除的范围上的数字是105、112、119、126、133、140、147、154、161、168、175、182、189和196。其中有14个,可以用几种方法计算。取两端的商并减去它们:28-14=14。或者取两个端点的差,除以除数,然后加1:196-105=91,91/7=13,13+1=14。但是当其中一个端点可以被除数整除时,要小心;我将让您来计算细节,并编写程序。

请提供下面关于算法的注释:假设范围是[R1,R2],要除数是n

找到从R1开始可被n整除的最小数字。称之为小

从R2除以n开始找出最大的数。称之为大数

可整除的总数=(大/小)/n+1

最坏的情况仍然是O(n),但对于R1和R2之间的较大差异可能是有效的。希望我已经涵盖了所有情况。请建议

int numofDivisible(int R1, int R2, int n) {

int small = R1, large= R2;

if ((R1 > R2) || (n==0)) return 0;

if (R1 == R2) {
    if (R1 % n == 0) 
        return 1;
    else 
        return 0;
}

while(small <= R2){

     if(small % n == 0)
         break;

      ++small;
}

if (small > R2)
    return 0;


while (large > small) {

    if (large % n == 0)
       break;

    --large;
}

if (large == small)
   return 1;

return ((large-small)/n + 1);

}
int numfodivisible(int R1,int R2,int n){
小整数=R1,大整数=R2;
如果((R1>R2)|(n==0))返回0;
如果(R1==R2){
如果(R1%n==0)
返回1;
其他的
返回0;
}
而(小R2)
返回0;
while(大>小){
如果(大%n==0)
打破
--大的;
}
如果(大==小)
返回1;
返回((大/小)/n+1);
}
说明:

有一些a/d数可以从0到a被d整除。(d!=0)

因此(floor)(high/d)-(floor)(low/d)将给出可在该范围内整除的数字(low,high)(注意,此范围不包括low,而包括high)

现在要从范围中删除high,只需减去(high%d==0)


将fmodf用于浮点数。

只有此实现对我有效(A,B在[0..2kkk]中;K在[1..2kkk]中):

函数解(A、B、K){
如果(B
您认为对数字进行排序有助于解决这个问题吗?您首先对数字进行排序,测试第一个元素。然后,下一个可分割的元素都是当前的+N。类似于此。从那里您可以获得这些数字,或者只需计数而不需要迭代:)抱歉,我实际上增加了一点以提高精度。我仍然不知道排序有什么帮助。最优化的算法根本不使用迭代,但迭代算法是从排序集开始的
R1,R1+1,R1+2,…,R2-2,R2-1,R2
。你在排序什么?我一定误解了OP的意图,我是在印象中,他有一个数字列表,他需要检查一个可以被一个数字整除的范围,通过将这个列表排序为可以被这个数字整除的子列表,他可以检查第一个
public static int solution(int low,int high, int n) {
    boolean h0=high%n==0;
    boolean l0=low%n==0;

    int k1=l0?low/n:(low+n-low%n)/n;
    int k2=h0?high/n:(high+n-high%n)/n;

    //                 |-----------|
    // ---------------k1----------k2---------------

    if(k2*n>high) k2--;

    return k2-k1+1;

}
int numofDivisible(int R1, int R2, int n) {

int small = R1, large= R2;

if ((R1 > R2) || (n==0)) return 0;

if (R1 == R2) {
    if (R1 % n == 0) 
        return 1;
    else 
        return 0;
}

while(small <= R2){

     if(small % n == 0)
         break;

      ++small;
}

if (small > R2)
    return 0;


while (large > small) {

    if (large % n == 0)
       break;

    --large;
}

if (large == small)
   return 1;

return ((large-small)/n + 1);

}
 public int myfunc(int low, int high, int test) {   
    int count = 0;
    if(low % test == 0)
       count++;
    count +=(high-low)/test;
    return count;
 }
(floor)(high/d) - (floor)(low/d) - (high%d==0)
function solution(A, B, K) {
    if(B < K) return A === 0 ? 1 : 0;
    if(A === B) return A % K === 0 ? 1 : 0;

    var pre = A === 0 ? 2 : 1;
    var min = A < K ? K : A + A % K;
    var max = B - B % K;

    return (max - min) / K + pre;
}