您的位置:首页 > 编程语言

编程珠玑第九章--性能之代码调优

2016-09-10 14:06 204 查看
大手术–二分搜索

几个程序的书写

package chapter9;

public class BinarySort {
public static int binarySort0(int x[],int number){
int l=0,r=x.length-1;
int m=0;
while(true){
if(l>r){
return -1;
}
m=(l+r)/2;
if(x[m]>number){
r=m-1;
}
if(x[m]==number){
return m;
}
if(x[m]<number){
l=m+1;
}
}
}
//我们假定x[-1]<t;x
=>t只是假想并不实际进行访问这两个元素;然后在循环进入条件l+1!=m,并且根据m=(l+r)/2;通过对x[m]与number的比较,不断更新l或r,使得x[l]<t,x[r]>=t始终成立,甚至最终l+1=m跳出循环时仍然成立,此时看一下r是否为所求下标;
public static int binarySort1(int x[],int number){
int l=-1,r=x.length;
while(l+1!=r){
int m=(l+r)/2;
if(x[m]<number){
l=m;
}
else {
r=m;
}
}
if(r>=x.length||x[r]!=number)//r>=x.length保证不会访问x
;
return -1;
else {
return r;
}
}
//假设n=1000;程序里我们不使用l,r表示数组的左右边界;而是使用l+i来表示右边界,
//所以就要使得l+i=r,并且我们要是i是2的正整数次 ;
public static int binarySort2_a(int x[],int number){
int i=512;
int l=-1;
if(x[511]<number){
l=1000-i;//确保l...l+incremnt要么为-1...511,要么是488...512;
}
int next_i;
while(i!=1){
//循环不变式:x[l]<number&&x[l+i]>=number&&i=2^j;
next_i=i/2;
if(x[l+next_i]<number){
l+=next_i;
i=next_i;
}
else {
i=next_i;
}
}
//      assert(i==1&&x[l]<number&&x[l+i]>=number);
int p=l+1;
if(p>1000||x[p]!=number){
return -1;
}
return p;
}
public static int binarySort2_b(int x[],int
dad5
number){
int i=512;
int l=-1;
if(x[511]<number){
l=1000-i;//确保l...l+incremnt要么为-1...511,要么是488...512;
}
while(i!=1){
//循环不变式:x[l]<number&&x[l+i]>=number&&i=2^j;
i=i/2;
if(x[l+i]<number){
l+=i;
}
}
//      assert(i==1&&x[l]<number&&x[l+i]>=number);
int p=l+1;
if(p>1000||x[p]!=number){
return -1;
}
return p;
}
public static int binarySort3(int x[],int number){
int i=512;
int l=-1;
if(x[511]<number){
l=1000-i;//确保l...l+incremnt要么为-1...511,要么是488...512;
}
if(x[l+256]<number)l+=256;
if(x[l+128]<number)l+=128;
if(x[l+64]<number)l+=64;
if(x[l+32]<number)l+=32;
if(x[l+16]<number)l+=16;
if(x[l+8]<number)l+=8;
if(x[l+4]<number)l+=4;
if(x[l+2]<number)l+=2;
if(x[l+1]<number)l+=1;
//      assert(i==1&&x[l]<number&&x[l+i]>=number);
int p=l+1;
if(p>1000||x[p]!=number){
return -1;
}
return p;
}
}


习题

6.0~9,a~z,A~Z看它属于哪一个范围

7.先设计算法计算每一个输入单元,int 或者是char;

