Java笔记03:
自学笔记1
内容:
- Java流程控制(基于黑马程序员视频)
- 编程练习(基于菜鸟教程-C 语言经典100例)
- 编程时遇到的问题及解决方法
1.Java流程控制
花了两天时间把黑马程序员的流程控制篇顺序结构看完,本来打算去力扣做题目,新手村的第一题就出数组,我还需要继续学习,暂时用菜鸟教程的C 语言经典100例练习
2.编程练习
2.1 有 1、2、3、4 四个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
1.要组成互不相同的数字就需要用三层嵌套循环来定义个十百位,且取值范围均在[1,4]间
2.要无重复数字就需要在生成数字后判断是否出现重复,如果没重复就输出,并统计
public class EighthCode{
public static void main(String[] args){
int count=0;//统计次数
for (int i=1;i<5;i++){//百位
for(int j=1;j<5;j++){//十位
for(int k=1;k<5;k++){//个位
if(i!=j&&i!=k&&j!=k){//如果各个位数的值都不同,才输出
count++;
System.out.println(i*100+j*10+k);
}
}
}
}
System.out.println("一共可以组成"+count+"个互不相同且无重复数字的三位数");
}
}
2.2 企业发放的奖金根据利润提成
利润(I)低于或等于10万元时,奖金可提10%;
利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%;
20万到40万之间时,高于20万元的部分,可提成5%;
40万到60万之间时高于40万元的部分,可提成3%;
60万到100万之间时,高于60万元的部分,可提成1.5%;
高于100万元时,超过100万元的部分按1%提成。
从键盘输入当月利润I,求应发放奖金总数?
1.这关考分支结构,用if或switch,又因为switch格式不支持(case的值为常量表达式,不能用关系运算符,而且我总不能从case 1写到case 100),所以选择if第三种格式判断
2.不想算的太麻烦,先用序号来代替,看看分的对不对
3.如果没问题,再将公式改写,代入计算
档位正确,那就改公式
import java.util.Scanner;
public class CDemo2{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
System.out.println("enter your profit(wan yuan):");
int i=sc.nextInt();
double money=0;
if (i<=10){
money=i*0.1;
}else if(i<20){
money=10*0.1+(i-10)*0.075;
}else if(i<40){
money=10*0.1+10*0.075+(i-20)*0.05;
}else if(i<60){
money=10*0.1+10*0.075+20*0.05+(i-40)*0.03;
}else if(i<100){
money=10*0.1+10*0.075+20*0.05+20*0.03+(i-60)*0.015;
}else{
money=10*0.1+10*0.075+20*0.05+20*0.03+40*0.015+(i-100)*0.01;
}
System.out.println("you have "+money*10000+" yuan");
}
}
2.3 一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
看完题目就感觉凉了,完全不会,幸好有解析,不用四处找答案,于是我先去百度完全平方数,若一个数能表示成某个整数的平方的形式,则称这个数为完全平方数
,再去看答案解析。
1.假设这个整数是x,由题目可得,x+100=一个完全平方数(假设为n方),再在此基础上+168=另一个完全平方数(假设为m方)
即x + 100 = n2, x + 100 + 168 = m2
2.由1得m2=n2+168
–>m2-n2=168
–>因式分解得 (m+n)(m-n)=168
-->至少有一个是偶数,才能得到168,两个奇数相乘是不可能得到偶数的
3.假设 m+n=i
,m-n=j
则m=i-n
,m=j+n
–>i-n=j+n
–>2n=i-j
—>n=(i-j)/2
;同理得m=(i+j)/2
。当前i j
取值可分为三种:都是偶数、都是奇数、其中一个是奇数,另一个是偶数;又因为m n
都是整数,所以(i+j)
和(i-j)
都必须为偶数,所以i j
取值只有两种,都是偶数、都是奇数,再次回到2的结论,最终可以得出i j
都是偶数
4.因为i*j=168
,i j
又是偶数,所以i j
均是>= 2 的偶数,且i>j
所以2<=i<=168/2
–>1<i<85
public class CDemo3{
public static void main(String[] args){
for (int i=1;i<85;i++){
if(168%i==0){//因数
int j=168/i;
if((i+j)%2==0 && (i-j)%2==0 && i>j){
int m=(i+j)/2;
int n=(i-j)/2;
int x=n*n-100;//int x=m*m-100-168;
System.out.println(x+" + 100 = "+n +" * "+n);
System.out.println(x+" + 100 +168 = "+m +" * "+m);
System.out.println("-------------");
}
}
}
}
}
2.4 输入某年某月某日,判断这一天是这一年的第几天?
1.输入年月日,先判断是闰年还是平年,闰年的话,2月会多1天
2.根据月份计算日期,经典用法是用switch,同样统计十二生肖也用switch
3.要统计的日期公式=月份+输入的日期,在输出之前,再判断是否闰年,如果是的话就在总的日期上+1
//输入某年某月某日,判断这一天是这一年的第几天?
import java.util.Scanner;
public class CDemo4{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
System.out.println("请输入分别输入要查询的年月日:");
System.out.println("请输入要查询的年份:");
boolean flag=false;
int year=sc.nextInt();
System.out.println("请输入要查询的月份:");
int mouth=sc.nextInt();
System.out.println("请输入要查询的日期:");
int day=sc.nextInt();
int sum =0,endday=0;
if((year % 4==0 && year % 100 !=0 )||(year % 400 == 0)){//判断闰年
flag=true;
}
//口诀:一三五七八十腊(12月),三十一天永不差;四六九冬(11月)三十日;平年二月二十八,闰年二月把一加
switch (mouth){//确定月份
case 1:
sum=0;//第一个月没过完,直接就用day的值就行
break;
case 2://闰年就是29
sum=31;//说明第一个月过完了,需要在day的基础上加上第一个月的日子。我又不会switch累加,索性自己算,降低难度
break;
case 3:
sum=59;
break;
case 4:
sum=90;
break;
case 5:
sum=120;
break;
case 6:
sum=151;
break;
case 7:
sum=181;
break;
case 8:
sum=212;
break;
case 9:
sum=243;
break;
case 10:
sum=273;
break;
case 11:
sum=304;
break;
case 12:
sum=334;
break;
default:
System.out.println("请退出重新输入合法月份数");
}
if (flag && mouth>2){//如果是闰年且输入的月份>2,那么在此基础上+1,反之则正常累加
endday=sum+day+1;
}else{
endday=sum+day;
}
System.out.println("是第 "+endday+" 天");
}
}
2.5 输入三个整数x,y,z,请把这三个数由小到大输出
1.常规操作是定义一个临时变量,将用户输入的值两两比较,使用临时变量,将值交换,最后输出,突然没想开,打算用逻辑判断将值输出(这个别学,太憨了)
2.首先将值赋值给变量x、y、z,其次将x、y进行比较,再将其中小值与z比较,就可以出结果了,假设很美好,现实很残酷,我忘了这只是其中最简单的一种结果,从这开始,我开始了多余的逻辑思考,麻了,这时候不得不提一句,注释创造美好未来
import java.util.Scanner;
public class CDemo5{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
System.out.println("请输入分别输入整数,进行比较:");
System.out.println("请输入第一个值:");
boolean flag=true;//用来判断是否输出,若结果未输出,则比较x,z
int x=sc.nextInt();
System.out.println("请输入第二个值:");
int y=sc.nextInt();
System.out.println("请输入第三个值:");
int z=sc.nextInt();
System.out.println("输入"+x+" "+y+" "+z);
int temp=0;//x<y<z
if(x>y){
temp=x;
x=y;
y=temp;
}//这时候就变成了x<y
if(x>z){
temp=x;
x=z;
z=temp;
}//这时候就变成了x<z
if(y>z){
temp=y;
y=z;
z=temp;
}//这时候就变成了y<z
System.out.println("由小到大输出为:"+x+" "+y+" "+z);
}
}
常规方法的
import java.util.Scanner;
public class CDemo5{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
System.out.println("请输入分别输入整数,进行比较:");
System.out.println("请输入第一个值:");
boolean flag=true;//用来判断是否输出,若结果未输出,则比较x,z
int x=sc.nextInt();
System.out.println("请输入第二个值:");
int y=sc.nextInt();
System.out.println("请输入第三个值:");
int z=sc.nextInt();
System.out.println("输入"+x+" "+y+" "+z);
if(x>y){//x>y
if(y>z){//判断y>z,为真则最大值为x,第二大的就是y,最小的就是z了
System.out.println("由小到大输出为:"+z+" "+y+" "+x);
flag=false;
}else{//x>y && z>y,那么需要判断x和z谁大
if(x>z){
System.out.println("由小到大输出为:"+z+" "+y+" "+x);
flag=false;
}else{
System.out.println("由小到大输出为:"+y+" "+x+" "+z);
flag=false;
}
}
}else{//x<y
if(y>z){//x<y && z<y,那么需要判断x和z谁大
if(x>z){
System.out.println("由小到大输出为:"+z+" "+x+" "+y);
flag=false;
}else{
System.out.println("由小到大输出为:"+x+" "+z+" "+y);
flag=false;
}
}
}
if(flag){
if(x>z){//x>z
if(z>y){//x>z && z>y --> x>z>y
System.out.println("由小到大输出为:"+y+" "+z+" "+x);
}else{//x>z && y>z --> 判断x>y
if(x>y){//x>z && x>y && y>z --> x>y>z
System.out.println("由小到大输出为:"+z+" "+y+" "+x);
}else{//x>z && y>x && y>z --> y>x>z
System.out.println("由小到大输出为:"+z+" "+x+" "+y);
}
}
}else{//x<z
if(y>z){//x<z && z<y -->y>z>x
System.out.println("由小到大输出为:"+x+" "+z+" "+y);
}else{//x<z && y<z -->判断x>y
if(x>y){//x<z && y<z && y<x -->z>x>y
System.out.println("由小到大输出为:"+y+" "+x+" "+z);
}else{//x<z && y<z && x<y -->z>y>x
System.out.println("由小到大输出为:"+x+" "+y+" "+z);
}
}
}
}
}
}
纯if判断的
一眼就可以看出哪个简单了吧*—*
2.6 输出9*9口诀
1.每次学习编程语言都会遇到这道题,第一想法就是嵌套for循环,第一层循环负责行,第二层循环负责列
2.输出很简单,但是这个格式我不会,经过不懈的查询,我终于查到了java九九乘法表输出怎么能对齐,原来还可以用这个方法输出
public class CDemo6{
public static void main(String[] args){
for (int i=1;i<10;i++){
for (int j=1;j<i+1;j++){
//System.out.println(i + " * "+j+" = "+i*j);
System.out.printf("%d*%d=%-2d ",i,j,(i*j));
}
System.out.println("\n");
}
}
}
2.7 古典问题(兔子生崽):有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?(输出前40个月即可)
1.假设有一对兔子a1,发育,当前还是1对
2.a1继续培养感情,下个月就开始生产了,现在还是1对
3.第三个月生了一对兔子a2,目前有2对
4.第四个月,a1继续生a3,a2还在默默发育,就变成了3对
5.第五个月,a1继续生a4,a2这时候也开始加入壮大家族的队伍,生了a5,所以有5对
6.第六个月,a1生a6,a2生a7,a3生a8,所以有8对
那看着这个,直接想到斐波那契数列,多亏了当初学vb的时候认真听讲,我还记得套路
先假设两个变量,f1、f2值均为1,要输出前40个月,那就直接for循环,范围是[1,20]即可
public class CDemo7{
public static void main(String[] args){
int f1=1,f2=1;
for (int i=1;i<21;i++){
System.out.println(f1+"\t"+f2);
f1=f2+f1;
f2=f2+f1;
}
}
}
3.编程时遇到的问题及解决方法
问题1:
出现标签重复,第一个重复是我范围写错,第二个重复我也不知道为什么。
疑似原因:通过查阅资料错误:case标签重复,根据这篇文章的说法,我的标签重复是因为二进制编码冲突,于是我将20-39做了二进制与运算,值刚好是40的二进制,大概也许可能是这个原因
解决方案:那我将3档的结尾改成38,再运行,发现没报错。不过只查到这篇,我不能很明确的确定,标签重复的原因
问题2:
看了java switch case后跟一个范围的问题后自己尝试了一下,不管我输入的是什么,都执行default的语句
解决方法:先跳过,用if来实现
问题3:
重复输出了,猜测是因为重复执行了if判断
解决方法:设一个布尔类型的变量flag,在前面的if判断中,如果输出,那么flag值改变,到后面再判断flag值,改变,则不执行后面的语句,没改变,就说明前面的条件没命中