import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
/*有一个整数n,写一个函数f(n),返回0到n之间出现的"1"的个数。比如f(13)=6,现在f(1)=1,问有哪些n能满足f(n)=n? 例如:f(13)=6, 因为1,2,3,4,5,6,7,8,9,10,11,12,13.数数1的个数,正好是6.*/
public class CountNumber {

public static void main(String[] args) {
Date now = new Date();
DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.CHINA);
String time =fmt.format(now);
System.out.println(time);
System.out.println(CountNumber.countOne(1111111111));
now = new Date();
time =fmt.format(now);
System.out.println(time);
}
    
/*计算单1个个数的方法*/
public static int countOne(int number){
int countone = 0;                        //记录单个1的数组
if(number <= 0){                         //不合理情况,去掉
return -1;
}else if(number<=9){                     //个位数,肯定有有且只有一个
return 1;
}else if(number==10){                    //特殊情况2个
return 2;
}else{                                   //正常情况,从11开始计数
for(int i=11;i<=number;i++){
countone+=CountNumber.countANumber(i);
}
return countone+2;
}
} /*计算单个数1个数的函数*/
private static int countANumber(int number) {
int count=0;                                 //计数器
int flag = 1;                                //用作检测数
while((number-flag)>=0){
if((number-flag)%(flag*10)==0){
count++;
}
flag = flag*10;
number = number-number%flag;
}
return count;
}

}以前在论坛上面看到的编程之美的题目。结果我按自己写的方法写了一个方法,结果发觉速度好慢。难道全部用基本类型,速度反而会慢?

