1. 如何将整形数转化到对应的字节数组中。
都知道字节是8位的,而Java中整形,也就是int型的变量是32位的,因此这个”对应“也就是要保存到长度为4的字节数组中。那么下面来考虑如何转换。看代码:
public class IntToByte {
public static void main(String args[]){
int a = 1000;
byte[] byteArray = new byte[4];
for (int i=0; i<4; i++){
byteArray[i] = new Integer(a & 0xFF).byteValue();
a >>= 8;
System.out.println(byteArray[i]);
}
}
}
2. 有一个整数n,写一个函数f(n),返回0到n之间出现的"1"的个数。 如f(13)=6, 因为1,2,3,4,5,6,7,8,9,10,11,12,13.数数1的个数,正好是6.
当然了,我想看到这个问题的时候,大家第一反应肯定是用replaceAll()这个方法,但是代码写出来后,测试一下,你会发现当n=100w的时候,速度就有点跟不上了,因为实现replaceAll()方法的时候,也必不可少的牵扯都遍历匹配和字符串的连接。这个时候就要去寻找一种相对高效的方法。
一种办法就是用数学的办法,试图推导出一个关系式,来计算这个函数。这里我贴出一个网友的解法和代码:
对于N=10^n-1 (0、9、99、999……)来说
设F(n)=f(10^n-1)
F(n)=A(n)+B(n)
A(n)表示由最高位带来的1的个数
B(n)表示由非最高位带来的1的个数
那么,易得A(n)=10^n,
B(n)=10*F(n-1) (n>0)
B(0)=0
综上所述,F(n)=F(n-1)+10^n=n*10^(n-1)
而对任意正整数N=a*10^n+b
其中a为N的最高位数(1-9)
那么,f(N)中由最高位带来的1的个数C(N)=a>1 ? 10^n : b+1
而非最高位来带的1的个数D(N)=f(b)+a*F(n)
其中f(b)为[a*10^n,a*10^n+b]中的个数
aF(n)为[0,a*10^n]中的个数
所以,f(N)=f(b)+aF(n)+(a>1 ? 10^n : b+1)
=f(b)+an*10^(n-1) + (a>1 ? 10^n : b+1)
代码:
public class GoogleTest {
private static final int[] tenSqr = new int[]{1, 10, 100, 1000, 10000, 100000, 1000000, 10000000};
// 获取a的位数
private static int get_n(int a){
int n = 0;
while (tenSqr[n] <= a) n++;
return n-1;
}
private static int f(int N){
if (N == 0)
return 0;
else if (N < 10)
return 1;
int n = get_n(N);
int a = N / tenSqr[n];
int b = N % tenSqr[n];
return f(b) + a * n * tenSqr[n-1] + (a > 1 ? tenSqr[n] : b+1);
}
public static void main(String[] args) {
for (int i = 1; i < 1000; ++i)
System.out.println("f(" + i + ")=" + f(i));
}
}
这种解法最直接的好处就是把复杂度化简到了分析中,分析之后的结果再由计算机去处理,效率提高很多。下面我想讲讲我的想法,以为一个数的大小,是由他位数和各个位置上的数字大小决定的,再具体化一下,可以把一个数看成2部分,最高位和除去最高位之后的数。举个例子:148,那么可以肯定的说这个S = f(148)的值和最高位的1,以及48有着直接的关系。我的分析就是如果最高位1,那么这个S(初始是0)的值现在就可以变成48+1了,因为100-148有49个1,然后再去递归分析48这个数,分析完之后再分析148-48-1这个数的情况;如果最高位不是1,那么就应该分析去除最高位之后的那个数的情况。好了,贴代码:
public class Cound {
static int number = 0;
public static int count2(int n){
String str = "" + n;
if (n == 0)
number += 0;
else if (n <= 9 && n > 0)
number ++;
else if (n >= 10){
String temp = str.substring(1);
nt tempInt = Integer.parseInt(temp);
if (str.charAt(0) == '1')
number += tempInt + 1;
count2 (tempInt);
n -= tempInt + 1;
count2(n);
}
return number;
}
public static void main(String args[]){
int i = 1000000;
long time2 = System.currentTimeMillis();
System.out.print(count2(i) +" ");
System.out.println(System.currentTimeMillis()-time2);
}
}
后记:当然了,还是推荐第一种解法,分析的最优结果就是能将这个问题的复杂度降到O(1),当然这是理论的情况,能不能,值不值得还是需要具体问题具体分析的。当然也可以寻求别的解法,如同我做的那样。