大哥 教教小弟我吧 1+2+3+4......+n<8888求N用JAVA来编.我真整不会了.

解决方案 »

  1.   

    求和公式 (n^2+n)<8888*2public class Logic {
     public static void main(String[] args) {
       int i = 0;
       for (; i < 8888; i++) {
         if ((i^2+i) >= 8888 * 2)
           break;
       }
       System.out.println("你要的n:=" + (i-1));
     }
    }简单实现
      

  2.   

    求和公式   (n^2+n) <8888*2 public   class   Logic   { 
      public   static   void   main(String[]   args)   { 
          int   i   =   0; 
          while((i^2+i)   <   8888   *   2){
           i++;
          } 
          System.out.println("你要的n:="   +   (i-1)); 
      } 
    } 简单实现
      

  3.   

    等差数列求和公式:S[n]=S[n-1]+a[n]public class Sum{
       public static void main(String args[]){
          int a1=1,d=1,an=0,Sn=0,n=0;
          for(n=1;;n++){
             an=a1+n*d;
             Sn=Sn+an;
             if(Sn>8888)
               break;
          }
          System.out.println("n="+(n-1));
       }
    }
      

  4.   

    写错了一点public class Sum{
       public static void main(String args[]){
          int a1=1,d=1,an=0,Sn=0,n=0;
          for(n=1;;n++){
             an=a1+(n-1)*d;
             Sn=Sn+an;
             System.out.println(n+":"+Sn);
             if(Sn>8888)
               break;
          }
          System.out.println("n="+(n-1));
       }
    }
      

  5.   

    都有点舍近求远呀~
    加法的效率比乘法和平方高多了~
    干嘛放着简单的高效方法不用呢~int sum = 0;
    int n = 1;
    while(true){
      sum += n;
      if (sum >= 8888){
        break;
      }
      n ++;
    }
    System.out.println("N = " + n);
      

  6.   

    n^2就是n的平方,n^3就是n的三次方.
      

  7.   

    嗯?怎么同一个问题发了两贴?下面的算法简单高效:
    return Math.floor((Math.floor(Math.sqrt(1 + 8 * 8888)) - 1) / 2);^表示乘方是VB的语法吧?Java中用Math.pow()。
      

  8.   

    "^"这个是二进制位运算符.是按位异或(XOR).举个例子:
     00101010    42
    ^00001111    15
    -----------
     00100101    37
      

  9.   

    ^在java中是异或,但是1#的把它当作平方用了~
      

  10.   

    是的,一下给搞糊涂了,因为知道求和公式是:sum=(n+1)*n/2,所以以为是平方了,差点要误导了.
      

  11.   

    10#算法也不是高效算法,用了取整、开方、乘法,这能高效的了吗~~
    你可以看看操作系统和计算机原理,了解一下什么样的运算才是高效的~计算机的高效算法就是加减法(+-)和移位(<<、>>、>>>)是效率最高的~
    for循环也是高效的,因为计算机的简单计数是硬件(计数器)直接实现的~
      

  12.   

    public class Sum{
       public static void main(String args[]){
          int sum=0;
          int n=1;
          do{
           n++;
           //sum=(n+1)*n/2;  //这个也能用,2个选1
           sum=(int)(Math.pow(n,2)+n)/2;//这个是用平方的
          }while(sum<8888);
          
          System.out.println("n="+(n-1));
       }
    }
      

  13.   

    to 14楼:算法的效率要结合问题规模来分析,“for循环也是高效的”,这句话就很武断。单层for循环的效率是O(n),执行时间是随着n的规模线性增长的。
    Math.sqrt()是一个本地方法,相信效率不会低到哪里去,开方运算如果用牛顿迭代法,效率至少要高于O(n)。我分别用循环和开平方算法测试了楼主的问题,在我的电脑上,当S=8888时看不出差别,但是,当我用S=Long.MaxValue分别测试,循环方法将近30秒才给出结果,而我的算法时间依然不到半秒。可知Math.sqrt()的效率不低。
      

  14.   

    嗯,^用的语言多了,没去ide检查就出错了``
      

  15.   

    晕,30秒,好慢啊。
    还有用pow(n, 2)的兄弟, 你直接用n * n不就得了 这个问题显然用 牛顿迭代法更快,要相信数学的力量。PS:
    GBBasic,QB,VB中  ^表示乘方,Basic语系基本都是这样的。
    很多语言用 **来表示乘方,比如Ruby。
    ^在Pascal中是 指针指示。在C类语法(includeing C/C++/Java/C#)中表示位运算。
      

  16.   

    to Dan1980 :
    给你完整的测试代码和测试结果,不知道你用什么电脑跑的测试,竟然用30秒~~~~
    你从结果也可以看到哪种算法好坏来了~那个用floor等一系列函数的我没用最大值,没看出来为什么用8~~~
    public static void main(String[] args) {
    int max = Integer.MAX_VALUE-1000;
    long t1 = System.currentTimeMillis();
    int sum = 0,i = 1;
    for (i = 1; ; i ++){
    sum += i;
    if (sum >= max){
    break;
    }
    }
    System.out.println("N = " + i);
    long t2 = System.currentTimeMillis();
    System.out.println("第一次使用时间 t1 = " + (t2-t1) + "毫秒");

    long t3 = System.currentTimeMillis();
    sum = 0;
    i = 1;
    while(true){
    sum += i;
    if (sum >= max){
    break;
    }
    i ++;
    }
    System.out.println("N = " + i);
    long t4 = System.currentTimeMillis();
    System.out.println("第二次使用时间 t2 = " + (t4-t3) + "毫秒");
    }
    第1次测试结果:
    N = 5004393
    第一次使用时间 t1 = 15毫秒
    N = 5004393
    第二次使用时间 t2 = 0毫秒
    第2次测试结果:
    N = 5004393
    第一次使用时间 t1 = 16毫秒
    N = 5004393
    第二次使用时间 t2 = 0毫秒
    第3次测试结果:
    N = 5004393
    第一次使用时间 t1 = 15毫秒
    N = 5004393
    第二次使用时间 t2 = 0毫秒
    第4次测试结果:
    N = 5004393
    第一次使用时间 t1 = 16毫秒
    N = 5004393
    第二次使用时间 t2 = 0毫秒
    第5次测试结果:
    N = 5004393
    第一次使用时间 t1 = 16毫秒
    N = 5004393
    第二次使用时间 t2 = 0毫秒哪一次测试时间也没超过20毫秒,我不知道你的30秒是用什么电脑测出来的~
    对于return Math.floor((Math.floor(Math.sqrt(1 + 8 * max)) - 1) / 2);
    我不知道你怎么额出来的结果:
    当max接近Integer.MAX_VALUE,很明显8 * max已经溢出了,已经严重出错了,那你还怎么测呢~~
    多多考虑些因素,不是脑袋一热就能想完美的~
      

  17.   

    上面的算法还是有可能溢出,看看下面改进的结果:int max = Integer.MAX_VALUE;
    for (int n = 0; n < 5; n ++){
    System.out.println("第" + (n+1) + "次测试结果:");

    long t1 = System.currentTimeMillis();
    int sum = 0,i = 1;
    for (i = 1; ; i ++){
    sum += i;
    if (sum >= max || Integer.MAX_VALUE-sum < i){
    break;
    }
    }
    System.out.println("N = " + i);
    long t2 = System.currentTimeMillis();
    System.out.println("第一次使用时间 t1 = " + (t2-t1) + "毫秒");

    long t3 = System.currentTimeMillis();
    sum = 0;
    i = 1;
    while(true){
    sum += i;
    if (sum >= max || Integer.MAX_VALUE-sum < i){
    break;
    }
    i ++;
    }
    System.out.println("N = " + i);
    long t4 = System.currentTimeMillis();
    System.out.println("第二次使用时间 t2 = " + (t4-t3) + "毫秒");
    }
    }
    测试结果:
    第1次测试结果:
    N = 65535
    第一次使用时间 t1 = 0毫秒
    N = 65535
    第二次使用时间 t2 = 0毫秒第2次测试结果:
    N = 65535
    第一次使用时间 t1 = 0毫秒
    N = 65535
    第二次使用时间 t2 = 0毫秒第3次测试结果:
    N = 65535
    第一次使用时间 t1 = 0毫秒
    N = 65535
    第二次使用时间 t2 = 0毫秒第4次测试结果:
    N = 65535
    第一次使用时间 t1 = 0毫秒
    N = 65535
    第二次使用时间 t2 = 0毫秒第5次测试结果:
    N = 65535
    第一次使用时间 t1 = 0毫秒
    N = 65535
    第二次使用时间 t2 = 0毫秒第6次测试结果:
    N = 65535
    第一次使用时间 t1 = 0毫秒
    N = 65535
    第二次使用时间 t2 = 0毫秒第7次测试结果:
    N = 65535
    第一次使用时间 t1 = 0毫秒
    N = 65535
    第二次使用时间 t2 = 0毫秒第8次测试结果:
    N = 65535
    第一次使用时间 t1 = 0毫秒
    N = 65535
    第二次使用时间 t2 = 0毫秒第9次测试结果:
    N = 65535
    第一次使用时间 t1 = 0毫秒
    N = 65535
    第二次使用时间 t2 = 0毫秒第10次测试结果:
    N = 65535
    第一次使用时间 t1 = 0毫秒
    N = 65535
    第二次使用时间 t2 = 0毫秒
      

  18.   

    哇靠  一堆变态男,里面应该没有变态女吧!真是猛呀!看了你们的回帖我真是服了,佩服你们的专业精神呀!另人汗颜的看来我还有好多路要走~哭ing   
      

  19.   

    to daniel_kaka:请看清楚,我用的是Long.MAX_VALUE,不是Integer.MAX_VALUE,程序中的int我也都相应改成double了,Math.sqrt()本来就返回double,所以无需修改。
      

  20.   

    我的完整测试程序如下,两者效率简直天壤之别,请大家自己运行:public class Test {
    public static void main(String[] args) {
    double timeStart, timeEnd; /* 使用循环 */
    timeStart = System.currentTimeMillis();
    System.out.println(maxLoop(Long.MAX_VALUE));
    timeEnd = System.currentTimeMillis();
    System.out.println("使用循环耗时:" + (timeEnd - timeStart) + " ms"); /* 使用Math.sqrt()方法 */
    timeStart = System.currentTimeMillis();
    System.out.println(maxSQRT(Long.MAX_VALUE));
    timeEnd = System.currentTimeMillis();
    System.out.println("使用Math.sqrt()耗时:" + (timeEnd - timeStart) + " ms"); } static double maxLoop(double s) {
    double i = 0;
    for (; i < s; i++)
    if ((i * i + i) >= s * 2)
    break;
    return i-1;
    } static double maxSQRT(double s) {
    return Math.floor((Math.floor(Math.sqrt(1 + 8 * s)) - 1) / 2);
    }
    }测试结果:
    4.294967295E9
    使用循环耗时:27922.0 ms
    4.294967295E9
    使用Math.sqrt()耗时:0.0 ms
      

  21.   

    下午没仔细看daniel_kaka高人的回帖,刚刚仔细看了一下,果然不是一般的强,我严重无语……把我的Long.MAX_VALUE错看成Integer.MAX_VALUE也就罢了,看了下面的话我发现我简直和你没有共同语言了。----------------------------
    对于return   Math.floor((Math.floor(Math.sqrt(1   +   8   *   max))   -   1)   /   2); 
    我不知道你怎么额出来的结果: 
    当max接近Integer.MAX_VALUE,很明显8   *   max已经溢出了,已经严重出错了,那你还怎么测呢~~ 
    多多考虑些因素,不是脑袋一热就能想完美的~
    ----------------------------拜托老兄你有空看看api,Math.sqrt()的参数类型是double,1+8*max的值会自动提升为double,无论如何也不存在所谓的溢出问题。还有奉劝一定要相信api,api可以说是精英智慧的结晶,难不成你求平方根也要去用循环穷举?再奉劝凡事不要过于自信,学了几天原理没什么值得摆谱的,谁都知道计算机做加减、移位效率最高,学点算法基础再来摆谱吧(不过相信到时你会摆得更厉害了,哈哈)。不好意思,我心情激动,言辞过激,抱歉。
      

  22.   

    Dan1980 果然是太激动了
    你给出的代码在后,人家评论在前,怎么就说人家说错了呢,只在没了解你怎么用的Long.MAX_VALUE/Integer.MAX_VALUE罢了
    1+8 * Long.MAX_VALUE确实是溢出的啊
    它不同于:
    1+8*changeType(Long.MAX_VALUE)。我并不是说那样会很快,但你这个方法是用人脑做了部分工作得来的。
    就好像你问一个小学生从1加到100结果是多少,他老老实实的一个一个加出来得5050;
    而一个中学生就会(1+100)*100/2也得到5050。
    很明显中学生效率高,但却需要一定的数学知识才可理解。小学生高明不高明也不是一棒子打死的,至少他最接近本来的需求,易懂,而且在规模比较小的时候会快些
    另外,你在循环的方法中每次都乘一下来代替原来的方法,自然要更慢............
      

  23.   


    既然ls提出来了,我想有必要说一点,本来是不打算说的,没必要计较~从static double maxSQRT(double s) {
      return Math.floor((Math.floor(Math.sqrt(1 + 8 * s)) - 1) / 2);
    }
    到System.out.println(maxSQRT(Long.MAX_VALUE));根本就是不等价转化,
    从人脑的考虑没错,但从计算机角度考虑就存在问题~都知道
    maxLong = 9223372036854775807
    maxDouble = 1.7976931348623157E308
    也就是,
    Long.MAX_VALUE=9223372036854775807,19位长度
    Double.MAX_VALUE=1.7976931348623157E308是18位小数,
    看起来没什么问题~其实不然:
    maxLong2Double=9.223372036854776E18
    浮点数的小数点部分真正精确位其实只有15位
    也就是Long.MAX_VALUE转化为double时根本就不等价~所以虽然结果是正确的,但是方法根本就不对~
    有时间还是多看看计算机基础的书吧,充充电~
    软件的基础还是计算机,不要忘本~