解决方案 »

  1.   


    public class Demo{
        public int countOne(int max){
    int count=0;  //用来计数
    for(int i=1;i<=max;i++){
        char[] c=String.valueOf(i).toCharArray();  //把每个数都拆成一个字符数组
        for(int j=0;j<c.length;j++){
    if(c[j]=='1')  //检查这个数组中含有'1'的个数
        count++;
        }
    }
    return count;
        }
        public static void main(String[] args){
    int n=new Demo().countOne(13);
    System.out.println(n);  //结果是:6
        }
    }
      

  2.   

    满足f(n)=n :public class Demo{
    public void countOne(int max){  //计算并输出从1到max中,所有满足countOne(n)=n的数
    int count=0;  //用来计数
    for(int i=1;i<=max;i++){
    char[] c=String.valueOf(i).toCharArray();  //把每个数都拆成一个字符数组
    for(int j=0;j<c.length;j++){
    if(c[j]=='1')  //检查这个数组中含有'1'的个数
    count++;
    }
    if(count==i)
    System.out.println(i);
    count=0;  //还原count,准备检测下一个数
    }
    }
    public static void main(String[] args){
    new Demo().countOne(13);  //结果:1
    }
    }
    具体有哪些数是满足条件的,还没有作进一步的测试,好像这样的数很少
      

  3.   

    有谁验证一下结果
    /**
     * 
     */
    package test;/**
     * @author - yy
     * @time   - Dec 1, 2008 9:30:40 AM
     */
    public class Demo {
      
      public int count1(int max) {   // 2楼的程序
        int count = 0; //用来计数
        for (int i = 1; i <= max; i++) {
          char[] c = String.valueOf(i).toCharArray(); //把每个数都拆成一个字符数组
          for (int j = 0; j < c.length; j++) {
            if (c[j] == '1') //检查这个数组中含有'1'的个数
              count++;
          }
        }
        return count;
      }
      
      public int countLess_1e2(int max) {
        if (max == 0) {
          return 0;
        }
        int count = 0;
        int quotient = max / 10;
        int remainder = max % 10;
        switch (quotient) {
          case 1:
            if (remainder == 0) {
              count = 2;
            } else {
              count = 3 + remainder;
            }
            break;
          case 0:
            count = 1;
            break;
          default:
            if (remainder == 0) {
              count = 10 + quotient;
            } else {
              count = 11 + quotient;
            }
            break;
          
        }
        return count;
      }
      
      public int countLess_1e3(int max) {
        int count = 0;
        int quotient = max / 100;
        int remainder = max % 100;
        switch (quotient) {
          case 1:
            if (remainder == 0) {
              count = 21;
            } else {
              count = 21 + remainder + this.countLess_1e2(remainder);
            }
            break;
          case 0:
            count = this.countLess_1e2(remainder);
            break;
          default:
            count = 100 + quotient * 20 + this.countLess_1e2(remainder);
            break;
        }
        return count;
      }
      
      public int countLess_1e4(int max) {
        int count = 0;
        int quotient = max / 1000;
        int remainder = max % 1000;
        switch (quotient) {
          case 1:
            if (remainder == 0) {
              count = 301;
            } else {
              count = 301 + remainder + this.countLess_1e3(remainder);
            }
            break;
          case 0:
            count = this.countLess_1e3(remainder);
            break;
          default:
            count = 1000 + quotient * 300 + this.countLess_1e3(remainder);
            break;
        }
        return count;
      }
      
      public int countLess_1e5(int max) {
        int count = 0;
        int quotient = max / 10000;
        int remainder = max % 10000;
        switch (quotient) {
          case 1:
            if (remainder == 0) {
              count = 4001;
            } else {
              count = 4001 + remainder + this.countLess_1e4(remainder);
            }
            break;
          case 0:
            count = this.countLess_1e4(remainder);
            break;
          default:
            count = 10000 + quotient * 4000 + this.countLess_1e4(remainder);
            break;
        }
        return count;
      }
      
      public int countLess_1e6(int max) {
        int count = 0;
        int quotient = max / 100000;
        int remainder = max % 100000;
        switch (quotient) {
          case 1:
            if (remainder == 0) {
              count = 50001;
            } else {
              count = 50001 + remainder + this.countLess_1e5(remainder);
            }
            break;
          case 0:
            count = this.countLess_1e5(remainder);
            break;
          default:
            count = 100000 + quotient * 50000 + this.countLess_1e5(remainder);
            break;
        }
        return count;
      }
      
      public int countLess_1e7(int max) {
        int count = 0;
        int quotient = max / 1000000;
        int remainder = max % 1000000;
        switch (quotient) {
          case 1:
            if (remainder == 0) {
              count = 600001;
            } else {
              count = 600001 + remainder + this.countLess_1e6(remainder);
            }
            break;
          case 0:
            count = this.countLess_1e6(remainder);
            break;
          default:
            count = 1000000 + quotient * 600000 + this.countLess_1e6(remainder);
            break;
        }
        return count;
      }
      
      public int countLess_1e8(int max) {
        int count = 0;
        int quotient = max / 10000000;
        int remainder = max % 10000000;
        switch (quotient) {
          case 1:
            if (remainder == 0) {
              count = 7000001;
            } else {
              count = 7000001 + remainder + this.countLess_1e7(remainder);
            }
            break;
          case 0:
            count = this.countLess_1e7(remainder);
            break;
          default:
            count = 10000000 + quotient * 7000000 + this.countLess_1e7(remainder);
            break;
        }
        return count;
      }
      
      public int countLess_1e9(int max) {
        int count = 0;
        int quotient = max / 100000000;
        int remainder = max % 100000000;
        switch (quotient) {
          case 1:
            if (remainder == 0) {
              count = 80000001;
            } else {
              count = 80000001 + remainder + this.countLess_1e8(remainder);
            }
            break;
          case 0:
            count = this.countLess_1e8(remainder);
            break;
          default:
            count = 100000000 + quotient * 80000000 + this.countLess_1e8(remainder);
            break;
        }
        return count;
      }
      
      public int countLess_1e10(int max) {
        int count = 0;
        int quotient = max / 1000000000;
        int remainder = max % 1000000000;
        switch (quotient) {
          case 1:
            if (remainder == 0) {
              count = 90000001;
            } else {
              count = 90000001 + remainder + this.countLess_1e9(remainder);
            }
            break;
          case 0:
            count = this.countLess_1e9(remainder);
            break;
          default:
            count = 1000000000 + quotient * 90000000 + this.countLess_1e9(remainder);
            break;
        }
        return count;
      }
      
      public static void main(String[] args) {
        Demo demo = new Demo();
        long s = System.currentTimeMillis();
        System.out.println();
        //System.out.println(demo.count1(Integer.MAX_VALUE)); 有谁验证一下结果
        System.out.println(demo.countLess_1e10(Integer.MAX_VALUE));
        System.out.println(Integer.MAX_VALUE);
        System.out.println(System.currentTimeMillis() - s);
      }
    }
      

  4.   


      没看过编程之美,这是我总结采用数学归纳总结的, 
      看了10楼说得,特地下了编程之美看了看,
      发现自己的效率比编程之美的还要高.
      上面的算法我只测试到10^8,后面的没验证,因为后面的验证好慢,
      我的算法几乎都是0毫秒,无论多大的数.
    public static void main(String[] args) {
      Demo demo = new Demo();
      long start = System.currentTimeMillis();
      //System.out.println(demo.countLess_1e10(100000000)); // 编程之美说要40多秒,我的几乎只要0毫秒
      System.out.println(demo.countLess_1e10(1111111111));
      long end = System.currentTimeMillis() ;
      System.out.println("计算时间: "+(end - start)+" 毫秒");
      // 输出结果是:
      // 1111111120
      // 计算时间: 0 毫秒
    }
    另外,测出了所有满足f(n)=n的数,共耗时8分22秒(502969毫秒) [cpu 2.0GHz,双核, 2G内存]
    这是循环计算出来的
    运行结果

      for (int i = s; i < Integer.MAX_VALUE; i++) {
        int n2 = demo.countLess_1e10(i);
        if (i == n2) {
          System.out.println(n2);
        }
       }
    //输出满足的数:
    // 0
    // 1
    // 199981
    // 199982
    // 199983
    // 199984
    // 199985
    // 199986
    // 199987
    // 199988
    // 199989
    // 199990
    // 200000
    // 200001
    // 1599981
    // 1599982
    // 1599983
    // 1599984
    // 1599985
    // 1599986
    // 1599987
    // 1599988
    // 1599989
    // 1599990
    // 2600000
    // 2600001
    // 13199998
    // 35000000
    // 35000001
    // 35199981
    // 35199982
    // 35199983
    // 35199984
    // 35199985
    // 35199986
    // 35199987
    // 35199988
    // 35199989
    // 35199990
    // 35200000
    // 35200001
    // 117463825
    // 500000000
    // 500000001
    // 500199981
    // 500199982
    // 500199983
    // 500199984
    // 500199985
    // 500199986
    // 500199987
    // 500199988
    // 500199989
    // 500199990
    // 500200000
    // 500200001
    // 501599981
    // 501599982
    // 501599983
    // 501599984
    // 501599985
    // 501599986
    // 501599987
    // 501599988
    // 501599989
    // 501599990
    // 502600000
    // 502600001
    // 513199998
    // 535000000
    // 535000001
    // 535199981
    // 535199982
    // 535199983
    // 535199984
    // 535199985
    // 535199986
    // 535199987
    // 535199988
    // 535199989
    // 535199990
    // 535200000
    // 535200001
    // 1111111110
    // 计算时间: 502969 毫秒