2012-05-07
Chapter18
1、表驱动法→从表里面查找信息而不使用if,case等语句
如,一个月有多少天,可维护数组days[12]={31,28,31,30……31}
则,day=days[month-1]; 省去判断if(month==1)……
优点:可读性好;易于修改
2、已知a,b与min(),max(),保证数x介于a,b之间(a<b)
max( min(b,x) , a )
3、索引访问表:有时候不能把数据直接作为键值
假设商店有100种商品,编号范围从0000-9999,存储单价,库存等信息,一条记录100字节
法一:直接建立主表,建立一个Info[10000],共用100*10000=10^6字节
法二:建立索引表→指向主表 索引表可以很小,如每个记录2字节,索引表为Index[1000],主表为Info[100],使用时,直接Info[Index[num]]
-1 |
-1 |
-1 |
0 |
1 |
Info[100]数组,只有100种商品
0 |
1 |
2 |
… |
99 |
Index[10000]数组
共用10000*2+100*100=3*10^4字节,大量节省空间
例如,商品编号依次为0135,0229,0518,1314…….
则Index[0135]=0,Index[0229]=1,Index[0518]=2,知道Index[9997]=99
使用时,Info[Index[Num]]即可
法二优点:节省空间;通过建立多个索引表可更方便访问,如Index1[10000]通过Num访问商品,Index2[10000]通过Name访问商品
4、阶梯访问表
>=90 |
A |
<90 |
B |
<75 |
C |
<65 |
D |
<50 |
E |
假设分类评级,如上表,不适合直接创建索引
法一:取整,建立索引
法二:阶梯访问表
将每一区间的上限写入表中,并写一个循环,按照各区间的上限来检查分数,等级不断提升,直到超过上限
例:double RangeLimit[5]={50,65,75,90,100}
string grade[5]={E,D,C,B,A};
int MaxGradeLevel=4;
string GetGradeLevel(double score)
{
int gradeLevel=0;
if(score<Rangelimit[gradeLevel]) return grade[GradeLevel]
while(gradeLevel<MaxGradeLevel && score>RangeLimit[gradeLevel])
gradeLevel++;
return grade[GradeLevel];
}
若阶梯很多,可考虑二分
阶梯访问表:省空间,耗时
索引访问表:费空间,省时
Chapter19
1、用true和false做布尔判断,而不要用0、1(使语义更明确)
2、通过1,拆分复杂的判断并引入心得布尔变量
2,把复杂的表达式做成布尔函数
→简化复杂的判断
3、编写肯定形式的布尔表达式
用if(statusOK)
do sth…
else do sth else…
替代if(!statusOK) do sth else…
else do sth…
考虑用狄摩根定律简化判断式
if(!dispalyOK || !printOK)→ if( ! (displayOK&&printOK) )
4、C++,Java中对&&,||的短路求值:对于&&,若conditional1为false,则不再计算condition2
例如,两数做除法
if( (denominator!=0) && ( (item/denominator)>MIN_VALUE ) )
正确,若分母为0,不会计算condition2
交换顺序后会出错
5、按数轴顺序编写数值表达式,例如,对于a<b,
用if( a<I && i<b )来替代if(i>a && i<b),前者可以直观上看出判断的是什么,语意清楚
6、在C中显式的比较字符和’\0’
最好写成if(*charptr !=’\0’) 而非if(*charptr)
强调表达式是在处理字符数据(用后者也可)
7、指针与NULL比较,而不要与0或者直接写
如,if(p!=NULL) 而不要写成if(p)
8、在java中,a==b判断a,b是否引用了同一个对象
a.equals(b)判断2个对象是否存相同的值(通常用这个)