H2j自学记录-2023.03
前言
学的进度很慢,想日报一样把每天新学的东西略作总结,会更有收获,就权当是个记录吧。
day_1 :循环与条件
包括While,for,do while,switch的循环方法,以及break,continue,以及用“标记”中止多层循环中特定循环的方法(本质还是break)。
如果以后再回头来看,可以给自己提个问题:
while和do while的区别在哪?
我把这个问题的答案放到最后。
今天的代码题目为:
1.黄金分割率
题目描述:*寻找某两个数相除,其结果 离黄金分割点 0.618最近,分母和分子不能同时为偶数,分母和分子取值范围在[1-20]。
我的解答:
public class Gold {
public static void main(String[] args) {
int a_final=0,b_final=0,a=20;
double min=Math.abs((20*0.618)-(int)Math.round(20*0.618));
//定义初始分母与分子为a与b,我们最终得到的分母与分子为int a_final,b_final。
//min是1--20的所有a,b组合中,b、a之商与黄金分割率的最小差值。初始化min为a=20时的值。
for (a=20;a>2;a--){
//a为分母,黄金分割率<1,因此b只可能比a小,每一个固定的a都对应一个固定的b使其商最接近0.618,这个b可以被计算,其表达式如下:
int b=(int)Math.round(a*0.618);
double cha=Math.abs((a*0.618)-b);
while (cha<min){
min=cha;
a_final=a;
b_final=b;
}
}
System.out.println(b_final+"与"+a_final+"之商最接近黄金分割率0.618");
}
}
当然,官方给的答案如下,但我觉得我自己的更好,因为事先确定了b,所以少用了一次循环遍历。
public class HelloWorld {
public static void main(String[] args) {
// 寻找某两个数相除,其结果 离黄金分割点 0.618最近
//
// 分母和分子不能同时为偶数
// 分母和分子 取值范围在[1-20]
int range = 20; // 取值范围
float breakPoint = 0.618f; // 黄金分割点
float minDiff = 100; // 离黄金分割点的差值
int answerFenzi = 0; // 找到的分子
int answerFenmu = 0; // 找到的分母
for (int fenzi = 1; fenzi <= range; fenzi++) {
for (int fenmu = 1; fenmu <= range; fenmu++) {
// 分母和分子不能同时为偶数
if (0 == fenzi % 2 & 0 == fenmu % 2)
continue;
// 取值
float value = (float) fenzi / fenmu;
// 取离黄金分割点的差值
float diff = value - breakPoint;
// 绝对值
diff = diff < 0 ? 0 - diff : diff;
// 找出最小的差值
if (diff < minDiff) {
minDiff = diff;
answerFenzi = fenzi;
answerFenmu = fenmu;
}
}
}
System.out.println("离黄金分割点(" + breakPoint + ")最近的两个数相除是:" + answerFenzi + "/" + answerFenmu + "="
+ ((float) answerFenzi / answerFenmu));
}
}
2.水仙花数
水仙花数定义:
- 一定是3位数
- 每一位的立方,加起来恰好是这个数本身,比如153=111+555+333
寻找所有的水仙花数
我的解法:
int a,b,c;
System.out.println("水仙花数有:");
for (a=1;a<9;a++){
for (b=0;b<9;b++){
for (c=0;c<9;c++){
if (a*a*a+b*b*b+c*c*c==100*a+10*b+c){
System.out.println(100*a+10*b+c);
}
}
}
}
可以说这个解法太暴力了,实在不值得推荐。这幸好水仙花数只有3位,假设水仙花数是一个n位数,那上面这个解法的时间复杂度就是O(10n),已经是指数级的复杂度,因为是三层循环嵌套,每层复杂度为10。
关于时间复杂度的计算网上有很多教程,这里不再赘述。
而官方给的解答就好很多,假设水仙花数是一个n位数而不是3位数,那么算法的时间复杂度也是O(1)。其解答如下:
for (int i = 100; i < 1000; i++) {
int baiwei = i / 100;
int shiwei = i / 10 % 10;
int gewei = i % 10;
int cube = baiwei * baiwei * baiwei + shiwei * shiwei * shiwei + gewei * gewei * gewei;
if (cube == i) {
System.out.println("找到水仙花数:" + i);
}
}
小学算术题
题目如图所示:
我的解答:
int a,b,c,d;
System.out.println("对于图中a,b,c,d的唯一解为:");
lo1://外层循环
for (a=0;a<8;a++){//因为是小学题目,可以不用考虑负数,因为a=8-b,所以a最大的情况就是b=0的时候,a=8
b=8-a;
c=14-a;
lo2://内层循环
for (d=0;d<10;d++){//同理,d最大不超过10
if (c-d==6&&b+d==10) {
System.out.println(a + "," + b + "," + c + "," + d);
break lo1;//方程具有唯一解,找到之后,后面的情况都可以不考虑了
}
}
}