对于int,方法一:number&(1<

package chapter9;

import java.util.HashMap;
public class t7 {
//因为Java里int为32位,并且只有有符号数只能访问到31位
//方法一:number&(1<<i);找到对应的每一位的值,

//当然这个方法对于每个int都要运行31次
public static int countInt0( int number){
int temp=0;
int count=0;
for(int i=0;i<31;i++){
temp=number&(1<<i);
//          System.out.print(temp+" ");
if(temp!=0){//事实上,temp应该等于1<<i;才会进行count++
count++;
}
}
//      System.out.println();
return count;
}
//方法二:使用number&=(number-1),对number中是1的位进行迭代,直到b==0,跳出循环
//可以看出方法二运行的次数就是number中位为1的个数,比方法一肯定是快的;
public static int countInt1(int number){
int count=0;
while(number>0){
number&=(number-1);
//          System.out.print(number+" ");
count++;
}
//      System.out.println();
return count;
}
//对于字符位为1的个数,只需将字符转换成int就好,然后就利用countInt1可以直接来算
public static int countChar(char c){
int re=Integer.valueOf(c);
//      System.out.println(re);
return countInt1(re);

}
//优化是用一个HashMap进行保存各个数字及其位为1的个数,键位数字+""或者字符+"",值为个数;
//对于每一个数先看hashmap里是否包含,若是包含就直接取值,若是不包含则使用上述的方法二countInt1进行计算并保存
static HashMap<String, Integer> hashMap=new HashMap<String, Integer>();
//当然另一种优化就是看看对所有输入单元进行统计,看看每一个单元出现的次数,然后存储下次数,最后对于不同的单元计算其1出现的个数并乘以个数,最后相加
//其实和上面的优化的效率差不多
public static long countExample(){
int arr[]={31,31,30,30};
char cArr[]="aabb".toCharArray();
long count=0;
int temp;
for(int i=0;i<arr.length;i++){
if(!hashMap.containsKey(arr[i]+"")){
temp=countInt1(arr[i]);
count+=temp;
hashMap.put(arr[i]+"", temp);
System.out.println("store "+arr[i]);
}
else {
count+=hashMap.get(arr[i]+"");
System.out.println("from the store ");
}
}
for(int i=0;i<cArr.length;i++){
if(!hashMap.containsKey(cArr[i]+"")){
temp=countChar(cArr[i]);
count+=temp;
hashMap.put(cArr[i]+"", temp);
System.out.println("store "+cArr[i]);
}
else {
count+=hashMap.get(cArr[i]+"");
System.out.println("from the store ");
}
}
return count;

}
public static void main(String args[]){
//      System.out.println(Integer.SIZE);
//      System.out.println(Integer.MAX_VALUE);
//      System.out.println(Integer.MIN_VALUE);
//      System.out.println(Character.SIZE);//0000-FFFF 16位
//      System.out.println(Character.MIN_VALUE+" ");
//  System.out.println("方法一");
//  System.out.println(countInt0(255));
//  System.out.println(countInt0(254));
//  System.out.println(countInt0(253));
//  System.out.println(countInt0(1023));
//  System.out.println(countInt0(1022));
//  System.out.println(countInt0(1021));
//  System.out.println("\n\n");
//  System.out.println("方法二");
//  System.out.println(countInt1(255));
//  System.out.println(countInt1(254));
//  System.out.println(countInt1(253));
//  System.out.println(countInt1(1023));
//  System.out.println(countInt1(1022));
//  System.out.println(countInt1(1021));
//  System.out.println("\n\n");
//      System.out.println("count char");
//      System.out.println(countChar('a'));
System.out.println(countExample());
}
}


运行结果

store 31
from the store
store 30
from the store
store a
from the store
store b
from the store
30


8.利用哨兵元素寻找最大值

*

package chapter9;
public class t8 {
public static int findMax(int arr[]){
//      arr[arr.length-1]用来作为哨兵元素
int i=0;
int n=arr.length-1;
int max=0;
while(i<n){
max=arr[i];
arr
=max;
i++;
while(arr[i]<max){
i++;//直到找到比现在max大或等于的;或者最终i==n,找到哨兵,跳出循环
}
}
return max;
}
public static void main(String args[]){
System.out.println(findMax(new int[]{5,4,3,3,1}));
}
}


11.因为只需要角度为5度的整数倍时才需要计算。360/5=72;因为0与360是等价的,所以只需要取其一即可。所以只要利用表格记录角度为0,5,10,15,…….,355对应的三角函数值即可

12.人们在调优程序时有时会从数学的角度而不是代码的角度看问题。

package chapter9;

public class t12 {
public static int compute(int a[],int x){
int y=a[0];
int n=a.length-1;
int temp=1;
for(int i=1;i<=n;i++){
temp=x*temp;
y+=a[i]*temp;
//          System.out.print(y+" ");
}
//      System.out.println();
return y;
}
public static int compute1(int a[],int x){
int n=a.length-1;
int y=a
;
for(int i=n-1;i>=0;i--){
y=x*y+a[i];//利用n次乘法,按需要与x的乘积次数将a数组里的元素一一放入,进行乘积
}
return y;

}
public static void main(String args[]){
System.out.println(compute(new int[]{1,1,1,1,1}, 2));
System.out.println(compute1(new int[]{1,1,1,1,1}, 2));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: