原视频(我不是up主,我只是搬运工):算法前置课_哔哩哔哩_bilibili
目录
第1章
1.1特点-简史-硬件
介绍Java发展史以及一些特点。略
1.2操作系统与应用程序
关于操作系统。略
1.3、1.4Java机制
JVM
一次编写,处处运行。略
1.5下载安装-环境变量
网上很多。略
1.6Path-Classpath
略
1.7Hello的编写-编译和运行
很基础。略
1.8常见错误
找不到命令
找不到主类
类名与文件名不一致
大小写错误
中英文错误
文件名的后缀问题
1.9macOSX及Linux上Java开发环境搭建
略。(我是windows)
1.10关于IDE和代码书写工具
记事本(赤手空拳)
Notepad++、EditPlus、UltraEdit
sublimeText
各种IDE(eclipse、idea...)
第2章
2.1 基本数据类型之整数
2.2 整数的范围推算
8 4 2 1
八卦 8 8 64卦
阴阳组合可以形成复合卦:
所以8*8=64
所以中国的易经本质上就是6位2进制编码的体现。
byte最小是-128:
计算机用补码表示数字
(负数)补码=反码+1
先求原码(绝对值)再求反码:
再加1得到补码:
此时最高位兼有符号与数值两种特性
2.3 编码验证整数范围-浮点-字符-布尔
public class T123 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
// byte b = 129;//127max
// int i = 129;
// short s = 400000;//32767max
// long l = 789;
System.out.println(2.0-1.1);//0.89999999...即不能用2进制表示出来
}
}
上述代码运行结果为:0.89999999...
即不能用2进制表示出来,类似10进制不能准确表示1/3
转义字符:
第3章 变量-标识符-关键字
驼峰命名法中,变量名第一个字母一般小写
第4章
package qianzhi;
public class T4 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
//4.1 算术运算
System.out.println("***4.1 算术运算***");
System.out.println(3/2);//两个都是整数,是整数除法,结果是整数
System.out.println(3.0/2.0);
System.out.println(3.0/2);
System.out.println(3/2.0);
int i1 = 10, i2 = 20;
int i = i2++;
System.out.print("i=" + i);
System.out.println(" i2=" + i2);
i = ++i2;
System.out.print("i=" + i);
System.out.println(" i2=" + i2);
i = --i1;
System.out.print("i=" + i);
System.out.println(" i1=" + i1);
i = i1--;
System.out.print("i=" + i);
System.out.println(" i1=" + i1);
//4.2 逻辑运算
System.out.println("***4.2 逻辑运算***");
System.out.println("i=i2? "+(i==i2));
System.out.println("i!=i2? "+(i!=i2));
double j=2,j1=2.3;
System.out.println("i!=i2&&j1>j? "+((i!=i2)&&(j1>j)));
System.out.println("i!=i2||j1<j? "+((i!=i2)||(j1<j)));
System.out.println("!(i!=i2)? "+!(i!=i2));
boolean res=(i<j)&&(++j==3);//前一个对象是false,后边不运算
System.out.println(res);
System.out.println("短路运算之后j="+j);
//4.3三元运算符
System.out.println("***4.3三元运算符***");
int score=85;
String isOK=score>=60?(score>=85?"优秀":"良好"):"不及格";//嵌套三元运算
System.out.println("score="+score+"时,我们任务成绩"+isOK);
//4.4 位运算1
System.out.println("***4.4 位运算1***");
System.out.println("位运算判断奇数偶数(二进制偶数最低位0,奇数最低为1):");
int num=86;
//任何数与1,结果位0是偶数。为1是奇数
System.out.println(num+"是"+(((num&1)==0)?"偶数":"奇数"));
//4.5 位运算2
System.out.println("***4.5 位运算2***");
System.out.println("获取二进制位是1还是0(两种解决方法):");
System.out.println("1.1左移,按位与,结果右移");
/*判断第n位:先将1左移n-1位,然后按位与num,得出的结果再右移n-1位,若最终结果是0,则第n位是0,是1第n位是1
System.out.println("第n位是"+(((num&(1<<(n-1)))>>(n-1))==0?"0":"1"))*/
System.out.println("第5位是"+(((num&(1<<4))>>4)==0?"0":"1"));
System.out.println("2.num右移,按位与");
/*判断第n位:先将num右移n-1位,任何按位与1,结果是0第n位就是0,是1第n位就是1
System.out.println("第n位是"+(((num>>(n-1))&1)==0?"0":"1"));*/
System.out.println("第5位是"+(((num>>4)&1)==0?"0":"1"));
System.out.println("交换两个整数变量的值(利用异或)");
/*异或,可以理解为不进位加法:1+1=o,O+O=0,1+0=1性质
1、交换律可任意交换运算因子的位置,结果不变
2、结合律(即(a^b)^c == a^(b^c))
3、对于任何数x,都有x^x=O,x^O=x,同自己求异或为0,同o求异或为自己
4、自反性A^B^B=A^O=A,连续和同一个因子做异或运算,最终结果为自己*/
int num1=10;
int num2=20;
//运用了自反性与交换律
num1=num1^num2;
num2=num1^num2;//也就是num2=(num1^num2)^num2=num1^(num2^num2)=num1
num1=num1^num2;//也就是num1=(num1^num2)^num2=(num1^num2)^num1=num2^(num1^num1)=num2
System.out.println("num1=="+num1+","+"num2=="+num2);
//4.6 位运算3
//逻辑移位右移>>>,高位补零;算术移位右移>>,高位补符号位
System.out.println("***4.6 位运算3***");
System.out.println("不利用判断语句(if-else、三元运算符),求整数的绝对值");
int num3=-1;
/* 计算机里存储的是补码
* >>算术移位 java中int占4字节,也就是32位,负数右移31是111111...也就是-1
* (num3>>31)^num3)若num3为负数,则相当于num3^-1,也就是取反,加1得到原码绝对值
* 对于正数,相当于num3^0,还是num3本身;加0即可
* num3>>>31无符号右移,正数得到0,负数得到1
*/
System.out.println("|num3|="+(((num3>>31)^num3) + (num3>>>31)));
//4.7 赋值运算-类型转换-运算符优先级等
System.out.println("***4.7 赋值运算-类型转换-运算符优先级等***");
/*注意:可以将整型常量直接赋值给byte, short,char等类型变量,
* 而不需要进行强制类型转换,只要不超出其表数范围
* 自动类型转换:绝对安全的,精度小转精度大的(int赋值给long,如long l=128;
* byte->short->int->long;char->int;int->double不会丢失精度,
* int->float;long->float;long->double;可能会丢失精度)
* 强制类型转换:明知可能有安全风险(精度丢失),非要做。如int i=(long)128l;
* byte、char和 short型参与运算时自动提升为int型对于表达式
* 如果一个操作数为long型,则整个表达式提升为 long型
* 如果一个操作数为float 型,则整个表达式提升为float型
* 如果一个操作数为double型,则整个表达式提升为double 型
*/
//int i3=222;
float f3=3.14f;
f3=f3+0.05f;//正确
//f3=(float)(f3+0.05);//强制类型转换
//f3=(f3+(float)(0.05));//强制类型转换
//f3=f3+0.05;//错误,不能将double类型自动转换为float.0.5是double类型,则整个表达式返回double,与float类型的f3不同
System.out.println("f3="+f3);
/*运算符优先级
* 小括号中括号>正负取反非自增自减>乘除%>加减>移位>比较>等于不等于>按位与
* >异或>按位或>逻辑与>逻辑或>?:>赋值运算
* 正负!~++--、?:以及赋值运算符从右向左结合
* 多用括号
* */
//4.8 类型转换代码验证-自测题讲解
System.out.println("***4.8 类型转换代码验证-自测题讲解***");
/*绝对安全的赋值,即便两侧的数据类型不一致,也会发生自动类型转换
* 编译器只检查语法,运行期才负责运算
*/
byte b=127;
int i3=129;
long longNum=i3;
//i3=longNum;//错误,编译器只检查语法,运行期才负责运算,虽然只有129,但是编译器不会检测值
i3=(int)longNum;//正确,强制类型转换
float f=123.123f;//不加f会造成编译错误
f=(float)(f+1.2);//要强制类型转换,因为如果一个操作数为double型,则整个表达式提升为double
double doubleNum=longNum;
float floatNum=longNum;
//4.9 case1-AA制
System.out.println("***4.9 case1-AA制***");
/*假设菜的价格都是整数,定义三个int表示三个菜的价格
* 一共三个人一起吃饭,他们决定AA制
* 请帮他们算出每个人付多少钱
*/
int a1=32;
int a2=20;
int a3=9;
double result=(a1+a2+a3)/3.0;
System.out.println(result);
//4.10 case2-显示系统当前时间
System.out.println("***4.10 case2-显示系统当前时间***");
/*已知:System.currentTimeMillis()返回1970-1-1零点至今的毫秒数,
*long型输出系统当前时间,格式为时:分:秒
*限制:不调用系统的Date或Calendar API
*/
long totalTimeMills=System.currentTimeMillis();
long totalSeconds=totalTimeMills/1000;//总秒数
long totalMinutes=totalSeconds/60;//总分钟数
long totalHours=totalMinutes/60;//总小时数
long s=totalSeconds%60;
long m=totalMinutes%60;
long h=totalHours%24+8;//+8时区修正 0时区->东八区
System.out.println(h+"时:"+m+"分:"+s+"秒");
//求年份:
long totalDays=totalHours/24;
long totalYears=totalDays/365;
long y=totalYears+1970;
System.out.println(y+"年");
//4.11 case3-任意范围内随机整数
System.out.println("***4.11 case3-任意范围内随机整数***");
/*已知:Math.random() 随机返回[0,1)之间的一个double型浮点数
* Math在lang包下,因此不必显式import
* 你有办法得到任意范围内的随机整数和随机浮点数吗?
* (int)(Math.random()*10)返回0~9之间的一个随机整数
* 50 + (int)(Math.random() * 50)返回50~99之间的一个随机整数
* 通常,返回a ~a+b之间的一个a + Math.random() * b随机整数,不包括a+b
*/
int x1=1;
int x2=100;
//产生[a,b]随机整数:a+random()*(b-a+1);
int r1=(int)(Math.random()*(x2-x1+1))+x1;//产生[1,100]随机整数
System.out.println("产生的随机整数是:"+r1);
double r2=Math.random()*(x2-x1+1)+x1;//产生[1,100]随机浮点数
System.out.println("产生的随机浮点数是:"+r2);
4.1 运算符与表达式-1 算数运算
4.2 运算符与表达式-2 关系-逻辑运算
4.3 运算符与表达式-3 三元运算符
4.4、4.5、4.6 位运算
>>和<<是算术移位;>>>是逻辑移位
把2变成8最高效的方法是2左移2位
位运算奇巧淫技之判断奇偶数
思路:奇数二进制最低位为1,偶数为2。可以把给定数字&1,结果是0就是偶数,是1就是奇数。
System.out.println("位运算判断奇数偶数(二进制偶数最低位0,奇数最低为1):");
int num=86;
//任何数与1,结果位0是偶数。为1是奇数
System.out.println(num+"是"+(((num&1)==0)?"偶数":"奇数"));
位运算奇巧淫技之获取二进制位是1还是0(两种解决方案)
方案1:判断第n位,先将1左移n-1位,然后按位与num,得出的结果再右移n-1位,若最终结果是0,则第n位是0,是1第n位是1
System.out.println("获取二进制位是1还是0(两种解决方法):");
System.out.println("1.1左移,按位与,结果右移");
/*判断第n位:先将1左移n-1位,然后按位与num,得出的结果再右移n-1位,若最终结果是0,则第n位是0,是1第n位是1
System.out.println("第n位是"+(((num&(1<<(n-1)))>>(n-1))==0?"0":"1"))*/
System.out.println("第5位是"+(((num&(1<<4))>>4)==0?"0":"1"));
方案2:判断第n位,先将num右移n-1位,任何按位与1,结果是0第n位就是0,是1第n位就是1
System.out.println("2.num右移,按位与");
/*判断第n位:先将num右移n-1位,任何按位与1,结果是0第n位就是0,是1第n位就是1
System.out.println("第n位是"+(((num>>(n-1))&1)==0?"0":"1"));*/
System.out.println("第5位是"+(((num>>4)&1)==0?"0":"1"));
位运算奇巧淫技之交换两个整数变量的值
思路:
System.out.println("交换两个整数变量的值(利用异或)");
/*异或,可以理解为不进位加法:1+1=0,0+0=0,1+0=1性质
1、交换律可任意交换运算因子的位置,结果不变
2、结合律(即(a^b)^c == a^(b^c))
3、对于任何数x,都有x^x=0,x^0=x,同自己求异或为0,同0求异或为自己
4、自反性A^B^B=A^0=A,连续和同一个因子做异或运算,最终结果为自己*/
int num1=10;
int num2=20;
//运用了自反性与交换律
num1=num1^num2;
num2=num1^num2;//也就是num2=(num1^num2)^num2=num1^(num2^num2)=num1
num1=num1^num2;//也就是num1=(num1^num2)^num2=(num1^num2)^num1=num2^(num1^num1)=num2
System.out.println("num1=="+num1+","+"num2=="+num2);
位运算奇巧淫技之不用判断语句求整数的绝对值
思路:计算机里存储的是补码,负数原码=补码取反再加1;正数原码=补码=补码+0=(0^补码)+0=(补码>>31)^补码+0。num>>>31,正数得到0,负数得到1。
System.out.println("不利用判断语句(if-else、三元运算符),求整数的绝对值");
int num3=-1;
/* 计算机里存储的是补码
* >>算术移位 java中int占4字节,也就是32位,负数算术右移31是111111...也就是-1
* (num3>>31)^num3)若num3为负数,则相当于num3^-1,也就是取反,加1得到原码绝对值
* 对于正数,相当于num3^0,还是num3本身;加0即可
* num3>>>31无符号右移,正数得到0,负数得到1
*/
System.out.println("|num3|="+(((num3>>31)^num3) + (num3>>>31)));
4.7 赋值运算-类型转换-运算符优先级等
小的往大的转换:自动类型转换
*可以将整型常量直接赋值给byte, short,char等类型变量,而不需要进行强制类型转换,只要不超出其表数范围(绝对安全的赋值,即便两侧的数据类型不一致,也会发生自动类型转换)
* 自动类型转换:绝对安全的,精度小转精度大的(int赋值给long,如long l=128;byte->short->int->long;char->int;int->double不会丢失精度,int->float;long->float;long->double;可能会丢失精度)
* 强制类型转换:明知可能有安全风险(精度丢失),非要做。如int i=(long)128l;
//4.7 赋值运算-类型转换-运算符优先级等
System.out.println("***4.7 赋值运算-类型转换-运算符优先级等***");
/*注意:可以将整型常量直接赋值给byte, short,char等类型变量,
* 而不需要进行强制类型转换,只要不超出其表数范围
* 自动类型转换:绝对安全的,精度小转精度大的(int赋值给long,如long l=128;
* byte->short->int->long;char->int;int->double不会丢失精度,
* int->float;long->float;long->double;可能会丢失精度)
* 强制类型转换:明知可能有安全风险(精度丢失),非要做。如int i=(long)128l;
* byte、char和 short型参与运算时自动提升为int型对于表达式
* 如果一个操作数为long型,则整个表达式提升为 long型
* 如果一个操作数为float 型,则整个表达式提升为float型
* 如果一个操作数为double型,则整个表达式提升为double 型
*/
//int i3=222;
float f3=3.14f;
f3=f3+0.05f;//正确
//f3=(float)(f3+0.05);//强制类型转换
//f3=(f3+(float)(0.05));//强制类型转换
//f3=f3+0.05;//错误,不能将double类型自动转换为float.0.5是double类型,则整个表达式返回double,与float类型的f3不同
System.out.println("f3="+f3);
/*运算符优先级
* 小括号中括号>正负取反非自增自减>乘除%>加减>移位>比较>等于不等于>按位与
* >异或>按位或>逻辑与>逻辑或>?:>赋值运算
* 正负!~++--、?:以及赋值运算符从右向左结合
* 多用括号
* */
4.8 类型转换代码验证-自测题
//4.8 类型转换代码验证-自测题讲解
System.out.println("***4.8 类型转换代码验证-自测题讲解***");
/*绝对安全的赋值,即便两侧的数据类型不一致,也会发生自动类型转换
* 编译器只检查语法,运行期才负责运算
*/
byte b=127;
int i3=129;
long longNum=i3;
//i3=longNum;//错误,编译器只检查语法,运行器才负责运算,虽然只有129,但是编译器不会检测值
i3=(int)longNum;//正确,强制类型转换
float f=123.123f;//不加f会造成编译错误
f=(float)(f+1.2);//要强制类型转换,因为如果一个操作数为double型,则整个表达式提升为double
double doubleNum=longNum; //不报错
float floatNum=longNum; //不报错
4.9 case1-AA制
/*假设菜的价格都是整数,定义三个int表示三个菜的价格
* 一共三个人一起吃饭,他们决定AA制
* 请帮他们算出每个人付多少钱
*/
//4.9 case1-AA制
System.out.println("***4.9 case1-AA制***");
/*假设菜的价格都是整数,定义三个int表示三个菜的价格
* 一共三个人一起吃饭,他们决定AA制
* 请帮他们算出每个人付多少钱
*/
int a1=32;
int a2=20;
int a3=9;
double result=(a1+a2+a3)/3.0;
System.out.println(result);
4.10 case2-显示系统当前时间
/*已知:System.currentTimeMillis()返回1970-1-1零点至今的毫秒数,
*long型输出系统当前时间,格式为时:分:秒
*限制:不调用系统的Date或Calendar API
*/
思路:做除法得到或更高一级的单位。取余得到当前时分秒。
扩展:求当前年。得到总年数加1970。
//4.10 case2-显示系统当前时间
System.out.println("***4.10 case2-显示系统当前时间***");
/*已知:System.currentTimeMillis()返回1970-1-1零点至今的毫秒数,
*long型输出系统当前时间,格式为时:分:秒
*限制:不调用系统的Date或Calendar API
*/
long totalTimeMills=System.currentTimeMillis();
long totalSeconds=totalTimeMills/1000;//总秒数
long totalMinutes=totalSeconds/60;//总分钟数
long totalHours=totalMinutes/60;//总小时数
long s=totalSeconds%60;
long m=totalMinutes%60;
long h=totalHours%24+8;//+8时区修正 0时区->东八区
System.out.println(h+"时:"+m+"分:"+s+"秒");
//求年份:
long totalDays=totalHours/24;
long totalYears=totalDays/365;
long y=totalYears+1970;
System.out.println(y+"年");
4.11 case3-任意范围内随机整数
/*已知:Math.random() 随机返回[0,1)之间的一个double型浮点数
* Math在lang包下,因此不必显式import
* 你有办法得到任意范围内的随机整数和随机浮点数吗?
*思路:
*(int)(Math.random()*10)返回0~9之间的一个随机整数 [0,10)
* 50 + (int)(Math.random() * 50)返回50~99之间的一个随机整数 [0,50)+50=[50,100)
* 通常,返回a ~a+b之间的一个a + Math.random() * b随机整数,不包括a+b [0,b)+a=[a,a+b)
*/
//4.11 case3-任意范围内随机整数
System.out.println("***4.11 case3-任意范围内随机整数***");
/*已知:Math.random() 随机返回[0,1)之间的一个double型浮点数
* Math在lang包下,因此不必显式import
* 你有办法得到任意范围内的随机整数和随机浮点数吗?
* (int)(Math.random()*10)返回0~9之间的一个随机整数
* 50 + (int)(Math.random() * 50)返回50~99之间的一个随机整数
* 通常,返回a ~a+b之间的一个a + Math.random() * b随机整数,不包括a+b
*/
int x1=1;
int x2=100;
//产生[a,b]随机整数:a+random()*(b-a+1);
int r1=(int)(Math.random()*(x2-x1+1))+x1;//产生[1,100]随机整数
System.out.println("产生的随机整数是:"+r1);
double r2=Math.random()*(x2-x1+1)+x1;//产生[1,100]随机浮点数
System.out.println("产生的随机浮点数是:"+r2);
第5章
package qianzhi;
import java.util.Scanner;
public class T5 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
//5.1 接收控制台输入
System.out.println("***5.1 接收控制台输入***");
// Scanner in=new Scanner(System.in);
// String s=in.nextLine();
// int i=in.nextInt();
// double d=in.nextDouble();
// System.out.println("s="+s+" i="+i+" d="+d);
//5.2 case4-5 Scanner使用示例
System.out.println("***5.2 case4-5 Scanner使用示例***");
/*case4 :
*已知∶圆面积公式为3.14159*r2
*需求:提示用户输入一个圆的半径(浮点数),计算出圆的面积并输出
*case5 :
*需求:提示用户输入两个整数,代表一个范围,随机输出这个范围内的一个整数
*/
System.out.println("case4:计算圆的面积");
System.out.print("r=");
@SuppressWarnings("resource")
Scanner input=new Scanner(System.in);
double r=input.nextDouble();
double res=Math.PI*r*r;
System.out.println("圆的面积为:"+res);
System.out.println("case5:产生随机数");
System.out.println("请输入两个整数,第一个为上界,第二个为下界");
int a=input.nextInt();
int b=input.nextInt();
int res1=(int)(Math.random()*(b-a+1))+a;
double res2=Math.random()*(b-a+1)+a;
System.out.println("产生的随机整数为"+res1);
System.out.println("产生的随机浮点数为"+res2);
}
}
5.1 接收控制台输入
输入字符:
char c=sc.next().charAt(0);
java.lang包属于“贵族”,不需要引入。变量名可以改。
5.2 case4-5-Scanner使用示例
case4:
System.out.println("case4:计算圆的面积");
System.out.print("r=");
@SuppressWarnings("resource")
Scanner input=new Scanner(System.in);
double r=input.nextDouble();
double res=Math.PI*r*r;
System.out.println("圆的面积为:"+res);
case5:
System.out.println("case5:产生随机数");
System.out.println("请输入两个整数,第一个为上界,第二个为下界");
int a=input.nextInt();
int b=input.nextInt();
int res1=(int)(Math.random()*(b-a+1))+a;
double res2=Math.random()*(b-a+1)+a;
System.out.println("产生的随机整数为"+res1);
System.out.println("产生的随机浮点数为"+res2);
第6章
package qianzhi;
import java.util.Scanner;
public class T6 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
//6.1 深入介绍字符
System.out.println("***6.1 深入介绍字符***");
/*一个16位Unicode码占两个字节,用以\\u开头的4位十六进制数表示,
* 范围从\u0000到\uFFFF,65536个字符
* 几乎可以代表所以字符,16bit=2byte=2B=1代码单元,
* 如果一个代码单元不够表示一个字符,要再加一个代码单元
* 大多数计算机采用ASCII码,它是表示所有大小写字母、数字、
* 标点符号和控制字符的 8位编码表
* Unicode码包括ASCII码,从\u0000到\u007F对应128个
* 字符 十进制编码值 Unicode值
* '0'-'9' 48-57 \u0030-\u0039
* 'A'-'Z' 65-90 \u0041-\u005A
* 'a'-'z' 97-122 \u0061-\u007A
*/
System.out.println("A"+'\u0061'+"B");
//6.2 关于字符的运算
System.out.println("***6.2 关于字符的运算***");
/*自增和自减操作符也可用在 char 型变量上,这会得到该字符之
* 前或之后的Unicode字符。例如,下面的语句显示字符b :
*/
char ch='a';
System.out.println(++ch);
System.out.println(ch++);
/*char型数据可以转换成任意一种数值类型,反之亦然
* 将整数(32位)转换成char型(16位)数据时,只用到该数据的低十六位,
* 其余部分都被忽略
*/
char ch1=(char)0xAB0041;//(0041)16->(65)10->'A' 相当于char(65)
System.out.println(ch1);
/*要将一个浮点值转换成char型时,
* 首先将浮点值转换成int型,
* 然后将这个整型值转换为char型
*/
char ch2=(char)65.25;
System.out.println(ch2);
/*当一个char型数据转换成数值型(int、double等)时,
* 这个字符的 Unicode码就被转换成某个特定的数值类型
*/
int i=(int)'A';
System.out.println(i);
/*0~FFFF 的任何一个十六进制正整数都可以隐式地转换成字符型数据。
* 而不在此范围内的任何其他数值都必须显式地转换为 char型
*/
char ch4=(char)0xAB0041;//不强制转换会报错 0xAB0041>0xFFFF
char ch5=0x0041;//0x0041<0xFFFF,可以隐式转换 与char ch5=65、char ch5='\u00041'一样
System.out.println("ch4="+ch4+" ch5="+ch5);
/*所有数值操作符都可以用在 char型操作数上。
* 如果另一个操作数是一个数字或字符,那么char型操作数就会被自动转换成一个数字。
* 如果另一个操作数是一个字符串,字符就会与该字符串相连
*/
int i1='2'+'3';//相当于50+51
System.out.println("i1 is "+i1);
int j=2+'a';//相当于2+97
System.out.println("j is "+j);
System.out.println("Chapter M"+'2');
char ch6='2'+'3';//相当于50+51=101 对应字符为e
char ch7='2'+3;//相当于2+3=5
System.out.println("char ch6="+ch6);
System.out.println("char ch7="+ch7);
//6.3 case6-整数转16进制
System.out.println("***6.3 case6-整数转16进制***");
/*已知:
* 0~9的十六进制表示和十进制一样
* 10~15的十六进制表示为A,B,C,D,E,F
* 需求:
* 提示用户输入0-15中的一个数,
* 用程序将其转换为十六进制表示法的单个字符,并输出
* 限制:
* 用户只能输入0~15
*/
//15->F
//大于9:'A'+(x-10);<=9:""+x
System.out.println("请输入0-15中的一个数:");
Scanner input = new Scanner(System.in);
int x=input.nextInt();
//char result=x>9?(char)('A'+(x-10)):((char)(x+'0'));
char result=(char)(x>9?'A'+(x-10):x+'0');
System.out.println(x+"对应的16进制为"+result);
//6.4 String,初步认识类、对象和方法
System.out.println("***6.4 String,初步认识类、对象和方法***");
/*字符串操作是程序设计中最常见的行为
* 从概念上讲,Java字符串就是unicode字符序列
* String不是基本数据类型,而是引用数据类型...
* 字符串声明与赋值:String name="zhangsan " ;
* 这有点像基本数据类型,实际上不是...
*/
/*“+"除用于算术加法运算外,还可用于对字符串进行连接操作
* int id = 800 +90;
* string s = "hello"+ "world " ;
* “+"操作符两侧的操作数中只要有一个是字符串(string )类型,系统会自动将另一个操作数转换为字符串然后再进行连接。
* int c = 12;
* system.out.println ( "c=" + c) ;
* 注意这样一个问题:
* System.out.println ( "c="+ 2 + 2 );
* 和System.out.println (2 +2+ "=c") ;
*/
System.out.println("c="+2+2);
System.out.println("c="+(2+2));
System.out.println(2+2+"=c");
/*字符串字面量,不再是一个基本数据类型,
* 虽然可以使用=和+运算符,但字符串字面量是一个"对象”
* 对象要比基木数据类型复杂得多,对象可以认为是多个其他数据的组合体
*/
/*
* string name = new string("zhangsan") ;name叫做对象的句柄/引用
* String是类名,等号右侧是一个新建的对象, name是对象的句柄
* 对象的一个显著特征是,有一系列可调用的方法(用.符号)
* int len = name .length ();
* 或者int len = new string("zhangsan").length() ;
* 通常我们会操作句柄而不是直接操作对象
* char c = name.charAt(1) ;操作句柄(遥控器)与操作对象(电视上的按钮)是等效的
*/
//6.5 API的查阅以及方法调用示例
System.out.println("***6.5 API的查阅以及方法调用示例***");
//1.得到或者创建对象,并赋值给一个句柄(引用类型的变量)
String name="abc123";
//2.在句柄上调用各种方法,如果方法有参数,需要传递参数
//3.如果方法有返回值,我们可以接收这个返回值
int len=name.length();
char charAt1=name.charAt(1);
System.out.println("长度为"+len);
System.out.println("第一个字符为"+charAt1);//b
//API https://docs.oracle.com/javase/8/docs/api/
String upperName=name.toUpperCase();
System.out.println("name大写形式:"+upperName);
//6.6 case7-猜猜你的生日号数
System.out.println("***6.6 case7-猜猜你的生日号数***");
/*每次输出一个16个数字组成的数字集合(1-31),询问生日号数是否在内,在输入1,不在输入0;
* 进行5次判断后输出生日号数
*/
/*思路,利用5位二进制数,从右到左,每次询问这一位是1还是0,
*即把这一位为1或0的所有数字(十进制)输出,然后判断下一位
*询问5次后,相当于确定了一个二进制数,转换为10进制输出即可
*综合运用二进制、输入输出、移位、拼接
*1.准备代表5个集合的五个字符串,这个字符串要在内部换行
*编号1的集合的内容:第1位上为1的1~31间数字的集合
*编号2的集合的内容:第2位上为1的1~31间数字的集合
*编号3的集合的内容:第3位上为1的1~31间数字的集合
*编号4的集合的内容:第4位上为1的1~31间数字的集合
*编号5的集合的内容:第5位上为1的1~31间数字的集合
*2.准备好之后,开始交互,每次询问得到的结果与之前的结果累加
*day=0
*依次询问
*是否在第1个集合里面,用户输入0或者1day +=answer*1; 1
*是否在第2个集合里面,用户输入0或者1day +=answer*(1<<1); 2
*是否在第3个集合里面,用户输入0或者1day +=answer*(1<<2); 4
*是否在第4个集合里面,用户输入0或者1day +=answer*(1<<3); 8
*是否在第5个集合里面,用户输入0或者1day +=answer*(1<<4); 16
*3.最终的day就是生日的号数
*/
String set1=
"1 3 5 7\n"+
"9 11 13 15\n"+
"17 19 21 23\n"+
"25 27 29 31";
String set2=
"2 3 6 7\n"+
"10 11 14 15\n"+
"18 19 22 23\n"+
"26 27 30 31";
String set3=
"4 5 6 7\n"+
"12 13 14 15\n"+
"20 21 22 23\n"+
"28 29 30 31";
String set4=
"8 9 10 11\n"+
"12 13 14 15\n"+
"24 25 26 27\n"+
"28 29 30 31";
String set5=
"16 17 18 19\n"+
"20 21 22 23\n"+
"24 25 26 27\n"+
"28 29 30 31";
int day=0;
//第1次询问
Scanner sc=new Scanner(System.in);
System.out.println("你的生日号数在这里边吗?\n");
System.out.println(set1);
System.out.println("是输入1,否输入0");
int answer=sc.nextInt();
day+=answer*1;
//第2次询问
System.out.println("你的生日号数在这里边吗?\n");
System.out.println(set2);
System.out.println("是输入1,否输入0");
answer=sc.nextInt();
day+=answer*(1<<1);
//第3次询问
System.out.println("你的生日号数在这里边吗?\n");
System.out.println(set3);
System.out.println("是输入1,否输入0");
answer=sc.nextInt();
day+=answer*(1<<2);
//第4次询问
System.out.println("你的生日号数在这里边吗?\n");
System.out.println(set4);
System.out.println("是输入1,否输入0");
answer=sc.nextInt();
day+=answer*(1<<3);
//第5次询问
System.out.println("你的生日号数在这里边吗?\n");
System.out.println(set5);
System.out.println("是输入1,否输入0");
answer=sc.nextInt();
day+=answer*(1<<4);
System.out.println("你的生日号数为"+day);
//6.7 case8-输出大写金额
System.out.println("***6.7 case8-输出大写金额***");
/*需求
* 给定5位整数2位小数的金额,请将其转换为半中文大写金额
* 89735.12->8万9千7百3十5元1角2分
* 限制
* 因为目前掌握知识较少,还做不到全中文
*/
//思路:取余取低位(舍高位),除法取高位(舍低位)
@SuppressWarnings("resource")
Scanner sc1=new Scanner(System.in);
System.out.println("请输入5位整数2位小数的金额");
double d=sc1.nextDouble();
int k=(int)(d*100);//总分
/*法1:
* int d1=k%10;//分
k/=10;//总角
int d2=k%10;//角
k/=10;//总元
int d3=k%10;//元
k/=10;//总十
int d4=k%10;//十
k/=10;//总百
int d5=k%10;//百
k/=10;//总千
int d6=k%10;//千
k/=10;//总万
int d7=k%10;//万
System.out.println(d+"的大写金额为"+d7+"萬"+d6+"仟"+d5+"佰"+d4+"拾"+d3+"圆"+d2+"角"+d1+"分");*/
//法2:
String res="";
int fen=(int)(d*100);
int wan=fen/1000000;//万分位数字
res+=wan+"萬";
fen=fen%1000000;
int qian=fen/100000;//千分位数字
res+=qian+"仟";
fen=fen%100000;
int bai=fen/10000;//百分位数字
res+=bai+"佰";
fen=fen%10000;
int shi=fen/1000;//十分位数字
res+=shi+"拾";
fen=fen%1000;
int yuan=fen/100;//元分位数字
res+=yuan+"圆";
fen=fen%100;
int jiao=fen/10;//角分位数字
res+=jiao+"角";
fen=fen%10;
int fenfen=fen;//分分位数字
res+=fenfen+"分";
System.out.println(d+"的大写金额为"+res);
}
}
6.1 深入介绍字符
/*一个16位Unicode码占两个字节,用以\u开头的4位十六进制数表示,
* 范围从\u0000到\uFFFF,65536个字符
* 几乎可以代表所以字符,16bit=2byte=2B=1代码单元,
* 如果一个代码单元不够表示一个字符,要再加一个代码单元即4个字节
* 大多数计算机采用ASCII码,它是表示所有大小写字母、数字、标点符号和控制字符的 8位编码表
* Unicode码包括ASCII码,从\u0000到\u007F对应128个(0-127)
* 字符 十进制编码值 Unicode值
* '0'-'9' 48-57 \u0030-\u0039
* 'A'-'Z' 65-90 \u0041-\u005A
* 'a'-'z' 97-122 \u0061-\u007A
*/
//6.1 深入介绍字符
System.out.println("***6.1 深入介绍字符***");
/*一个16位Unicode码占两个字节,用以\\u开头的4位十六进制数表示,
* 范围从\u0000到\uFFFF,65536个字符
* 几乎可以代表所以字符,16bit=2byte=2B=1代码单元,
* 如果一个代码单元不够表示一个字符,要再加一个代码单元
* 大多数计算机采用ASCII码,它是表示所有大小写字母、数字、标点符号和控制字符的 8位编码表
* Unicode码包括ASCII码,从\u0000到\u007F对应128个
* 字符 十进制编码值 Unicode值
* '0'-'9' 48-57 \u0030-\u0039
* 'A'-'Z' 65-90 \u0041-\u005A
* 'a'-'z' 97-122 \u0061-\u007A
*/
System.out.println("A"+'\u0061'+"B");
6.2 关于字符的运算
//6.2 关于字符的运算
System.out.println("***6.2 关于字符的运算***");
/*自增和自减操作符也可用在 char 型变量上,这会得到该字符之
* 前或之后的Unicode字符。例如,下面的语句显示字符b :
*/
char ch='a';
System.out.println(++ch);
System.out.println(ch++);
/*char型数据可以转换成任意一种数值类型,反之亦然
* 将整数(32位)转换成char型(16位)数据时,只用到该数据的低十六位,
* 其余部分都被忽略
*/
char ch1=(char)0xAB0041;//(0041)16->(65)10->'A' 相当于char(65)
System.out.println(ch1);
/*要将一个浮点值转换成char型时,
* 首先将浮点值转换成int型,
* 然后将这个整型值转换为char型
*/
char ch2=(char)65.25;
System.out.println(ch2);
/*当一个char型数据转换成数值型(int、double等)时,
* 这个字符的 Unicode码就被转换成某个特定的数值类型
*/
int i=(int)'A';
System.out.println(i);
/*0~FFFF 的任何一个十六进制正整数都可以隐式地转换成字符型数据。
* 而不在此范围内的任何其他数值都必须显式地转换为 char型
*/
char ch4=(char)0xAB0041;//不强制转换会报错 0xAB0041>0xFFFF
char ch5=0x0041;//0x0041<0xFFFF,可以隐式转换 与char ch5=65、char ch5='\u00041'一样
System.out.println("ch4="+ch4+" ch5="+ch5);
/*所有数值操作符都可以用在 char型操作数上。
* 如果另一个操作数是一个数字或字符,那么char型操作数就会被自动转换成一个数字。
* 如果另一个操作数是一个字符串,字符就会与该字符串相连
*/
int i1='2'+'3';//相当于50+51
System.out.println("i1 is "+i1);
int j=2+'a';//相当于2+97
System.out.println("j is "+j);
System.out.println("Chapter M"+'2');
char ch6='2'+'3';//相当于50+51=101 对应字符为e
char ch7='2'+3;//相当于2+3=5
System.out.println("char ch6="+ch6);
System.out.println("char ch7="+ch7);
6.3 case6-整数转16进制表示
/*已知:
* 0~9的十六进制表示和十进制一样
* 10~15的十六进制表示为A,B,C,D,E,F
* 需求:
* 提示用户输入0-15中的一个数,
* 用程序将其转换为十六进制表示法的单个字符,并输出
* 限制:
* 用户只能输入0~15
*/
//6.3 case6-整数转16进制
System.out.println("***6.3 case6-整数转16进制***");
/*已知:
* 0~9的十六进制表示和十进制一样
* 10~15的十六进制表示为A,B,C,D,E,F
* 需求:
* 提示用户输入0-15中的一个数,
* 用程序将其转换为十六进制表示法的单个字符,并输出
* 限制:
* 用户只能输入0~15
*/
//15->F
//大于9:'A'+(x-10);<=9:""+x
System.out.println("请输入0-15中的一个数:");
Scanner input = new Scanner(System.in);
int x=input.nextInt();
//char result=x>9?(char)('A'+(x-10)):((char)(x+'0'));
char result=(char)(x>9?'A'+(x-10):x+'0');
System.out.println(x+"对应的16进制为"+result);
6.4 String,初步认识类、对象和方法
//6.4 String,初步认识类、对象和方法
System.out.println("***6.4 String,初步认识类、对象和方法***");
/*字符串操作是程序设计中最常见的行为
* 从概念上讲,Java字符串就是unicode字符序列
* String不是基本数据类型,而是引用数据类型...
* 字符串声明与赋值:String name="zhangsan " ;
* 这有点像基本数据类型,实际上不是...
*/
/*“+"除用于算术加法运算外,还可用于对字符串进行连接操作
* int id = 800 +90;
* string s = "hello"+ "world " ;
* “+"操作符两侧的操作数中只要有一个是字符串(string )类型,系统会自动将另一个操作数转换为字符串然后再进行连接。
* int c = 12;
* system.out.println ( "c=" + c) ;
* 注意这样一个问题:
* System.out.println ( "c="+ 2 + 2 );
* 和System.out.println (2 +2+ "=c") ;
*/
System.out.println("c="+2+2);
System.out.println("c="+(2+2));
System.out.println(2+2+"=c");
/*字符串字面量,不再是一个基本数据类型,
* 虽然可以使用=和+运算符,但字符串字面量是一个"对象”
* 对象要比基木数据类型复杂得多,对象可以认为是多个其他数据的组合体
*/
/*
* string name = new string("zhangsan") ;name叫做对象的句柄/引用
* String是类名,等号右侧是一个新建的对象, name是对象的句柄
* 对象的一个显著特征是,有一系列可调用的方法(用.符号)
* int len = name .length ();
* 或者int len = new string("zhangsan").length() ;
* 通常我们会操作句柄而不是直接操作对象
* char c = name.charAt(1) ;操作句柄(遥控器)与操作对象(电视上的按钮)是等效的
*/
6.5 API的查阅以及方法调用示例
Java 8 中文版 - 在线API中文手册 - 码工具 (matools.com)
//6.5 API的查阅以及方法调用示例
System.out.println("***6.5 API的查阅以及方法调用示例***");
//1.得到或者创建对象,并赋值给一个句柄(引用类型的变量)
String name="abc123";
//2.在句柄上调用各种方法,如果方法有参数,需要传递参数
//3.如果方法有返回值,我们可以接收这个返回值
int len=name.length();
char charAt1=name.charAt(1);
System.out.println("长度为"+len);
System.out.println("第一个字符为"+charAt1);//b,索引从0开始
//API https://docs.oracle.com/javase/8/docs/api/
String upperName=name.toUpperCase();
System.out.println("name大写形式:"+upperName);
6.6 case7-猜猜你的生日号数
/*每次输出一个16个数字组成的数字集合(1-31),询问生日号数是否在内,在输入1,不在输入0;
* 进行5次判断后输出生日号数
*/
/*思路,利用5位二进制数,从右到左,每次询问这一位是1还是0,
*即把这一位为1或0的所有数字(十进制)输出,然后判断下一位
*询问5次后,相当于确定了一个二进制数,转换为10进制输出即可
*综合运用二进制、输入输出、移位、拼接
*1.准备代表5个集合的五个字符串,这个字符串要在内部换行
*编号1的集合的内容:第1位上为1的1~31间数字的集合
*编号2的集合的内容:第2位上为1的1~31间数字的集合
*编号3的集合的内容:第3位上为1的1~31间数字的集合
*编号4的集合的内容:第4位上为1的1~31间数字的集合
*编号5的集合的内容:第5位上为1的1~31间数字的集合
*2.准备好之后,开始交互,每次询问得到的结果与之前的结果累加
*day=0
*依次询问
*是否在第1个集合里面,用户输入0或者1day +=answer*1; 1
*是否在第2个集合里面,用户输入0或者1day +=answer*(1<<1); 2
*是否在第3个集合里面,用户输入0或者1day +=answer*(1<<2); 4
*是否在第4个集合里面,用户输入0或者1day +=answer*(1<<3); 8
*是否在第5个集合里面,用户输入0或者1day +=answer*(1<<4); 16
[1,1+2+4+8+16]=[1,31]
*3.最终的day就是生日的号数
*/
//6.6 case7-猜猜你的生日号数
System.out.println("***6.6 case7-猜猜你的生日号数***");
String set1=
"1 3 5 7\n"+
"9 11 13 15\n"+
"17 19 21 23\n"+
"25 27 29 31";
String set2=
"2 3 6 7\n"+
"10 11 14 15\n"+
"18 19 22 23\n"+
"26 27 30 31";
String set3=
"4 5 6 7\n"+
"12 13 14 15\n"+
"20 21 22 23\n"+
"28 29 30 31";
String set4=
"8 9 10 11\n"+
"12 13 14 15\n"+
"24 25 26 27\n"+
"28 29 30 31";
String set5=
"16 17 18 19\n"+
"20 21 22 23\n"+
"24 25 26 27\n"+
"28 29 30 31";
int day=0;
//第1次询问
Scanner sc=new Scanner(System.in);
System.out.println("你的生日号数在这里边吗?\n");
System.out.println(set1);
System.out.println("是输入1,否输入0");
int answer=sc.nextInt();
day+=answer*1;
//第2次询问
System.out.println("你的生日号数在这里边吗?\n");
System.out.println(set2);
System.out.println("是输入1,否输入0");
answer=sc.nextInt();
day+=answer*(1<<1);
//第3次询问
System.out.println("你的生日号数在这里边吗?\n");
System.out.println(set3);
System.out.println("是输入1,否输入0");
answer=sc.nextInt();
day+=answer*(1<<2);
//第4次询问
System.out.println("你的生日号数在这里边吗?\n");
System.out.println(set4);
System.out.println("是输入1,否输入0");
answer=sc.nextInt();
day+=answer*(1<<3);
//第5次询问
System.out.println("你的生日号数在这里边吗?\n");
System.out.println(set5);
System.out.println("是输入1,否输入0");
answer=sc.nextInt();
day+=answer*(1<<4);
System.out.println("你的生日号数为"+day);
6.7 case8-输出大写金融
/*需求
* 给定5位整数2位小数的金额,请将其转换为半中文大写金额
* 89735.12->8万9千7百3十5元1角2分
* 限制
* 因为目前掌握知识较少,还做不到全中文
*/
//思路:取余取低位(舍高位),除法取高位(舍低位)
两种方法:
//6.7 case8-输出大写金额
System.out.println("***6.7 case8-输出大写金额***");
/*需求
* 给定5位整数2位小数的金额,请将其转换为半中文大写金额
* 89735.12->8万9千7百3十5元1角2分
* 限制
* 因为目前掌握知识较少,还做不到全中文
*/
//思路:取余取低位(舍高位),除法取高位(舍低位)
@SuppressWarnings("resource")
Scanner sc1=new Scanner(System.in);
System.out.println("请输入5位整数2位小数的金额");
double d=sc1.nextDouble();
int k=(int)(d*100);//总分
/*法1:
* int d1=k%10;//分
k/=10;//总角
int d2=k%10;//角
k/=10;//总元
int d3=k%10;//元
k/=10;//总十
int d4=k%10;//十
k/=10;//总百
int d5=k%10;//百
k/=10;//总千
int d6=k%10;//千
k/=10;//总万
int d7=k%10;//万
System.out.println(d+"的大写金额为"+d7+"萬"+d6+"仟"+d5+"佰"+d4+"拾"+d3+"圆"+d2+"角"+d1+"分");*/
//法2:
String res="";
int fen=(int)(d*100);
int wan=fen/1000000;//万分位数字
res+=wan+"萬";
fen=fen%1000000;
int qian=fen/100000;//千分位数字
res+=qian+"仟";
fen=fen%100000;
int bai=fen/10000;//百分位数字
res+=bai+"佰";
fen=fen%10000;
int shi=fen/1000;//十分位数字
res+=shi+"拾";
fen=fen%1000;
int yuan=fen/100;//元分位数字
res+=yuan+"圆";
fen=fen%100;
int jiao=fen/10;//角分位数字
res+=jiao+"角";
fen=fen%10;
int fenfen=fen;//分分位数字
res+=fenfen+"分";
System.out.println(d+"的大写金额为"+res);
第7章
package qianzhi;
import java.text.NumberFormat;
import java.util.Iterator;
import java.util.Scanner;
public class T7 {
@SuppressWarnings("unused")
public static void main(String[] args) {
// TODO 自动生成的方法存根
// test1();
// test2();
// case9();
// case10();
// case11();
// case12();
// case13();
// case14();
// case15();
// case16();
// case17();
// case18();
// test3();
// case19();
// case20();
// case21();
// case22();
// case23();
// case24();
case25();
}
@SuppressWarnings("unused")
// 7.1 if语法介绍
public static void test1() {
System.out.println("***7.1 if语法介绍***");
if (false) {
System.out.println(1);
} else if (false) {
System.out.println(2);
} else if (true) {
System.out.println(3);// 条件成立,后边的不会执行了
} else if (true) {
System.out.println(4);
} else {
System.out.println(5);
}
int x = 12;
if (x > 4) {
System.out.println("test 1");
} else if (x > 9) {
System.out.println("test 2");
} else {
System.out.println("test 3");
}
}
// 7.2 switch语法介绍
public static void test2() {
System.out.println("***7.2 switch语法介绍***");
/*
* JDK1.7开始 : switch接受string类型的表达式 在此之前,只接受byte、short、char、int——实际上就是int 还接受枚举值
*/
int month = 3;
switch (month) {// 从
case 1:
System.out.println("January");
break;
case 2:
System.out.println("February");
break;
case 3:
System.out.println("March");
break;
case 4:
System.out.println("April");
break;
case 5:
System.out.println("May");
break;
case 6:
System.out.println("June");
break;
case 7:
System.out.println("July");
break;
case 8:
System.out.println("August");
break;
case 9:
System.out.println("September");
break;
case 10:
System.out.println("October");
break;
case 11:
System.out.println("November");
break;
case 12:
System.out.println("December");
break;
default:
System.out.println("没有这样的月份,你是外星人吧");
// break;
}
String mon = "Jan";
switch (mon) {
case "Jan":
System.out.println("January");
break;
case "Feb":
System.out.println("February");
break;
default:
break;
}
}
// 7.3 case9-10 if-else使用示例
public static void case9() {
System.out.println("***case9-闰年***");
/*
* 已知 如果年份能被4整除且不能被100整除,或者能被400整除,则为闰年 需求 编写程序,读取用户输入的一个整数作为年份,并且确定是否为闰年,输出结果
* 如果输入的年份小于1582则输出错误信息,因为在此之前公历还未被采用
*/
Scanner input = new Scanner(System.in);
System.out.println("输入年份,不小于1582");
int year = input.nextInt();
if (year < 1582) {
System.out.println("输入错误,数据不合法");
} else if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
System.out.println(year + "是闰年");
} else {
System.out.println(year + "不是闰年");
}
}
public static void case10() {
System.out.println("***case10-10进制转16进制字符(case6改写)***");
// case10:改写case6 (0~15十进制转十六进制字符的程序),使用if-else
Scanner input = new Scanner(System.in);
System.out.println("请输入0-15的10进制整数");
int x = input.nextInt();
char res;
if (x>=0&&x<=15) {
if (x>9) {
res = (char) ('A' + (x - 10));
System.out.println(x + "对应16进制数为" + res);
} else {
res=(char) ('0'+(x-0));
//res=(char) x;
System.out.println(x + "对应16进制数为" + res);
}
}
else {
System.out.println("输入非法");
}
}
//7.4 case11-16进制字符转整数
public static void case11() {
System.out.println("***7.4 case11-16进制字符转整数***");
/*已知常用字符的unicode值
*用户输入0~9、A-F、a-f中的一个字符用来表示一个十六进制数,
*程序输出这个数的十进制形式
*提示: '0'=48 'A'=65 'a'=97一示例,输入:D输出:13
*/
Scanner input = new Scanner(System.in);
System.out.println("请输入一个16进制字符");
int res;
char x=input.next().charAt(0);//Scanner里边没有nextChar()方法
if (x>='0' && x<='9') {//x>=48&&x<=57
//res=x-'0';
System.out.println(x+"对应10进制为"+x);
}
else if (x>='A' && x<='Z') {//x>=65&&x<=70
res=x-'A'+10;
System.out.println(x+"对应10进制为"+res);
}
else if(x>='a'&x<='z'){//x>=97&x<=102
res=x-'a'+10;
System.out.println(x+"对应10进制为"+res);
}
else {
System.out.println("输入非法");
}
}
//7.5、7.6 case12-个税计算器
public static void case12() {
System.out.println("***7.5、7.6 case12-个税计算器***");
/*已知:
* 工资个税的计算公式为:
* 应纳税额=(工资薪金所得-"五险一金”个人负担部分-扣除数)×适用税率―速算扣除数
* 2011年9月1日起调整后的7级超额累进税率:扣除数为3500元。
*·全月应纳税所得额 税率 速算扣除数(元)
*·全月应纳税额不超过1500元 3% 0
*·全月应纳税额超过1500元至4500元 10% 105
*·全月应纳税额超过4500元至9000元 20% 555
*·全月应纳税额超过9000元至35000元 25% 1005
*·全月应纳税额超过35000元至55000元 30% 2755
*·全月应纳税额超过55000元至80000元 35% 5505
*·全月应纳税额超过80000元 45% 13505
*/
//假定"五险一金”个人负担部分等于税前工资的10%
Scanner sc=new Scanner(System.in);
System.out.println("输入税前工资:");
double salary=sc.nextDouble();//原工资
double tax=0;//税额
double taxRate=0;//税率
double deduct=0;//速算扣除数
if (salary<0) {
System.out.println("不会有人上班给别人发钱吧?");
System.exit(0);//当前程序退出
}
//应纳税所得额=工资薪金所得-"五险一金”个人负担部分-扣除数
double taxableIncome=salary-salary*0.1-3500;
if (taxableIncome<=0) {
System.out.println("少年,你的工资太低了,不用交税!");
System.exit(0);
}
if (taxableIncome<=1500) {
taxRate=0.03;
deduct=0;
// tax=taxableIncome*0.03-0;
// System.out.println("应纳税所得额 "+taxableIncome+" 税率 3% 速算扣除数 0");
// System.out.println("应缴税款:"+tax);
// System.out.println("实发工资:"+(salary*(1-0.1)-tax));//实发工资=原工资-"五险一金”个人负担部分-应缴税款
}
else if (taxableIncome<=4500) {
taxRate=0.1;
deduct=105;
// tax=taxableIncome*0.1-105;
// System.out.println("应纳税所得额 "+taxableIncome+" 税率 10% 速算扣除数 105");
// System.out.println("应缴税款:"+tax);
// System.out.println("实发工资:"+(salary*(1-0.1)-tax));
}
else if (taxableIncome<=9000) {
taxRate=0.2;
deduct=555;
// tax=taxableIncome*0.2-555;
// System.out.println("应纳税所得额 "+taxableIncome+" 税率 20% 速算扣除数 555");
// System.out.println("应缴税款:"+tax);
// System.out.println("实发工资:"+(salary*(1-0.1)-tax));
}
else if (taxableIncome<=35000) {
taxRate=0.25;
deduct=1005;
// tax=taxableIncome*0.25-1005;
// System.out.println("应纳税所得额 "+taxableIncome+" 税率 25% 速算扣除数 1005");
// System.out.println("应缴税款:"+tax);
// System.out.println("实发工资:"+(salary*(1-0.1)-tax));
}
else if (taxableIncome<=55000) {
taxRate=0.3;
deduct=2755;
// tax=taxableIncome*0.3-2755;
// System.out.println("应纳税所得额 "+taxableIncome+" 税率 30% 速算扣除数 2755");
// System.out.println("应缴税款:"+tax);
// System.out.println("实发工资:"+(salary*(1-0.1)-tax));
}
else if (taxableIncome<=80000) {
taxRate=0.35;
deduct=5505;
// tax=taxableIncome*0.35-5505;
// System.out.println("应纳税所得额 "+taxableIncome+" 税率 35% 速算扣除数 5505");
// System.out.println("应缴税款:"+tax);
// System.out.println("实发工资:"+(salary*(1-0.1)-tax));
}
else {
taxRate=0.45;
deduct=13505;
// tax=taxableIncome*0.45-13505;
// System.out.println("应纳税所得额 "+taxableIncome+" 税率 45% 速算扣除数 13505");
// System.out.println("应缴税款:"+tax);
// System.out.println("实发工资:"+(salary*(1-0.1)-tax));
}
NumberFormat nf=NumberFormat.getNumberInstance();//格式化
nf.setMaximumFractionDigits(2);//最大2位小数
tax=taxableIncome*taxRate-deduct;
System.out.println("应纳税所得额 "+nf.format(taxableIncome)+" 税率 "+taxRate+" 速算扣除数 "+deduct);
System.out.println("应缴税款:"+nf.format(tax));
System.out.println("实发工资:"+nf.format(salary*(1-0.1)-tax));//实发工资=原工资-"五险一金”个人负担部分-应缴税款
}
//7.7 case13-简单的算术计算器
public static void case13() {
System.out.println("***7.7 case13-简单的算术计算器***");
/*需求
* 编写程序,读取用户输入的操作数与符号,计算结果并输出
* 输入样例:4 + 3
* 输出样例:4 + 3 = 7
* 支持+ ― * / %
* 综合运行输入,运算,switch
*/
Scanner sc=new Scanner(System.in);
System.out.println("请输入计算式");
double a=sc.nextDouble();
String operator=sc.next();
double b=sc.nextDouble();
double res=0;
switch(operator) {
case "+":
res=a+b;
break;
case "-":
res=a-b;
break;
case "*":
res=a*b;
break;
case "/":
res=a/b;
break;
case "%":
res=a%b;
break;
default:
res=Double.NaN;
}
System.out.printf("%.2f %s %.2f = %.2f\n",a,operator,b,res);//printf格式化输出
}
//7.8 case14-while语句让程序反复执行
public static void case14() {
System.out.println("***7.8 case14-while语句让程序反复执行(case9改)***");
/*
* 修改之前判断闰年的程序,让用户可以同时测试多个年份,
* 用户输人“-1"时,终止程序
* 之前的案例都可以改写.(如个税计算器),让用户可以反复输入
* 设定某种特定的输入,用来终止循环
*/
// System.out.println("***case9-闰年***");
// /*
// * 已知 如果年份能被4整除且不能被100整除,或者能被400整除,则为闰年 需求 编写程序,读取用户输入的一个整数作为年份,并且确定是否为闰年,输出结果
// * 如果输入的年份小于1582则输出错误信息,因为在此之前公历还未被采用
// */
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("输入年份,不小于1582");
int year = input.nextInt();
if (year==-1) {
System.out.println("程序结束");
break;
}
if (year < 1582) {
System.out.println("输入错误,数据不合法");
} else if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
System.out.println(year + "是闰年");
} else {
System.out.println(year + "不是闰年");
}
}
// System.out.println("输入年份,不小于1582");
// int year = input.nextInt();
// while (year!=-1) {
// if (year < 1582) {
// System.out.println("输入错误,数据不合法");
// } else if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
// System.out.println(year + "是闰年");
// } else {
// System.out.println(year + "不是闰年");
// }
// System.out.println("输入年份,不小于1582");
// year = input.nextInt();
// }
// System.out.println("程序结束");
//case12改
Scanner sc=new Scanner(System.in);
NumberFormat nf=NumberFormat.getNumberInstance();//格式化
nf.setMaximumFractionDigits(2);//最大2位小数
while (true) {
System.out.println("输入税前工资:");
double salary=sc.nextDouble();//原工资
double tax=0;//税额
double taxRate=0;//税率
double deduct=0;//速算扣除数
if (salary<0) {
// if (salary==-1) {
// System.out.println("程序结束");
// break;
// }
System.out.println("不会有人上班给别人发钱吧?");
System.out.println("程序结束");
System.exit(0);//当前程序退出,代替了break
}
//应纳税所得额=工资薪金所得-"五险一金”个人负担部分-扣除数
double taxableIncome=salary-salary*0.1-3500;
if (taxableIncome<=0) {
System.out.println("少年,你的工资太低了,不用交税!");
System.exit(0);
}
if (taxableIncome<=1500) {
taxRate=0.03;
deduct=0;
}
else if (taxableIncome<=4500) {
taxRate=0.1;
deduct=105;
}
else if (taxableIncome<=9000) {
taxRate=0.2;
deduct=555;
}
else if (taxableIncome<=35000) {
taxRate=0.25;
deduct=1005;
}
else if (taxableIncome<=55000) {
taxRate=0.3;
deduct=2755;
}
else if (taxableIncome<=80000) {
taxRate=0.35;
deduct=5505;
}
else {
taxRate=0.45;
deduct=13505;
}
tax=taxableIncome*taxRate-deduct;
System.out.println("应纳税所得额 "+nf.format(taxableIncome)+" 税率 "+taxRate+" 速算扣除数 "+deduct);
System.out.println("应缴税款:"+nf.format(tax));
System.out.println("实发工资:"+nf.format(salary*(1-0.1)-tax));//实发工资=原工资-"五险一金”个人负担部分-应缴税款
}
}
//7.9 case15-和女朋友聊天的正确姿势
public static void case15() {
System.out.println("***7.9 case15-和女朋友聊天的正确姿势***");
/*设计一个简易的聊天程序,使用者为男性,程序模拟的是女朋友
*对女朋友说"你又胖了",收到回复"滚! "
*对女朋友说"你是最美的",收到回复"你这样说,人家会害羞啦......"
*对女朋友说"娘子,夜深了",收到回复"不用说了,先把灯关上吧",程序中止
*你还可以设定一些固定的对答,但只有上一条对答会终止程序
*固定对答之外,无论你说什么,都会收到回复"你说什么,我听不懂啦....
*/
Scanner sc=new Scanner(System.in);
//switch
while (true) {
System.out.println("你对女朋友说:");
String talk=sc.nextLine();
String anwser="";
switch(talk) {
case "你又胖了":
anwser="滚!";
break;
case "你是最美的":
anwser="你这样说,人家会害羞啦......";
break;
case "娘子,夜深了":
anwser="不用说了,先把灯关上吧";
break;
default:
anwser="你说什么,我听不懂啦....";
}
System.out.println("女朋友回答:"+anwser);
if(anwser.equals("不用说了,先把灯关上吧")) {//不能用anwser=="不用说了,先把灯关上吧"???
System.out.println("聊天结束");
break;
}
}
// //if语句
// while (true) {
// System.out.println("说吧:");
// String content = sc.nextLine();
// if(content.equals("你又胖了")){
// System.out.println("滚!");
// }
// else if(content.equals("你是最美的!")){
// System.out.println("你这样说,人家会害羞呢...." );
// }
// else if(content.equals("娘子,夜深了")){
// System.out.println("不用说了,先把灯关上吧!");
// break;
// }
// else {
// System.out.println("你说什么,我听不懂啦....");
// }
// }
/*编写一个正确的循环对编程新手来说,并不是件容易的事。
* 编写循环时应该考虑如下三个步骤:
* 第一步:确定需要重复的语句,考虑是否真的有必要重复,不必要就放在循环外面
* 第二步:将这些语句放在一个循环中
* 第三步:为循环继续条件编码,并为控制循环添加适合的语句
* 此外,还需精心设计变量
*/
}
//7.10、7.11 case16-改进十进制转16进制
public static void case16() {
System.out.println("***7.10 case16-改进十进制转16进制***");
/*
* 背景:
* 之前的程序只能处理0-15,转换为单个字符
* 需求:
* 现在我们要处理任何整数如2345,要将其转换为16进制表示法的字符串并输出
* 已知:十进制数123 被转换为十六进制数7B。
* 这个转换过程如下:将123 除以 16,余数为11(十六进制的B),商为7。
* 继续将7除以 16,余数为7 ,商为 0。因此 7B就是123 的十六进制数
* 思路:利用循环,续商留余
*/
Scanner sc=new Scanner(System.in);
while (true) {
String res="";
System.out.println("请输入一个10进制数");
int x=sc.nextInt();
if (x<0) {
System.out.println("程序结束");
break;
}
while (x!=0) {
if(x%16>9) {
// res+=(char)('A'+(x%16-10));
res=(char)('A'+(x%16-10))+res;
}
else {
// res+=x%16;
res=x%16+res;
}
x=x/16;
}
// System.out.print(x+"对应16进制数为");
// int i=res.length()-1;
// while (i>=0) {
// System.out.print(res.charAt(i));
// i--;
// }
System.out.println("对应16进制数为"+res);
}
}
//7.12 case17-10进制转2进制
public static void case17() {
System.out.println("***7.12 case17-10进制转2进制***");
Scanner sc=new Scanner(System.in);
int count=0;//用于计数
String res="";
System.out.println("请输入一个10进制数");
int x=sc.nextInt();
while (x!=0) {
res=x%2+res;
x=x/2;
count++;
if (count%4==0&&x!=0) {//每4位加一个_
res="_"+res;
}
System.out.println("对应2进制数为"+res);
}
}
//7.13、7.14 case18-嵌套的循环
public static void case18() {
System.out.println("***7.13、7.14 嵌套的循环***");
/*(嵌套的循环)现在需要改进上一个案例:
* 用户可以反复测试,直到用户输入一个负数,程序终止
*/
Scanner sc=new Scanner(System.in);
while (true) {
int count=0;//用于计数
String res="";
System.out.println("请输入一个10进制数");
int x=sc.nextInt();
if (x<0) {
System.out.println("程序结束");
break;
}
//负数的2进制表示
/*类比:一个圆,一个128个单位,从原点后走1步与往前走127是一样的
* -128 -127 ...-2 -1
* 0 1 ...126 127
* 以8bit为例:两个数相差128,即2^7
* -128->1000 0000 0--->0000 0000
* -127->1000 0001 1--->0000 0001
* -1--->1111 1111 127-->0111 1111
* -2--->1111 1110 126-->0111 1110
* 规律:对应的高位(符号位)不同,低位一样
* 思路:
* 先算出2^7+x的低7位,再把高位补1
* 对于int(32位):先算出2^31+x的低31位,然后把高位补1
*/
// if(x<0) {
// x=(int) (Math.pow(2, 31)+x);
// }
while (x!=0) {
res=x%2+res;
x=x/2;
count++;
if (count%4==0&&x!=0) {//每4位加一个_
res="_"+res;
}
}
System.out.println("对应2进制数为"+res);
}
}
//7.15 趋于完整的十进制转二进制程序
public static void test3() {
System.out.println("***7.15 趋于完整的十进制转二进制程序***");
Scanner sc=new Scanner(System.in);
while (true) {
int count=0;//用于计数
String res="";
System.out.println("请输入一个10进制数");
int x=sc.nextInt();
int t=x;
// if (x<0) {
// System.out.println("程序结束");
// break;
// }
//负数的2进制表示
/*类比:一个圆,一个128个单位,从原点后走1步与往前走127是一样的
* -128 -127 ...-2 -1
* 0 1 ...126 127
* 以8bit为例:两个数相差128,即2^7
* -128->1000 0000 0--->0000 0000
* -127->1000 0001 1--->0000 0001
* -1--->1111 1111 127-->0111 1111
* -2--->1111 1110 126-->0111 1110
* 规律:对应的高位(符号位)不同,低位一样
* 思路:
* 先算出2^7+x的低7位,再把高位补1
* 对于int(32位):先算出2^31+x的低31位,然后把高位补1
*/
//边界值2147483647和-2147483648需要测试一下
if(x<0) {
x=(int) (Math.pow(2, 31)+x);
}
while (x!=0) {
res=x%2+res;
x=x/2;
count++;
if (count%4==0) {//每4位加一个_
res="_"+res;
}
}
//高位补零
while (count<31) {
count++;
if (count%4==0) {//每4位加一个_
res="_"+0+res;
}
else {
res=0+res;
}
}
if (t<0) {
res=1+res;//负数高位补1
}
else {
res=0+res;//正数补0
}
System.out.println("对应2进制数为"+res);
}
}
//7.16 do-while语法及应用
public static void case19() {
System.out.println("***7.16 case19-do-while语法及应用(case16改)***");
/*case16中,用户直接输入0,将没有任何输出,怎么破?改成do-while
*/
Scanner sc=new Scanner(System.in);
while (true) {
String res="";
System.out.println("请输入一个10进制数");
int x=sc.nextInt();
if (x<0) {
System.out.println("程序结束");
break;
}
do{
if(x%16>9) {
// res+=(char)('A'+(x%16-10));
res=(char)('A'+(x%16-10))+res;
}
else {
// res+=x%16;
res=x%16+res;
}
x=x/16;
}while(x!=0);
// System.out.print(x+"对应16进制数为");
// int i=res.length()-1;
// while (i>=0) {
// System.out.print(res.charAt(i));
// i--;
// }
System.out.println("对应16进制数为"+res);
}
}
//7.17 for循环语法及特点
public static void case20() {
System.out.println("***7.17 for循环语法及特点 case20-while改for***");
/*for(初始化语句;布尔语句;循环后动作){
* 循环体
* }
*/
// for (int i = 0; i < 100; i++) {
// System.out.println("Welcome to java"+i);
// }
// for (int i = 0; i < 10; i++) {
// System.out.print("*");
// }
// System.out.println();
// //等价于:
// int i=0;
// while (i<10) {
// System.out.print("*");
// i++;
// }
/*通常,如果已经提前知道重复次数,那就采用for循环,
* 例如,需要打印一条信息100次时
* 如果无法确定重复次数,就采用while 循环,就像读入一些数值直到读入0为止的这种情况
* 如果在检验继续条件前需要执行循环体(至少1次),就用do-while 循环替代 while 循环
*/
//case16
Scanner sc=new Scanner(System.in);
while (true) {
System.out.println("请输入一个10进制数");
int x=sc.nextInt();
String hex="";
char res='0';
int yu;
if (x<0) {
System.out.println("程序结束");
break;
}
for (int shang=x; shang!=0; shang=shang/16) {
yu=shang%16;
if(yu>9) {
res=(char)('A'+(yu-10));
}
else {
res=(char) ((yu-0)+'0');
}
hex=res+hex;
}
System.out.println("对应16进制数为"+hex);
}
}
//7.18 case21-生成随机字符串
public static void case21() {
System.out.println("***7.18 case21-生成随机字符串***");
/*
* 已知字符范围是\u0000-\uFFFF
* 需求:
* 用户给定一个长度
* 程序生成该长度的字符串,每个字符都是随机的
* 输出该字符串
* 扩展:
* 稍加改变,即可让用户反复测试
* 体会到while和for的不同
*/
Scanner sc = new Scanner(System.in);
System.out.println("输入长度:");
int n=sc.nextInt();
String res="";
for (int i = 0; i < n; i++) {
char c=(char) (Math.random()*(0xffff+1));//[0x0000,0xffff+1)
if ((c>='0'&&c<='9')||(c>='a'&&c<='z')||(c>='A'&&c<='Z')) {//可以用这种方式限定输出
res+=c;
}
else {
i--;
}
}
System.out.println("得到的字符串为:"+res);
//while实现,不需要else了
System.out.println("输入长度:");
n=sc.nextInt();
int i=0;
res="";
while (i<n) {
char c=(char) (Math.random()*(0xffff+1));//[0x0000,0xffff+1)
if ((c>='0'&&c<='9')||(c>='a'&&c<='z')||(c>='A'&&c<='Z')) {
res+=c;
i++;
}
}
System.out.println("得到的字符串为:"+res);
}
//7.19 case22-求PI的近似值
public static void case22() {
System.out.println("***7.19 case22-求PI的近似值***");
/*
* case22 :求Π的近似值
* 已知
* Π=4(1-1/3+1/5-1/7+1/9-1/11+...+((-1)^(i+1))/(2i-1))
* 编写程序,显示当i=10000,20000,100000 时的值
*/
Scanner sc=new Scanner(System.in);
System.out.println("输入迭代次数:");
int n=sc.nextInt();
double res=0;
for (int i = 1; i <= n; i++) {
// if (i%2!=0) {
// res+=1.0/(2*i-1);//需要浮点型除法!!!
// }
// else {
// res-=1.0/(2*i-1);
// }
res+=Math.pow(-1, i+1)/(2*i-1);
}
System.out.println("Π的近似值为:"+4*res);
}
//7.20、7.21 case23-回文字符串的判断
public static void case23() {
System.err.println("***7.20、7.21 case23-回文字符串的判断***");
/*
* case23:回文串 (Palindrome)的判断
* 如果一个字符串从前往后,以及从后往前是一样的,那么它就是一个回文。
* 例如, " mom"、" dad",以及" noon",都是回文
* 编写一个程序,提示用户输人一个字符串,
* 然后给出该字符串是否是回文
*/
//边界测试:空字符串与单字符字符串 边界错误就是逻辑错误
Scanner sc=new Scanner(System.in);
System.out.println("输入一个字符串");
String s=sc.nextLine();
boolean flag=true;
for (int i = 0; i < s.length()/2; i++) {
if (s.charAt(i)!=s.charAt(s.length()-1-i)) {
flag=false;
break;
}
}
// if (flag==true) {
// System.out.println(s+"是回文字符串");
// }
// else {
// System.out.println(s+"不是回文串");
// }
System.out.println(s+(flag?"是":"不是")+"回文字符串");
/* 1.循怀怎么控制 何时退出,用什么变量来控制
* 2.控制条件
* 3.每次循环后,控制变量有何变化
* 4.最终要什么结果?是:否
* 5.怎么在循环中逐步得到结果
*/
//双指针思路
// boolean isPalindrome=false;
// int begin=0,end=s.length()-1;
// while (begin<end&&s.charAt(begin)==s.charAt(end)) {
// begin++;
// end--;
// }
// if (begin>=end) {//当字符串为偶数长度,跳出循环后begin会大于end
// isPalindrome=true;
// }
// System.out.println(s+(isPalindrome?"是":"不是")+"回文字符串");
/*这几种情况while 更合适:
* 1、不确定次数
* 2、多个控制变量
* 3、控制变量的初始化必须放在循环外面的时候
*/
}
//7.22 case24-打印九九表(嵌套for循环)
public static void case24() {
System.out.println("***7.22 case24-打印九九表***");
/* case24 :九九乘法表
* 背景:还记得小时候背九九乘法表吗?
* 使用嵌套for循环打印一个乘法表(MultiplicationTable)
*/
//外层控制行(9行),内层控制列(第1行1列,第2行2列...第n行n列)
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
// System.out.printf("%d * %d = %d\t",j,i,i*j);
System.out.print(j+"x"+i+"="+i*j+"\t");
}
System.out.println();
}
}
//7.23、7.24、7.25 case25-最大公约数的几种解法
@SuppressWarnings("resource")
public static void case25() {
System.out.println("***7.23、7.24、7.25 case25-最大公约数的几种解法***");
/*法1:暴力破解法
*若x==y,则最大公约数两者选其一
*若x!=y,选取小(假如为x)的作为迭代次数,从1开始依次判断是否同时能被两者整除,
*最后一个符合的即为最大公约数
*/
// Scanner sc=new Scanner(System.in);
// System.out.println("x=");
// int x=sc.nextInt();
// System.out.println("y=");
// int y=sc.nextInt();
// int gcd=1;
// if (x>y) {//让x<y
// x=x^y;
// y=x^y;
// x=x^y;
// }
// else if (x==y) {
// gcd=x;
// System.out.println("最大公约数是"+gcd);
// System.exit(0);//退出程序
// }
// for (int i = 1; i <= x; i++) {
// if (x%i==0&&y%i==0) {
// gcd=i;
// }
// }
// System.out.println("最大公约数是"+gcd);
/*法2:
*基于法1,迭代次数为x/2,但是要单独判断边界,即x能被y整除的情况
*/
// Scanner sc=new Scanner(System.in);
// System.out.println("x=");
// int x=sc.nextInt();
// System.out.println("y=");
// int y=sc.nextInt();
// int gcd=1;
// if (x>y) {
// x=x^y;
// y=x^y;
// x=x^y;
// }
// if (y%x==0) {//包含了x==y 不能用else if,因为它与if互斥,不能满足x<y的情况
// gcd=x;
// System.out.println("最大公约数是"+gcd);
// System.exit(0);//退出程序
// }
// for (int i = 1; i <= x/2; i++) {
// if (x%i==0&&y%i==0) {
// gcd=i;
// }
// }
// System.out.println("最大公约数是"+gcd);
/*法3:
*基于法2,逆向扫描,第一个满足同时能被两者整除的数即为gcd
*/
// Scanner sc=new Scanner(System.in);
// System.out.println("x=");
// int x=sc.nextInt();
// System.out.println("y=");
// int y=sc.nextInt();
// int gcd=1;
// if (x>y) {
// x=x^y;
// y=x^y;
// x=x^y;
// }
// if (y%x==0) {
// gcd=x;
// System.out.println("最大公约数是"+gcd);
// System.exit(0);
// }
// for (int i = x/2; i >= 1; i--) {
// if (x%i==0&&y%i==0) {
// gcd=i;
// break;
// }
// }
// System.out.println("最大公约数是"+gcd);
//以上算法平均时间复杂度为O(n/2)
/*法4:欧几里得算法(辗转相除法)
* if m % n is 0, gcd (m, n) is n.
* Otherwise, gcd(m, n) is gcd(n, m % n).注意m n顺序
* 平均时间复杂度为O(log2(n))
*/
Scanner sc=new Scanner(System.in);
System.out.println("x=");
int x=sc.nextInt();
System.out.println("y=");
int y=sc.nextInt();
int gcd=1;
if (x>y) {
x=x^y;
y=x^y;
x=x^y;
}
else if (x==y) {
gcd=x;
System.out.println("最大公约数是"+gcd);
System.exit(0);//退出程序
}
while (y%x!=0) {
int tmp=x;
x=y%x;
y=tmp;
}
gcd=x;
System.out.println("最大公约数是"+gcd);
}
//最小公倍数=x*y/gcd
/*
* 想要解开这题目首先要了解什么是最小公倍数
* 最小公倍数:是指能同时被a和b整除的最小正整数
* 例如:14 和 6 的最小公倍数有 42 84 126
* 最小的数就是最小公倍数
* 假设:a=6 b=18
* 那么最小公倍数怎么也不可能小于 18
* 1.先找出a和b中的最大数赋值给max,
* 然后用 if 判断最大数max是否能同时%a和b等于零那么它就是最小公倍数
* 如果不行那最大数max++
int main()
{
int a = 0, b = 0;
scanf("%d %d", &a, &b);
int m = a < b ? a : b;
while (m)
{
if (m % a == 0 && m % b == 0)
{
printf("%d\n", m);
break;
}
m++;
}
return 0;
}
* 2.先用辗转相除法求出最大公约数,
* 然后a*b/最大公约数=最小公倍
int main()
{
int a = 0, b = 0;
scanf("%d %d", &a, &b);
int n = a * b;
int m = 0;
while (m = a % b)
{
a = b;
b = m;
}
printf("%d\n", n / b);
}
* 3.创建个 while 循环 if 判断 a * i % b==0
* 看 a 乘于 i 得出的数看能不能被 b 整除
* 如果可以那么它就是最小公倍数
int main()
{
int a = 0, b = 0;
scanf("%d %d", &a, &b);
int i = 1;
while ((a * i) % b != 0)
{
i++;
}
printf("%d\n", i * a);
return 0;
}
* 第三种方法效率最高
* ————————————————
* 版权声明:本文为CSDN博主「欧橘猫」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
* 原文链接:https://blog.csdn.net/m0_66483195/article/details/123508567
*/
}
7.1 if语法介绍
// 7.1 if语法介绍
public static void test1() {
System.out.println("***7.1 if语法介绍***");
if (false) {
System.out.println(1);
} else if (false) {
System.out.println(2);
} else if (true) {
System.out.println(3);// 条件成立,后边的不会执行了
} else if (true) {
System.out.println(4);
} else {
System.out.println(5);
}
int x = 12;
if (x > 4) {
System.out.println("test 1");
} else if (x > 9) {
System.out.println("test 2");
} else {
System.out.println("test 3");
}
}
7.2 switch语法介绍
// 7.2 switch语法介绍
public static void test2() {
System.out.println("***7.2 switch语法介绍***");
/*
* JDK1.7开始 : switch接受string类型的表达式 在此之前,只接受byte、short、char、int——实际上就是int 还接受枚举值
*/
int month = 3;
switch (month) {// 从
case 1:
System.out.println("January");
break;
case 2:
System.out.println("February");
break;
case 3:
System.out.println("March");
break;
case 4:
System.out.println("April");
break;
case 5:
System.out.println("May");
break;
case 6:
System.out.println("June");
break;
case 7:
System.out.println("July");
break;
case 8:
System.out.println("August");
break;
case 9:
System.out.println("September");
break;
case 10:
System.out.println("October");
break;
case 11:
System.out.println("November");
break;
case 12:
System.out.println("December");
break;
default:
System.out.println("没有这样的月份,你是外星人吧");
// break;
}
String mon = "Jan";
switch (mon) {
case "Jan":
System.out.println("January");
break;
case "Feb":
System.out.println("February");
break;
default:
break;
}
}
7.3 case9-10if-else使用示例
/*case9 判断是否为闰年
* 已知 如果年份能被4整除且不能被100整除,或者能被400整除,则为闰年 需求 编写程序,读取用户输入的一个整数作为年份,并且确定是否为闰年,输出结果
* 如果输入的年份小于1582则输出错误信息,因为在此之前公历还未被采用
*/
public static void case9() {
System.out.println("***case9-闰年***");
/*
* 已知 如果年份能被4整除且不能被100整除,或者能被400整除,则为闰年 需求 编写程序,读取用户输入的一个整数作为年份,并且确定是否为闰年,输出结果
* 如果输入的年份小于1582则输出错误信息,因为在此之前公历还未被采用
*/
Scanner input = new Scanner(System.in);
System.out.println("输入年份,不小于1582");
int year = input.nextInt();
if (year < 1582) {
System.out.println("输入错误,数据不合法");
} else if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
System.out.println(year + "是闰年");
} else {
System.out.println(year + "不是闰年");
}
}
// case10:改写case6 (0~15十进制转十六进制字符的程序),使用if-else
public static void case10() {
System.out.println("***case10-10进制转16进制字符(case6改写)***");
// case10:改写case6 (0~15十进制转十六进制字符的程序),使用if-else
Scanner input = new Scanner(System.in);
System.out.println("请输入0-15的10进制整数");
int x = input.nextInt();
char res;
if (x>=0&&x<=15) {
if (x>9) {
res = (char) ('A' + (x - 10));
System.out.println(x + "对应16进制数为" + res);
} else {
res=(char) ('0'+(x-0));
//res=(char) x;
System.out.println(x + "对应16进制数为" + res);
}
}
else {
System.out.println("输入非法");
}
}
7.4 case11 16进制字符转整数
/*已知常用字符的unicode值
*用户输入0~9、A-F、a-f中的一个字符用来表示一个十六进制数,
*程序输出这个数的十进制形式
*提示: '0'=48 'A'=65 'a'=97一示例,输入:D输出:13
*/
//7.4 case11-16进制字符转整数
public static void case11() {
System.out.println("***7.4 case11-16进制字符转整数***");
Scanner input = new Scanner(System.in);
System.out.println("请输入一个16进制字符");
int res;
char x=input.next().charAt(0);//Scanner里边没有nextChar()方法
if (x>='0' && x<='9') {//x>=48&&x<=57
//res=x-'0';
System.out.println(x+"对应10进制为"+x);
}
else if (x>='A' && x<='Z') {//x>=65&&x<=70
res=x-'A'+10;
System.out.println(x+"对应10进制为"+res);
}
else if(x>='a'&x<='z'){//x>=97&x<=102
res=x-'a'+10;
System.out.println(x+"对应10进制为"+res);
}
else {
System.out.println("输入非法");
}
}
7.5、7.6 case12-个税计算器
/*已知:
* 工资个税的计算公式为:
* 应纳税额=(工资薪金所得-"五险一金”个人负担部分-扣除数)×适用税率―速算扣除数
* 2011年9月1日起调整后的7级超额累进税率:扣除数为3500元。
*·全月应纳税所得额 税率 速算扣除数(元)
*·全月应纳税额不超过1500元 3% 0
*·全月应纳税额超过1500元至4500元 10% 105
*·全月应纳税额超过4500元至9000元 20% 555
*·全月应纳税额超过9000元至35000元 25% 1005
*·全月应纳税额超过35000元至55000元 30% 2755
*·全月应纳税额超过55000元至80000元 35% 5505
*·全月应纳税额超过80000元 45% 13505
*/
//假定"五险一金”个人负担部分等于税前工资的10%
7.7 case13简单算术计算器
/*需求
* 编写程序,读取用户输入的操作数与符号,计算结果并输出
* 输入样例:4 + 3
* 输出样例:4 + 3 = 7
* 支持+ ― * / %
* 综合运行输入,运算,switch
*/
输入非法,返回Double.NaN
//7.7 case13-简单的算术计算器
public static void case13() {
System.out.println("***7.7 case13-简单的算术计算器***");
/*需求
* 编写程序,读取用户输入的操作数与符号,计算结果并输出
* 输入样例:4 + 3
* 输出样例:4 + 3 = 7
* 支持+ ― * / %
* 综合运行输入,运算,switch
*/
Scanner sc=new Scanner(System.in);
System.out.println("请输入计算式");
double a=sc.nextDouble();
String operator=sc.next();
double b=sc.nextDouble();
double res=0;
switch(operator) {
case "+":
res=a+b;
break;
case "-":
res=a-b;
break;
case "*":
res=a*b;
break;
case "/":
res=a/b;
break;
case "%":
res=a%b;
break;
default:
res=Double.NaN;
}
System.out.printf("%.2f %s %.2f = %.2f\n",a,operator,b,res);//printf格式化输出
}
7.8 case14while语句让程序反复执行
/*
* 修改之前判断闰年的程序,让用户可以同时测试多个年份,
* 用户输人“-1"时,终止程序
* 之前的案例都可以改写.(如个税计算器),让用户可以反复输入
* 设定某种特定的输入,用来终止循环
*/
// /*
// * 已知 如果年份能被4整除且不能被100整除,或者能被400整除,则为闰年 需求 编写程序,读取用户输入的一个整数作为年份,并且确定是否为闰年,输出结果
// * 如果输入的年份小于1582则输出错误信息,因为在此之前公历还未被采用
// */
//7.8 case14-while语句让程序反复执行
public static void case14() {
System.out.println("***7.8 case14-while语句让程序反复执行(case9改)***");
/*
* 修改之前判断闰年的程序,让用户可以同时测试多个年份,
* 用户输人“-1"时,终止程序
* 之前的案例都可以改写.(如个税计算器),让用户可以反复输入
* 设定某种特定的输入,用来终止循环
*/
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("输入年份,不小于1582");
int year = input.nextInt();
if (year==-1) {
System.out.println("程序结束");
break;
}
if (year < 1582) {
System.out.println("输入错误,数据不合法");
} else if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
System.out.println(year + "是闰年");
} else {
System.out.println(year + "不是闰年");
}
}
}
//case12改:
//case12改
Scanner sc=new Scanner(System.in);
NumberFormat nf=NumberFormat.getNumberInstance();//格式化
nf.setMaximumFractionDigits(2);//最大2位小数
while (true) {
System.out.println("输入税前工资:");
double salary=sc.nextDouble();//原工资
double tax=0;//税额
double taxRate=0;//税率
double deduct=0;//速算扣除数
if (salary<0) {
// if (salary==-1) {
// System.out.println("程序结束");
// break;
// }
System.out.println("不会有人上班给别人发钱吧?");
System.out.println("程序结束");
System.exit(0);//当前程序退出,代替了break
}
//应纳税所得额=工资薪金所得-"五险一金”个人负担部分-扣除数
double taxableIncome=salary-salary*0.1-3500;
if (taxableIncome<=0) {
System.out.println("少年,你的工资太低了,不用交税!");
System.exit(0);
}
if (taxableIncome<=1500) {
taxRate=0.03;
deduct=0;
}
else if (taxableIncome<=4500) {
taxRate=0.1;
deduct=105;
}
else if (taxableIncome<=9000) {
taxRate=0.2;
deduct=555;
}
else if (taxableIncome<=35000) {
taxRate=0.25;
deduct=1005;
}
else if (taxableIncome<=55000) {
taxRate=0.3;
deduct=2755;
}
else if (taxableIncome<=80000) {
taxRate=0.35;
deduct=5505;
}
else {
taxRate=0.45;
deduct=13505;
}
tax=taxableIncome*taxRate-deduct;
System.out.println("应纳税所得额 "+nf.format(taxableIncome)+" 税率 "+taxRate+" 速算扣除数 "+deduct);
System.out.println("应缴税款:"+nf.format(tax));
System.out.println("实发工资:"+nf.format(salary*(1-0.1)-tax));//实发工资=原工资-"五险一金”个人负担部分-应缴税款
}
7.9 case15-和女朋友聊天的正确姿势
/*设计一个简易的聊天程序,使用者为男性,程序模拟的是女朋友
*对女朋友说"你又胖了",收到回复"滚! "
*对女朋友说"你是最美的",收到回复"你这样说,人家会害羞啦......"
*对女朋友说"娘子,夜深了",收到回复"不用说了,先把灯关上吧",程序中止
*你还可以设定一些固定的对答,但只有上一条对答会终止程序
*固定对答之外,无论你说什么,都会收到回复"你说什么,我听不懂啦....
*/
//7.9 case15-和女朋友聊天的正确姿势
public static void case15() {
System.out.println("***7.9 case15-和女朋友聊天的正确姿势***");
/*设计一个简易的聊天程序,使用者为男性,程序模拟的是女朋友
*对女朋友说"你又胖了",收到回复"滚! "
*对女朋友说"你是最美的",收到回复"你这样说,人家会害羞啦......"
*对女朋友说"娘子,夜深了",收到回复"不用说了,先把灯关上吧",程序中止
*你还可以设定一些固定的对答,但只有上一条对答会终止程序
*固定对答之外,无论你说什么,都会收到回复"你说什么,我听不懂啦....
*/
Scanner sc=new Scanner(System.in);
//switch
while (true) {
System.out.println("你对女朋友说:");
String talk=sc.nextLine();
String anwser="";
switch(talk) {
case "你又胖了":
anwser="滚!";
break;
case "你是最美的":
anwser="你这样说,人家会害羞啦......";
break;
case "娘子,夜深了":
anwser="不用说了,先把灯关上吧";
break;
default:
anwser="你说什么,我听不懂啦....";
}
System.out.println("女朋友回答:"+anwser);
if(anwser.equals("不用说了,先把灯关上吧")) {//不能用anwser=="不用说了,先把灯关上吧"???
System.out.println("聊天结束");
break;
}
}
}
/*编写一个正确的循环对编程新手来说,并不是件容易的事。
* 编写循环时应该考虑如下三个步骤:
* 第一步:确定需要重复的语句,考虑是否真的有必要重复,不必要就放在循环外面
* 第二步:将这些语句放在一个循环中
* 第三步:为循环继续条件编码,并为控制循环添加适合的语句
* 此外,还需精心设计变量
*/
7.10、7.11 case16 改进十进制转十六进制
/*
* 背景:
* 之前的程序只能处理0-15,转换为单个字符
* 需求:
* 现在我们要处理任何整数如2345,要将其转换为16进制表示法的字符串并输出
* 已知:十进制数123 被转换为十六进制数7B。
* 这个转换过程如下:将123 除以 16,余数为11(十六进制的B),商为7。
* 继续将7除以 16,余数为7 ,商为 0。因此 7B就是123 的十六进制数
* 思路:利用循环,续商留余
*/
//7.10、7.11 case16-改进十进制转16进制
public static void case16() {
System.out.println("***7.10 case16-改进十进制转16进制***");
Scanner sc=new Scanner(System.in);
while (true) {
String res="";
System.out.println("请输入一个10进制数");
int x=sc.nextInt();
if (x<0) {
System.out.println("程序结束");
break;
}
while (x!=0) {
if(x%16>9) {
// res+=(char)('A'+(x%16-10));
res=(char)('A'+(x%16-10))+res;//倒序
}
else {
// res+=x%16;
res=x%16+res;
}
x=x/16;
}
System.out.println("对应16进制数为"+res);
}
}
7.12 case17 十进制转二进制表示
//7.12 case17-10进制转2进制
public static void case17() {
System.out.println("***7.12 case17-10进制转2进制***");
Scanner sc=new Scanner(System.in);
int count=0;//用于计数
String res="";
System.out.println("请输入一个10进制数");
int x=sc.nextInt();
while (x!=0) {
res=x%2+res;
x=x/2;
count++;
if (count%4==0&&x!=0) {//每4位加一个_
res="_"+res;
}
System.out.println("对应2进制数为"+res);
}
}
7.13、7.14 case18 嵌套的循环
/*(嵌套的循环)现在需要改进上一个案例:
* 用户可以反复测试,直到用户输入一个负数,程序终止
*/
//7.13、7.14 case18-嵌套的循环
public static void case18() {
System.out.println("***7.13、7.14 嵌套的循环***");
/*(嵌套的循环)现在需要改进上一个案例:
* 用户可以反复测试,直到用户输入一个负数,程序终止
*/
Scanner sc=new Scanner(System.in);
while (true) {
int count=0;//用于计数
String res="";
System.out.println("请输入一个10进制数");
int x=sc.nextInt();
if (x<0) {
System.out.println("程序结束");
break;
}
//负数的2进制表示
/*类比:一个圆,一个128个单位,从原点后走1步与往前走127是一样的
* -128 -127 ...-2 -1
* 0 1 ...126 127
* 以8bit为例:两个数相差128,即2^7
* -128->1000 0000 0--->0000 0000
* -127->1000 0001 1--->0000 0001
* -1--->1111 1111 127-->0111 1111
* -2--->1111 1110 126-->0111 1110
* 规律:对应的高位(符号位)不同,低位一样
* 思路:
* 先算出2^7+x的低7位,再把高位补1
* 对于int(32位):先算出2^31+x的低31位,然后把高位补1
*/
while (x!=0) {
res=x%2+res;
x=x/2;
count++;
if (count%4==0&&x!=0) {//每4位加一个_
res="_"+res;
}
}
System.out.println("对应2进制数为"+res);
}
}
7.15 趋于完整的十进制转二进制程序
高位补零
负数的二进制表示(思路:
//负数的2进制表示
/*类比:一个圆,一个128个单位,从原点后走1步与往前走127是一样的
* -128 -127 ...-2 -1
* 0 1 ...126 127
* 以8bit为例:两个数相差128,即2^7
* -128->1000 0000 0--->0000 0000(补码)
* -127->1000 0001 1--->0000 0001
* -1--->1111 1111 127-->0111 1111
* -2--->1111 1110 126-->0111 1110
* 规律:对应的高位(符号位)不同,低位一样
* 思路:
* 先算出2^7+x的低7位,再把高位补1(x为负数,以8bit为例:两个数相差128,即2^7)
* 对于int(32位):先算出2^31+x的低31位,然后把高位补1
*/
//边界值2147483647和-2147483648需要测试一下)
//7.15 趋于完整的十进制转二进制程序
public static void test3() {
System.out.println("***7.15 趋于完整的十进制转二进制程序***");
Scanner sc=new Scanner(System.in);
while (true) {
int count=0;//用于计数
String res="";
System.out.println("请输入一个10进制数");
int x=sc.nextInt();
int t=x;
// if (x<0) {
// System.out.println("程序结束");
// break;
// }
//负数的2进制表示
/*类比:一个圆,一个128个单位,从原点后走1步与往前走127是一样的
* -128 -127 ...-2 -1
* 0 1 ...126 127
* 以8bit为例:两个数相差128,即2^7
* -128->1000 0000 0--->0000 0000
* -127->1000 0001 1--->0000 0001
* -1--->1111 1111 127-->0111 1111
* -2--->1111 1110 126-->0111 1110
* 规律:对应的高位(符号位)不同,低位一样
* 思路:
* 先算出2^7+x的低7位,再把高位补1(x为负数,以8bit为例:两个数相差128,即2^7)
* 对于int(32位):先算出2^31+x的低31位,然后把高位补1
*/
//边界值2147483647和-2147483648需要测试一下
if(x<0) {
x=(int) (Math.pow(2, 31)+x);
}
while (x!=0) {
res=x%2+res;
x=x/2;
count++;
if (count%4==0) {//每4位加一个_
res="_"+res;
}
}
//高位补零
while (count<31) {
count++;
if (count%4==0) {//每4位加一个_
res="_"+0+res;
}
else {
res=0+res;
}
}
if (t<0) {
res=1+res;//负数高位补1
}
else {
res=0+res;//正数补0
}
System.out.println("对应2进制数为"+res);
}
}
7.16 case19 do-while语法及应用
/*case16中,用户直接输入0,将没有任何输出,怎么破?改成do-while
*/
case16:改进十进制转十六进制
//7.16 do-while语法及应用
public static void case19() {
System.out.println("***7.16 case19-do-while语法及应用(case16改)***");
/*case16中,用户直接输入0,将没有任何输出,怎么破?改成do-while
*/
Scanner sc=new Scanner(System.in);
while (true) {
String res="";
System.out.println("请输入一个10进制数");
int x=sc.nextInt();
if (x<0) {
System.out.println("程序结束");
break;
}
do{
if(x%16>9) {
// res+=(char)('A'+(x%16-10));
res=(char)('A'+(x%16-10))+res;
}
else {
// res+=x%16;
res=x%16+res;
}
x=x/16;
}while(x!=0);
// System.out.print(x+"对应16进制数为");
// int i=res.length()-1;
// while (i>=0) {
// System.out.print(res.charAt(i));
// i--;
// }
System.out.println("对应16进制数为"+res);
}
}
7.17 for循环的语法及特点
case16改写
/*通常,如果已经提前知道重复次数,那就采用for循环,
* 例如,需要打印一条信息100次时
* 如果无法确定重复次数,就采用while 循环,就像读入一些数值直到读入0为止的这种情况
* 如果在检验继续条件前需要执行循环体(至少1次),就用do-while 循环替代 while 循环
*/
//7.17 for循环语法及特点
public static void case20() {
System.out.println("***7.17 for循环语法及特点 case20-while改for***");
/*for(初始化语句;布尔语句;循环后动作){
* 循环体
* }
*/
// for (int i = 0; i < 100; i++) {
// System.out.println("Welcome to java"+i);
// }
// for (int i = 0; i < 10; i++) {
// System.out.print("*");
// }
// System.out.println();
// //等价于:
// int i=0;
// while (i<10) {
// System.out.print("*");
// i++;
// }
/*通常,如果已经提前知道重复次数,那就采用for循环,
* 例如,需要打印一条信息100次时
* 如果无法确定重复次数,就采用while 循环,就像读入一些数值直到读入0为止的这种情况
* 如果在检验继续条件前需要执行循环体(至少1次),就用do-while 循环替代 while 循环
*/
//case16
Scanner sc=new Scanner(System.in);
while (true) {
System.out.println("请输入一个10进制数");
int x=sc.nextInt();
String hex="";
char res='0';
int yu;
if (x<0) {
System.out.println("程序结束");
break;
}
for (int shang=x; shang!=0; shang=shang/16) {
yu=shang%16;
if(yu>9) {
res=(char)('A'+(yu-10));
}
else {
res=(char) ((yu-0)+'0');
}
hex=res+hex;
}
System.out.println("对应16进制数为"+hex);
}
}
7.18 case21-生成随机字符串
/*
* 已知字符范围是\u0000-\uFFFF
* 需求:
* 用户给定一个长度
* 程序生成该长度的字符串,每个字符都是随机的
* 输出该字符串
* 扩展:
* 稍加改变,即可让用户反复测试
* 体会到while和for的不同
*/
//7.18 case21-生成随机字符串
public static void case21() {
System.out.println("***7.18 case21-生成随机字符串***");
/*
* 已知字符范围是\u0000-\uFFFF
* 需求:
* 用户给定一个长度
* 程序生成该长度的字符串,每个字符都是随机的
* 输出该字符串
* 扩展:
* 稍加改变,即可让用户反复测试
* 体会到while和for的不同
*/
Scanner sc = new Scanner(System.in);
System.out.println("输入长度:");
int n=sc.nextInt();
String res="";
for (int i = 0; i < n; i++) {
char c=(char) (Math.random()*(0xffff+1));//[0x0000,0xffff+1)
if ((c>='0'&&c<='9')||(c>='a'&&c<='z')||(c>='A'&&c<='Z')) {//可以用这种方式限定输出
res+=c;
}
else {
i--;
}
}
System.out.println("得到的字符串为:"+res);
}
//while实现,不需要else了
System.out.println("输入长度:");
n=sc.nextInt();
int i=0;
res="";
while (i<n) {
char c=(char) (Math.random()*(0xffff+1));//[0x0000,0xffff+1)
if ((c>='0'&&c<='9')||(c>='a'&&c<='z')||(c>='A'&&c<='Z')) {
res+=c;
i++;
}
}
System.out.println("得到的字符串为:"+res);
7.19 case22-求PI的近似值
/*
* case22 :求Π的近似值
* 已知
* Π=4(1-1/3+1/5-1/7+1/9-1/11+...+((-1)^(i+1))/(2i-1))
* 编写程序,显示当i=10000,20000,100000 时的值
*/
//7.19 case22-求PI的近似值
public static void case22() {
System.out.println("***7.19 case22-求PI的近似值***");
/*
* case22 :求Π的近似值
* 已知
* Π=4(1-1/3+1/5-1/7+1/9-1/11+...+((-1)^(i+1))/(2i-1))
* 编写程序,显示当i=10000,20000,100000 时的值
*/
Scanner sc=new Scanner(System.in);
System.out.println("输入迭代次数:");
int n=sc.nextInt();
double res=0;
for (int i = 1; i <= n; i++) {
// if (i%2!=0) {
// res+=1.0/(2*i-1);//需要浮点型除法!!!
// }
// else {
// res-=1.0/(2*i-1);
// }
res+=Math.pow(-1, i+1)/(2*i-1);
}
System.out.println("Π的近似值为:"+4*res);
}
7.20、7.21 case23-回文字符串的判断
*
* case23:回文串 (Palindrome)的判断
* 如果一个字符串从前往后,以及从后往前是一样的,那么它就是一个回文。
* 例如, " mom"、" dad",以及" noon",都是回文
* 编写一个程序,提示用户输人一个字符串,
* 然后给出该字符串是否是回文
*/
//边界测试:空字符串与单字符字符串 边界错误就是逻辑错误
思路:
1.无脑循环
2.双“指针”
//7.20、7.21 case23-回文字符串的判断
public static void case23() {
System.err.println("***7.20、7.21 case23-回文字符串的判断***");
/*
* case23:回文串 (Palindrome)的判断
* 如果一个字符串从前往后,以及从后往前是一样的,那么它就是一个回文。
* 例如, " mom"、" dad",以及" noon",都是回文
* 编写一个程序,提示用户输人一个字符串,
* 然后给出该字符串是否是回文
*/
//边界测试:空字符串与单字符字符串 边界错误就是逻辑错误
Scanner sc=new Scanner(System.in);
System.out.println("输入一个字符串");
String s=sc.nextLine();
boolean flag=true;
for (int i = 0; i < s.length()/2; i++) {
if (s.charAt(i)!=s.charAt(s.length()-1-i)) {
flag=false;
break;
}
}
// if (flag==true) {
// System.out.println(s+"是回文字符串");
// }
// else {
// System.out.println(s+"不是回文串");
// }
System.out.println(s+(flag?"是":"不是")+"回文字符串");
/* 1.循怀怎么控制 何时退出,用什么变量来控制
* 2.控制条件
* 3.每次循环后,控制变量有何变化
* 4.最终要什么结果?是:否
* 5.怎么在循环中逐步得到结果
*/
/*这几种情况while 更合适:
* 1、不确定次数
* 2、多个控制变量
* 3、控制变量的初始化必须放在循环外面的时候
*/
}
//双指针思路
// boolean isPalindrome=false;
// int begin=0,end=s.length()-1;
// while (begin<end&&s.charAt(begin)==s.charAt(end)) {
// begin++;
// end--;
// }
// if (begin>=end) {//当字符串为偶数长度,跳出循环后begin会大于end
// isPalindrome=true;
// }
// System.out.println(s+(isPalindrome?"是":"不是")+"回文字符串");
7.22 case24-打印九九表
/* case24 :九九乘法表
* 背景:还记得小时候背九九乘法表吗?
* 使用嵌套for循环打印一个乘法表(MultiplicationTable)
*/
//外层控制行(9行),内层控制列(第1行1列,第2行2列...第n行n列)
//7.22 case24-打印九九表(嵌套for循环)
public static void case24() {
System.out.println("***7.22 case24-打印九九表***");
/* case24 :九九乘法表
* 背景:还记得小时候背九九乘法表吗?
* 使用嵌套for循环打印一个乘法表(MultiplicationTable)
*/
//外层控制行(9行),内层控制列(第1行1列,第2行2列...第n行n列)
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
// System.out.printf("%d * %d = %d\t",j,i,i*j);
System.out.print(j+"x"+i+"="+i*j+"\t");
}
System.out.println();
}
}
7.23、7.24、7.25 case25-最大公约数
解法1
/*法1:暴力破解法
*若x==y,则最大公约数两者选其一
*若x!=y,选取小(假如为x)的作为迭代次数,从1开始依次判断是否同时能被两者整除,
*最后一个符合的即为最大公约数
*/
Scanner sc=new Scanner(System.in);
System.out.println("x=");
int x=sc.nextInt();
System.out.println("y=");
int y=sc.nextInt();
int gcd=1;
if (x>y) {//让x<y
x=x^y;
y=x^y;
x=x^y;
}
else if (x==y) {
gcd=x;
System.out.println("最大公约数是"+gcd);
System.exit(0);//退出程序
}
for (int i = 1; i <= x; i++) {
if (x%i==0&&y%i==0) {
gcd=i;
}
}
System.out.println("最大公约数是"+gcd);
解法2
/*法2:
*基于法1,迭代次数为x/2,但是要单独判断边界,即x能被y整除的情况
*/
Scanner sc=new Scanner(System.in);
System.out.println("x=");
int x=sc.nextInt();
System.out.println("y=");
int y=sc.nextInt();
int gcd=1;
if (x>y) {
x=x^y;
y=x^y;
x=x^y;
}
if (y%x==0) {//包含了x==y 不能用else if,因为它与if互斥,不能满足x<y的情况
gcd=x;
System.out.println("最大公约数是"+gcd);
System.exit(0);//退出程序
}
for (int i = 1; i <= x/2; i++) {
if (x%i==0&&y%i==0) {
gcd=i;
}
}
System.out.println("最大公约数是"+gcd);
解法3
/*法3:
*基于法2,逆向扫描,第一个满足同时能被两者整除的数即为gcd
*/
Scanner sc=new Scanner(System.in);
System.out.println("x=");
int x=sc.nextInt();
System.out.println("y=");
int y=sc.nextInt();
int gcd=1;
if (x>y) {
x=x^y;
y=x^y;
x=x^y;
}
if (y%x==0) {
gcd=x;
System.out.println("最大公约数是"+gcd);
System.exit(0);
}
for (int i = x/2; i >= 1; i--) {
if (x%i==0&&y%i==0) {
gcd=i;
break;
}
}
System.out.println("最大公约数是"+gcd);
解法4
//以上算法平均时间复杂度为O(n/2)
/*法4:欧几里得算法(辗转相除法)
* y>x
* if y % x is 0, gcd (y, x) is x.
* Otherwise, gcd(y, x) is gcd(x, y % x).
* 注意y x顺序
* 平均时间复杂度为O(log2(n))
*/
Scanner sc=new Scanner(System.in);
System.out.println("x=");
int x=sc.nextInt();
System.out.println("y=");
int y=sc.nextInt();
int gcd=1;
if (x>y) {
x=x^y;
y=x^y;
x=x^y;
}
else if (x==y) {
gcd=x;
System.out.println("最大公约数是"+gcd);
System.exit(0);//退出程序
}
while (y%x!=0) {
int tmp=x;
x=y%x;
y=tmp;
}
gcd=x;
System.out.println("最大公约数是"+gcd);
扩展:求最小公倍数
//最小公倍数=x*y/gcd
/*
* 想要解开这题目首先要了解什么是最小公倍数
* 最小公倍数:是指能同时被a和b整除的最小正整数
* 例如:14 和 6 的最小公倍数有 42 84 126
* 最小的数就是最小公倍数
* 假设:a=6 b=18
* 那么最小公倍数怎么也不可能小于 18
三种方法:
* 法1.先找出a和b中的最大数赋值给max,
* 然后用 if 判断最大数max是否能同时%a和b等于零那么它就是最小公倍数
* 如果不行那最大数max++
int main()
{
int a = 0, b = 0;
scanf("%d %d", &a, &b);
int m = a < b ? a : b;
while (m)
{
if (m % a == 0 && m % b == 0)
{
printf("%d\n", m);
break;
}
m++;
}
return 0;
}
* 法2.先用辗转相除法求出最大公约数,
* 然后a*b/最大公约数=最小公倍
int main()
{
int a = 0, b = 0;
scanf("%d %d", &a, &b);
int n = a * b;
int m = 0;
while (m = a % b)
{
a = b;
b = m;
}
printf("%d\n", n / b);
}
* 法3.创建个 while 循环 if 判断 a * i % b==0
* 看 a 乘于 i 得出的数看能不能被 b 整除
* 如果可以那么它就是最小公倍数
int main()
{
int a = 0, b = 0;
scanf("%d %d", &a, &b);
int i = 1;
while ((a * i) % b != 0)
{
i++;
}
printf("%d\n", i * a);
return 0;
}
* 第三种方法效率最高
* ————————————————
* 版权声明:本文为CSDN博主「欧橘猫」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
* 原文链接:https://blog.csdn.net/m0_66483195/article/details/123508567
*/
第8章
package qianzhi;
import java.util.Scanner;
public class T8 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
// int res=test1(10, 20);
// System.out.println(res);
// case26();
System.out.println(RandomCharacter.fun1('a','f'));
System.out.println(RandomCharacter.fun2());
System.out.println(RandomCharacter.fun3());
System.out.println(RandomCharacter.fun4());
System.out.println(RandomCharacter.fun5(5));
System.out.println(RandomCharacter.fun6(5));
System.out.println(RandomCharacter.fun7(5));
System.out.println(RandomCharacter.fun8(5));
}
//8.1 方法Method介绍
public static int test1(int num1,int num2) {
System.out.println("***8.1 方法Method介绍***");
if (num1>num2) {
return num1;
}
else {
return num2;
}
}
//8.2 case26-改进小写金额转大写金额
public static void case26() {
System.out.println("***8.2 case26-改进小写金额转大写金额***");
/*需求
* 给定5位整数2位小数的金额,请将其转换为中文大写金额
* 89735.12->捌万玖仟染佰叁拾伍圆壹角贰分
* 方法的设计过程:
* 起名
* 该方法需要调用者提供什么
* 该方法需要返回给调用者什么
* 最后考虑方法的内部细节
*/
@SuppressWarnings("resource")
Scanner sc=new Scanner(System.in);
System.out.println("请输入5位整数2位小数的金额");
double d=sc.nextDouble();
String chineseDigit="";
String res="";
int fen=(int)(d*100);
int wan=fen/1000000;//万分位数字
chineseDigit=num2ChineseDigit(wan);
res+=chineseDigit+"萬";
fen=fen%1000000;
int qian=fen/100000;//千分位数字
chineseDigit=num2ChineseDigit(qian);
res+=chineseDigit+"仟";
fen=fen%100000;
int bai=fen/10000;//百分位数字
chineseDigit=num2ChineseDigit(bai);
res+=chineseDigit+"佰";
fen=fen%10000;
int shi=fen/1000;//十分位数字
chineseDigit=num2ChineseDigit(shi);
res+=chineseDigit+"拾";
fen=fen%1000;
int yuan=fen/100;//元分位数字
chineseDigit=num2ChineseDigit(yuan);
res+=chineseDigit+"圆";
fen=fen%100;
int jiao=fen/10;//角分位数字
chineseDigit=num2ChineseDigit(jiao);
res+=chineseDigit+"角";
fen=fen%10;
int fenfen=fen;//分分位数字
chineseDigit=num2ChineseDigit(fenfen);
res+=chineseDigit+"分";
System.out.println(d+"的大写金额为:"+res);
}
//壹、贰、叁、肆、伍、陆、柒、捌、玖、零
public static String num2ChineseDigit(int num) {
String chineseDigit="";
switch(num) {
case 1:
chineseDigit="壹";
break;
case 2:
chineseDigit="贰";
break;
case 3:
chineseDigit="叁";
break;
case 4:
chineseDigit="肆";
break;
case 5:
chineseDigit="伍";
break;
case 6:
chineseDigit="陆";
break;
case 7:
chineseDigit="柒";
break;
case 8:
chineseDigit="捌";
break;
case 9:
chineseDigit="玖";
break;
case 0:
chineseDigit="零";
break;
default:
break;
}
return chineseDigit;
}
//8.4 方法重载及变量作用域
/*
* 重载方法使得你可以使用同样的名字来定义不同方法,只要它们的参数列麦是不同的
* 重载方法可以使得程序更加清楚,以及更加具有可读性。执行同样功能但是具有不同参数类型的方法应该使用同样的名字
* 被重载的方法必须具有不同的参数列表。不能基于不同修饰符或返回值类型来重载方法
* 有时调用一个方法时,会有两个或更多可能的匹配,但是,编译器无法判断哪个是最精确的匹配。这称为歧义调用( ambiguous invocation )。
* 歧义调用会产生一个编译错误
* */
public static double max(int num1,int num2) {
if (num1>num2) {
return num1;
}
else {
return num2;
}
}
public static double max(double num1,double num2) {
if (num1>num2) {
return num1;
}
else {
return num2;
}
}
}
//8.5 case28-方法封装练习:随机字符工具类
/*
* 该工具(RandomCharacter)提供
* 生成两个字符之间的随机字符
* 生成一个小写字母的字符
* 生成一个大写字母的字符
* 生成一个数字字符
* 生成一个随机数字串
* 生成一个随机小写字母串
* 生成一个随机大写字母串
* 生成一个由大小写字母和数字组成的串
* */
class RandomCharacter{
//生成两个字符之间的随机字符[a,b]
/**文档级的注释
*生成两个字符a,b之间的随机字符,结果包含a和b
*@parameter a 范围较小的边界
*@parameter b 范围较大的边界
*@return a~b之间的一个随机字符,包含a, b
*/
public static char fun1(char a,char b) {
// if (a>b) {
// return (char) ((int)(Math.random()*(a-b+1))+b);
// }
// else {
// return (char) ((int)(Math.random()*(b-a+1))+a);
// }
if (a>b) {
char t=a;
a=b;
b=t;
}
return (char) ((int)(Math.random()*(b-a+1))+a);
}
//生成一个小写字母的字符
/**
*生成一个小写字母的字符
*@return 一个小写字母的字符
*/
public static char fun2() {
// char c;
// c=(char) ((Math.random()*'a')+('z'-'a'));
// System.out.println(c);
return fun1('a', 'z');
}
//生成一个大写字母的字符
/**
*生成一个大写字母的字符
*@return 一个大写字母的字符
*/
public static char fun3() {
// char c;
// c=(char) ((Math.random()*'A')+('Z'-'A'));
// System.out.println(c);
return fun1('A', 'Z');
}
//生成一个数字字符
/**
*生成一个数字字符
*@return 一个数字字符
*/
public static char fun4() {
return fun1('0', '9');
}
//生成一个随机数字串
/**
*生成一个长度length的随机数字串
*@parameter length 字符串长度
*@return 一个长度length的随机数字串
*/
public static String fun5(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(fun4());
}
return sb.toString();
}
//生成一个随机小写字母串
/**
*生成一个长度length的随机小写字母串
*@parameter length 字符串长度
*@return 一个长度length的随机小写字母串
*/
public static String fun6(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(fun2());
}
return sb.toString();
}
//生成一个随机大写字母串
/**
*生成一个长度length的随机大写字母串
*@parameter length 字符串长度
*@return 一个长度length的随机大写字母串
*/
public static String fun7(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(fun3());
}
return sb.toString();
}
//生成一个由大小写字母和数字组成的串
/**
*生成一个长度length的由大小写字母和数字组成的串
*@parameter length 字符串长度
*@return 一个长度length的由大小写字母和数字组成的串
*/
public static String fun8(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
int r=(int) (Math.random()*3);
switch(r) {
case 0:
sb.append(fun2());
break;
case 1:
sb.append(fun3());
break;
case 2:
sb.append(fun4());
break;
default:
break;
}
}
return sb.toString();
}
}
package qianzhi;
import java.util.Scanner;
//8.3 case27-16进制工具类封装
/*
* 该工具提供
* 10进制数转16进制字符串
* public static String decimalTohex (int decimal)
* 16进制字符串转10进制数
* public static int hexToDecimal (String hex)
*/
public class T8_case27_HexUtil {
public static void main(String[] args) {
// TODO 自动生成的方法存根
System.out.println(decimalTohex(123));
System.out.println(Integer.toString(123, 16));
System.out.println(hexToDecimal("7B"));
// System.out.println(String.);
}
public static String decimalTohex (int decimal) {
// Scanner sc=new Scanner(System.in);
String res="";
// System.out.println("请输入一个10进制数");
// int x=sc.nextInt();
// if (x<0) {
// System.out.println("程序结束");
// break;
// }
while (decimal!=0) {
if(decimal%16>9) {
res=(char)('A'+(decimal%16-10))+res;
}
else {
res=decimal%16+res;
}
decimal=decimal/16;
}
return res;
}
public static int hexToDecimal (String hex) {
// Scanner sc=new Scanner(System.in);
int res=0;
// System.out.println("请输入一个16进制字符串");
// String str=sc.nextLine();
// if (x<0) {
// System.out.println("程序结束");
// break;
// }
for (int i = 0; i < hex.length(); i++) {
int tmp=0;
char c=hex.charAt(i);
if (c>='0'&&c<='9') {
tmp=(int) ((c-'0')*Math.pow(16, (hex.length()-1-i)));
res+=tmp;
}
else if (c>='a'&&c<='f') {
tmp=(int) ((c-'a'+10)*Math.pow(16, (hex.length()-1-i)));
res+=tmp;
}
else if (c>='A'&&c<='F') {
tmp=(int) ((c-'A'+10)*Math.pow(16, (hex.length()-1-i)));
res+=tmp;
}
}
return res;
}
}
package qianzhi;
//验证不同类也可以调用,即方法共享与重用
public class T8_demo {
public static void main(String[] args) {
int res=T8.test1(10, 20);
System.out.println(res);
}
}
8.1-方法Method简介
package qianzhi;
//验证不同类也可以调用,即方法共享与重用
public class T8_demo {
public static void main(String[] args) {
int res=T8.test1(10, 20);
System.out.println(res);
}
}
//8.1 方法Method介绍
public static int test1(int num1,int num2) {
System.out.println("***8.1 方法Method介绍***");
if (num1>num2) {
return num1;
}
else {
return num2;
}
}
8.2 case26改进小写金额转大写金额
/*需求
* 给定5位整数2位小数的金额,请将其转换为中文大写金额
* 89735.12->捌万玖仟染佰叁拾伍圆壹角贰分
* 方法的设计过程:
* 起名
* 该方法需要调用者提供什么
* 该方法需要返回给调用者什么
* 最后考虑方法的内部细节
*/
//8.2 case26-改进小写金额转大写金额
public static void case26() {
System.out.println("***8.2 case26-改进小写金额转大写金额***");
/*需求
* 给定5位整数2位小数的金额,请将其转换为中文大写金额
* 89735.12->捌万玖仟染佰叁拾伍圆壹角贰分
* 方法的设计过程:
* 起名
* 该方法需要调用者提供什么
* 该方法需要返回给调用者什么
* 最后考虑方法的内部细节
*/
@SuppressWarnings("resource")
Scanner sc=new Scanner(System.in);
System.out.println("请输入5位整数2位小数的金额");
double d=sc.nextDouble();
String chineseDigit="";
String res="";
int fen=(int)(d*100);
int wan=fen/1000000;//万分位数字
chineseDigit=num2ChineseDigit(wan);
res+=chineseDigit+"萬";
fen=fen%1000000;
int qian=fen/100000;//千分位数字
chineseDigit=num2ChineseDigit(qian);
res+=chineseDigit+"仟";
fen=fen%100000;
int bai=fen/10000;//百分位数字
chineseDigit=num2ChineseDigit(bai);
res+=chineseDigit+"佰";
fen=fen%10000;
int shi=fen/1000;//十分位数字
chineseDigit=num2ChineseDigit(shi);
res+=chineseDigit+"拾";
fen=fen%1000;
int yuan=fen/100;//元分位数字
chineseDigit=num2ChineseDigit(yuan);
res+=chineseDigit+"圆";
fen=fen%100;
int jiao=fen/10;//角分位数字
chineseDigit=num2ChineseDigit(jiao);
res+=chineseDigit+"角";
fen=fen%10;
int fenfen=fen;//分分位数字
chineseDigit=num2ChineseDigit(fenfen);
res+=chineseDigit+"分";
System.out.println(d+"的大写金额为:"+res);
}
//转大写:壹、贰、叁、肆、伍、陆、柒、捌、玖、零
public static String num2ChineseDigit(int num) {
String chineseDigit="";
switch(num) {
case 1:
chineseDigit="壹";
break;
case 2:
chineseDigit="贰";
break;
case 3:
chineseDigit="叁";
break;
case 4:
chineseDigit="肆";
break;
case 5:
chineseDigit="伍";
break;
case 6:
chineseDigit="陆";
break;
case 7:
chineseDigit="柒";
break;
case 8:
chineseDigit="捌";
break;
case 9:
chineseDigit="玖";
break;
case 0:
chineseDigit="零";
break;
default:
break;
}
return chineseDigit;
}
8.3 case27 16进制工具封装
//8.3 case27-16进制工具类封装
/*
* 该工具提供
* 10进制数转16进制字符串
* public static String decimalTohex (int decimal)
* 16进制字符串转10进制数
* public static int hexToDecimal (String hex)
*/
package qianzhi;
import java.util.Scanner;
//8.3 case27-16进制工具类封装
/*
* 该工具提供
* 10进制数转16进制字符串
* public static String decimalTohex (int decimal)
* 16进制字符串转10进制数
* public static int hexToDecimal (String hex)
*/
public class T8_case27_HexUtil {
public static void main(String[] args) {
// TODO 自动生成的方法存根
System.out.println(decimalTohex(123));
System.out.println(Integer.toString(123, 16));
System.out.println(hexToDecimal("7B"));
// System.out.println(String.);
}
public static String decimalTohex (int decimal) {
// Scanner sc=new Scanner(System.in);
String res="";
// System.out.println("请输入一个10进制数");
// int x=sc.nextInt();
// if (x<0) {
// System.out.println("程序结束");
// break;
// }
while (decimal!=0) {
if(decimal%16>9) {
res=(char)('A'+(decimal%16-10))+res;
}
else {
res=decimal%16+res;
}
decimal=decimal/16;
}
return res;
}
public static int hexToDecimal (String hex) {
// Scanner sc=new Scanner(System.in);
int res=0;
// System.out.println("请输入一个16进制字符串");
// String str=sc.nextLine();
// if (x<0) {
// System.out.println("程序结束");
// break;
// }
for (int i = 0; i < hex.length(); i++) {
int tmp=0;
char c=hex.charAt(i);
if (c>='0'&&c<='9') {
tmp=(int) ((c-'0')*Math.pow(16, (hex.length()-1-i)));
res+=tmp;
}
else if (c>='a'&&c<='f') {
tmp=(int) ((c-'a'+10)*Math.pow(16, (hex.length()-1-i)));
res+=tmp;
}
else if (c>='A'&&c<='F') {
tmp=(int) ((c-'A'+10)*Math.pow(16, (hex.length()-1-i)));
res+=tmp;
}
}
return res;
}
}
8.4 方法重载及变量作用域
方法重载:
/*
* 重载方法使得你可以使用同样的名字来定义不同方法,只要它们的参数列麦是不同的
* 重载方法可以使得程序更加清楚,以及更加具有可读性。执行同样功能但是具有不同参数类型的方法应该使用同样的名字
* 被重载的方法必须具有不同的参数列表。不能基于不同修饰符或返回值类型来重载方法
* 有时调用一个方法时,会有两个或更多可能的匹配,但是,编译器无法判断哪个是最精确的匹配。这称为歧义调用( ambiguous invocation )。
* 歧义调用会产生一个编译错误
* */
//8.4 方法重载及变量作用域
public static double max(int num1,int num2) {
if (num1>num2) {
return num1;
}
else {
return num2;
}
}
public static double max(double num1,double num2) {
if (num1>num2) {
return num1;
}
else {
return num2;
}
}
}
变量作用域:
8.5 case28 方法封装练习:随机字符工具类
/*
* 该工具(RandomCharacter)提供
* 生成两个字符之间的随机字符
* 生成一个小写字母的字符
* 生成一个大写字母的字符
* 生成一个数字字符
* 生成一个随机数字串
* 生成一个随机小写字母串
* 生成一个随机大写字母串
* 生成一个由大小写字母和数字组成的串
* */
两个字符之间的随机字符
/**文档级的注释
*生成两个字符a,b之间的随机字符,结果包含a和b
*@parameter a 范围较小的边界
*@parameter b 范围较大的边界
*@return a~b之间的一个随机字符,包含a, b
*/
public static char fun1(char a,char b) {
// if (a>b) {
// return (char) ((int)(Math.random()*(a-b+1))+b);
// }
// else {
// return (char) ((int)(Math.random()*(b-a+1))+a);
// }
if (a>b) {
char t=a;
a=b;
b=t;
}
return (char) ((int)(Math.random()*(b-a+1))+a);
}
生成一个小写字母的字符
/**
*生成一个小写字母的字符
*@return 一个小写字母的字符
*/
public static char fun2() {
// char c;
// c=(char) ((Math.random()*'a')+('z'-'a'));
// System.out.println(c);
return fun1('a', 'z');
}
生成一个大写字母的字符
/**
*生成一个大写字母的字符
*@return 一个大写字母的字符
*/
public static char fun3() {
// char c;
// c=(char) ((Math.random()*'A')+('Z'-'A'));
// System.out.println(c);
return fun1('A', 'Z');
}
生成一个数字字符
/**
*生成一个数字字符
*@return 一个数字字符
*/
public static char fun4() {
return fun1('0', '9');
}
生成一个随机数字串
/**
*生成一个长度length的随机数字串
*@parameter length 字符串长度
*@return 一个长度length的随机数字串
*/
public static String fun5(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(fun4());
}
return sb.toString();
}
生成一个随机小写字母串
/**
*生成一个长度length的随机小写字母串
*@parameter length 字符串长度
*@return 一个长度length的随机小写字母串
*/
public static String fun6(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(fun2());
}
return sb.toString();
}
生成一个随机大写字母串
/**
*生成一个长度length的随机大写字母串
*@parameter length 字符串长度
*@return 一个长度length的随机大写字母串
*/
public static String fun7(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(fun3());
}
return sb.toString();
}
生成一个由大小写字母和数字组成的串
/**
*生成一个长度length的由大小写字母和数字组成的串
*@parameter length 字符串长度
*@return 一个长度length的由大小写字母和数字组成的串
*/
public static String fun8(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
int r=(int) (Math.random()*3);
switch(r) {
case 0:
sb.append(fun2());
break;
case 1:
sb.append(fun3());
break;
case 2:
sb.append(fun4());
break;
default:
break;
}
}
return sb.toString();
}
整个类:
class RandomCharacter{
//生成两个字符之间的随机字符[a,b]
/**文档级的注释
*生成两个字符a,b之间的随机字符,结果包含a和b
*@parameter a 范围较小的边界
*@parameter b 范围较大的边界
*@return a~b之间的一个随机字符,包含a, b
*/
public static char fun1(char a,char b) {
// if (a>b) {
// return (char) ((int)(Math.random()*(a-b+1))+b);
// }
// else {
// return (char) ((int)(Math.random()*(b-a+1))+a);
// }
if (a>b) {
char t=a;
a=b;
b=t;
}
return (char) ((int)(Math.random()*(b-a+1))+a);
}
//生成一个小写字母的字符
/**
*生成一个小写字母的字符
*@return 一个小写字母的字符
*/
public static char fun2() {
// char c;
// c=(char) ((Math.random()*'a')+('z'-'a'));
// System.out.println(c);
return fun1('a', 'z');
}
//生成一个大写字母的字符
/**
*生成一个大写字母的字符
*@return 一个大写字母的字符
*/
public static char fun3() {
// char c;
// c=(char) ((Math.random()*'A')+('Z'-'A'));
// System.out.println(c);
return fun1('A', 'Z');
}
//生成一个数字字符
/**
*生成一个数字字符
*@return 一个数字字符
*/
public static char fun4() {
return fun1('0', '9');
}
//生成一个随机数字串
/**
*生成一个长度length的随机数字串
*@parameter length 字符串长度
*@return 一个长度length的随机数字串
*/
public static String fun5(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(fun4());
}
return sb.toString();
}
//生成一个随机小写字母串
/**
*生成一个长度length的随机小写字母串
*@parameter length 字符串长度
*@return 一个长度length的随机小写字母串
*/
public static String fun6(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(fun2());
}
return sb.toString();
}
//生成一个随机大写字母串
/**
*生成一个长度length的随机大写字母串
*@parameter length 字符串长度
*@return 一个长度length的随机大写字母串
*/
public static String fun7(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(fun3());
}
return sb.toString();
}
//生成一个由大小写字母和数字组成的串
/**
*生成一个长度length的由大小写字母和数字组成的串
*@parameter length 字符串长度
*@return 一个长度length的由大小写字母和数字组成的串
*/
public static String fun8(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
int r=(int) (Math.random()*3);
switch(r) {
case 0:
sb.append(fun2());
break;
case 1:
sb.append(fun3());
break;
case 2:
sb.append(fun4());
break;
default:
break;
}
}
return sb.toString();
}
}
第9章
package qianzhi;
import java.util.Arrays;
public class T9 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
// test1();
// int[] arr=Util.getRandomArr(10,10, 20);
// Util.printArr(arr);
// System.out.println(Util.getSum(arr));
// System.out.println(Util.getAve(arr));
// Util.getMax(arr);
// Util.getMin(arr);
// Util.shuffle(arr);
// Util.printArr(arr);
// Util.moveBack(arr);
// Util.moveForward(arr);
// Util.printArr(arr);
// System.out.println(Util.num2Month(1));
// test5();
// test6();
// case1();
// int[] arr= {1,2,3,4,5,6,7,8};
// System.out.println(Util.binarySearch(arr,0));
// int[] arr= {45,95,31,52,656};
// SortDemo.bubbleSort(arr);
// SortDemo.selectSort(arr);
// SortDemo.inserSort(arr);
// Util.printArr(arr);
// test11(arr);
// test12();
case2();
}
//9.1数组初始化及内存模型
public static void test1() {
System.out.println("***9.1数组初始化及内存模型***");
/*
* 声明
* elementTypel ] arrayRefVar; (元秦类型[]数组引用变量﹔)
* double[] myList;
* 创建
* arrayRefVar = new elementType [ arraySize ];
* (元素类型[]数组引用变量= new元秦类型[数组大小]; )
* double[ ] myList = new double [10];
* 默认值
* 创建数组后,每个元素的值是这个类型的默认值
* 数值型为0/0.0,布尔型为false,引用型为null
*/
double[] dArr=new double[10];
for (int i = 0; i < dArr.length; i++) {
dArr[i]=i*3.14;
}
int[] iArr;
iArr=new int[10];
boolean[] bArr=new boolean[10];
System.out.println(dArr[0]);
for (int i = 0; i < dArr.length; i++) {
System.out.println(dArr[i]);
}
/*
* 快捷初始化
* double [] myList o- { 1.9,2.9,3.4,3.5};
* 数组快捷初始化语法中不使用操作符new。
* 使用数组快捷初始化语法时,必须将声明、创建和初始化数组都放在一条语句中。
* 将它们分开会产生语法错误。
* 因此,下面的语句是错误的:
* double [ ] myList;
* myList = { 1.9,2.9,3.4,3.5 } ;
*/
double[]dArr1= {1.9,20.0};
/*
* 一个数组变量看起来似乎是存储了一个数组,但实际上它存储的是指向数组的引用。
* 严格地讲,一个数组变量和一个教组是不同的,但多教情况下它们的差别是可以忽略的。
* 因此,为了简化,通常可以说myList 是一个数组,而不用更长的陈述:myList是一个含有10个double型元秦数组的引用变量。
*/
}
//9.2数组常见用法举例(1)
public static void test2() {
System.out.println("***9.2数组常见用法举例(1)***");
//1.随机数初始数组
//2.求和求平均
//3.最大(小)元素及其下标
}
//9.3数组常见用法举例(2)
public static void test3() {
System.out.println("***9.3数组常见用法举例(2)***");
//1.随机打乱
//2.向前(向后)依次移动
//3.简化编程
//4.foreach
}
//9.4命令行参数 见T9_MainTestDemo.java
//javac T9_MainTestDemo.java
//java T9_MainTestDemo 123 abc 你好
//java T9_MainTestDemo "123 abc" 你好
public static void test4() {
System.out.println("***9.4命令行参数***");
/*
* main方法可以从命令行接收字符串参数
* 当调用main方法时,Java解释器会创建一个数组存储命令行参数,
* 然后将该数组的引用传递给args
* java TestMain arg0 arg1 arg2
* 参数arg0、arg1 和arg2都是字符串,但是在命合行中出现时,不需要放在双引号中。
* 这些字符串用空格分隔。如果字符串包含空格,那就必须使用双引号括住。
* 考虑下面的命令行:
* java TestMain "First num" alpha 53
* 如果运行程序没有传递字符串,那么使用new String[0]创建数组.
* 在这种情况下,该数组是长度为0的空数组. args是对这个空数组的引用.
* 因此, args不是null,但是args.length是0
*/
}
//9.5引用的拷贝
public static void test5() {
System.out.println("***9.5引用的拷贝***");
/*
* 在Java中,可以使用斌值语句复制基本数据类型的变量,但不能复制数组。
* 将一个数组变量赋值给另一个数组变量,
* 实际上是将一个数组的引用复制给另一个变量,
* 使两个变量都指向相同的内存地址。
* */
int i=10;
int j=i;
i=20;
System.out.println("j="+j);
int[] list1= {1,2,3,4,5};
int[] list2=new int[5];
list2=list1;//地址拷贝,不是内容拷贝,让list1与list2指向同一块地址空间
list1[0]=0;
System.out.println("list2[0]="+list2[0]);
/*赋值数组内容
* 用循环语句逐个复制
* 使用System类中的静态方法arraycopy
* arraycopy (sourceArray, srcPos, targetArray, tarPos ,length) ;
* arraycopy方法不会给目标数组分配内存空间。
* 复制前必须创建目标数组以及给它分配内存空间。
* 复制完成后,sourceArray和targetArray具有相同的内容, 但占有独立的内存空间
*/
int[] list3= {1,2,3,4,5};
int[] list4=new int[5];
//把list3的2 3 4 拷贝到list4开头
System.arraycopy(list3, 1, list4, 0, 3);//复制内容
Util.printArr(list4);
}
//9.6方法传参与堆栈模型初步
public static void test6() {
System.out.println("***9.6方法传参与堆栈模型初步***");
/* int[] list1= {1,2,3,4,5};
* int n=1
* 对象存储在堆(heap)当中,堆用于动态内存分配,如list1数组的元素{1,2,3,4,5}
* 基本数据类型和引用放在栈里,如list1、n;栈用于方法调用
*/
int x=1;
int[] y=new int[10];
m(x, y);//x按值传递 y引用传递
System.out.println("x is "+x);
System.out.println("y[0] is "+y[0]);
}
public static void m(int number,int[] numbers) {
number=1001;
numbers[0]=5555;
}
//9.7 case1:统计字母出现的次数
public static void case1() {
System.out.println("***9.7 case1:统计字母出现的次数***");
/*
* 统计字符数组中每个字母出现的次数
* */
String ranString=fun6(10);//生成长度为30的随机小写字符串
System.out.println(ranString);
char[] arr=ranString.toCharArray();
int[] res=new int[26];
for (char c : arr) {
res[c-'a']++;
}
for (int i = 0; i < res.length; i++) {
if (res[i]>0) {
System.out.println((char)('a'+i)+"的个数为"+res[i]);
}
// System.out.println((char)('a'+i)+"的个数为"+res[i]);
}
}
//生成两个字符之间的随机字符[a,b]
public static char fun1(char a,char b) {
if (a>b) {
char t=a;
a=b;
b=t;
}
return (char)((int)(Math.random()*(b-a+1))+a);
}
//生成一个小写字母的字符
public static char fun2() {
return fun1('a', 'z');
}
//生成一个随机小写字母串
public static String fun6(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(fun2());
}
return sb.toString();
}
//9.8顺序查找和二分查找
public static void test7() {
System.out.println("***9.8顺序查找和二分查找***");
/*
* 设计一个方法,用于在指定的数组中查找指定的值,
* 如果找到,返回下标
* 如果没有找到,返回-1
* 思路∶顺序扫描
* */
//1.顺序查找 indexOf
//2.二分查找 binarySearch
}
//9.9基础排序之冒泡排序 bubbleSort
public static void test8() {
System.out.println("***9.9基础排序之冒泡***");
//可以类比站队
}
//9.10基础排序之选择排序 selectSort
public static void test9() {
System.out.println("***9.10基础排序之选择排序***");
}
//9.11基础排序之插入排序 insertSort
public static void test10() {
System.out.println("***9.11基础排序之插入排序***");
//可以类比打扑克摸牌插牌
}
//9.12Arrays工具类
public static void test11(int[] arr) {
System.out.println("***9.12Arrays工具类***");
/*java.util.Arrays类包含一些实用的方法用于常见的数组操作,比如排序和查找
* 可以使用sort 或者parallelSort方法对整个数组或部分数组进行排序
* 可以采用二分查找法(binarySearch方法)在有序数组中查找关键字
* 可以采用equals方法检测两个数组是否相等
* 可以使用fill 方法填充整个数组或部分数组
* 可以使用toString方法来返回一个字符串
*/
Arrays.sort(arr);
int index=Arrays.binarySearch(arr, 45);
System.out.println(index);
Util.printArr(arr);
}
//9.13二维数组简介
public static void test12() {
System.out.println("***9.13二维数组简介***");
int[][] a;//声明
int[][] arr=new int[5][];//创建
System.out.println(arr[0]);//输出null
int[][] arr1=new int[5][5];//创建
System.out.println(arr1[0]);//输出地址
System.out.println(arr1[0][0]);//默认0
//循环初始换
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr1[0].length; j++) {
arr1[i][j]=i*j;
}
}
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr1[i].length; j++) {
System.out.print(arr1[i][j]+"\t");
}
System.out.println();
}
//快捷初始化
int[][] arr2= {{1,3,5,7},{2,4,6,8}};
for (int i = 0; i < arr2.length; i++) {
for (int j = 0; j < arr2[i].length; j++) {
System.out.print(arr2[i][j]+"\t");
}
System.out.println();
}
//利用foreach输出
for (int i = 0; i < arr2.length; i++) {
for (int e:arr2[i]) {
System.out.print(e+"\t");
}
System.out.println();
}
//不规则二维数组
int[][] b= {{1,2},
{3,4,5,6},
{7,8,9}};
for (int i = 0; i < b.length; i++) {
int[] row=b[i];//把二维数组的每一个元素看出一维数组
for (int j : row) {
System.out.print(j+"\t");
}
System.out.println();
}
}
//9.14 case2-找出距离最小的点对
public static void case2() {
System.out.println("***9.14 case2-找出距离最小的点对***");
/*把10X2二维数组的每行的第1列作为x坐标,第2列作为y坐标,用二维坐标表示
* 找出距离最小的两个点
*/
// double[][] arr=new double[10][2];//10行2列,即10个点
double[][] arr= {
{1,1},
{1,0.5},
{2,1},
{3,4},
{2.8,1},
{1,7},
{4,1.8},
{1.1,9},
{3,5},
{5,6}
};
// int mixDis=0;
double minDis=Double.MAX_VALUE;
int minI=0;
int minJ=0;
//i代表依次把每个点作为源点
for (int i = 0; i < arr.length; i++) {
//计算其余的点的距离,保留更小的距离
for (int j = i+1; j < arr.length; j++) {//j遍历除i之外的点
//(x1,y1)、(x2、y2)距离:
//((x1-x2)^2+(y1-y2)^2)^(1/2)
double x1=arr[i][0];
double x2=arr[j][0];
double y1=arr[i][1];
double y2=arr[j][1];
double dis = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
if (dis<minDis) {
minDis=dis;
minI=i;
minJ=j;
}
}
}
System.out.println("min distance:"+minDis+",i:"+minI+",j:"+minJ);
}
}
//随机数初始数组
class Util{
/**
* 获取指定范围指定个数的随机数组成的数组
* @param length 长度
* @param min 最小值
* @param max 最大值
* @return 数组
*/
public static int[] getRandomArr(int length,int min,int max) {
int[] arr=new int[length];
for (int i = 0; i < arr.length; i++) {
arr[i]=(int)(Math.random()*(max-min+1)+min);
}
return arr;
}
/**
* 打印数组
* @param arr 数组
*/
//两种方法
public static void printArr(int[] arr) {
// for (int i = 0; i < arr.length; i++) {
// System.out.print(arr[i]+"\t");
// }
for (int i : arr) {//i只读,只能正序输出
System.out.print(i+"\t");
}
System.out.println();
}
/**
*求数组元素和
*@param arr 数组
*@return 数组元素和
*/
public static int getSum(int[] arr) {
int sum=0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
return sum;
}
/**
*求数组元素平均值
*@param arr 数组
*@return 数组元素平均值
*/
public static int getAve(int[] arr) {
return getSum(arr)/arr.length;
}
/**
*最大元素及其下标
*@param arr 数组
*/
public static void getMax(int[] arr) {
int max=arr[0];
int indexOfMax=0;
for (int i = 0; i < arr.length; i++) {
if (arr[i]>max) {
max=arr[i];
indexOfMax=i;
}
}
System.out.println("最大值为:"+max);
System.out.println("下标为:"+indexOfMax);
}
/**
*最小元素及其下标
*@param arr 数组
*/
public static void getMin(int[] arr) {
int min=arr[0];
int indexOfMin=0;
for (int i = 0; i < arr.length; i++) {
if (arr[i]<min) {
min=arr[i];
indexOfMin=i;
}
}
System.out.println("最大值为:"+min);
System.out.println("下标为:"+indexOfMin);
}
/**
*随机打乱
*@param arr 数组
*/
public static void shuffle(int[] arr) {
for (int i = arr.length-1; i >= 0; i--) {
int j=(int) (Math.random()*(i+1));
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
/**
*向前依次移动
*@param arr 数组
*/
public static void moveForward(int[] arr) {
int temp = arr[0];//存第一个元素
for (int i = 1; i < arr.length; i++) {
arr[i-1]=arr[i];
}
arr[arr.length-1]=temp;
}
/**
*向后依次移动
*@param arr 数组
*/
public static void moveBack(int[] arr) {
int temp=arr[arr.length-1];
for (int i = arr.length-1; i > 0; i--) {
arr[i]=arr[i-1];
}
arr[0]=temp;
}
/**
*简化编程num2Month
*@param num 月份的数字形式
*/
//不用switch了
public static String num2Month(int num) {
String[] months= {"January","February","March","April",
"May","June","July","August",
"September","October","November","December"};
if (num<1||num>12) {
return "输入错误";
}
else {
return months[num-1];
}
}
/**元素交换
* @param arr int数组
* @param i 下标
* @param j 下标
*/
public static void swap(int[] arr,int i,int j) {
int tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
/**
* 顺序查找
* @param arr 目标数组
* @param target 目标元素
* @return 找到返回 下标,否则返回-1
* */
public static int indexOf(int[] arr,int target) {
int res=-1;
for (int i = 0; i < arr.length; i++) {
if (arr[i]==target) {
res=i;
break;
}
}
return res;
}
/**
* 二分查找
* @param arr 目标数组
* @param target 目标元素
* @return
* @return 找到返回 下标,否则返回-1
* */
// public static int binarySearch(int[] array, int key) {
// int low = 0;
// int high = array.length - 1;
// while (low <= high) {
// int mid = low + ((high - low) >> 1);
// if (array[mid] == key) {
// return mid;
// } else if (array[mid] < key) {
// low = mid + 1;
// } else {
// high = mid - 1;
// }
// }
// return -1;
//}
public static int binarySearch(int[] arr,int target) {
/*
* 1.mid
* 2.比较,目标值和mid比较,
* 目标值大,去右侧找
* 目标值小,去左侧找
* 目标值和mid相同,返回mid的下标
* 3.再与新mid比较
* */
//左右标尺
int begin=0;
int end=arr.length-1;
while (begin<=end) {
// int indexOfMid=length/2;
int mid=begin+((end-begin)>>1);
int midValue=arr[mid];
if (target>midValue) {
begin=mid+1;
}
else if (target<midValue) {
end=mid-1;
}
else {
return mid;
}
}
return -1;
}
}
class SortDemo{
/**冒泡排序
* @param arr 数组
* */
public static void bubbleSort(int[] arr) {
//外层是天花板
for (int tianHuaBan = arr.length-1; tianHuaBan >= 0; tianHuaBan--) {
//在天花板内将最大的数组顶到天花板
for (int i = 0; i < tianHuaBan; i++) {
if (arr[i]>arr[i+1]) {
int temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
}
}
/**选择排序
* @param arr int数组
* */
public static void selectSort(int[] arr) {
//外层是天花板
for (int tianHuaBan = arr.length-1; tianHuaBan >= 0; tianHuaBan--) {
//在天花板范围内选一个最大的
int indexOfMax=0;
int max=arr[indexOfMax];
for (int i = 0; i < tianHuaBan; i++) {
if (arr[i]>max) {
indexOfMax=i;
max=arr[i];
}
}
//内层for循环完成之后,天花板范围内的最大值及其下标就确定了
Util.swap(arr, indexOfMax, tianHuaBan);
}
}
/**插入排序
* @param arr int数组
* */
// public static void insertionSort(int[] arr) {
// for (int i = 1; i < arr.length; i++) {
// int key = arr[i];
// int j = i - 1;
// while (j >= 0 && arr[j] > key) {
// arr[j + 1] = arr[j];
// j--;
// }
// arr[j + 1] = key;
// }
// }
public static void inserSort(int[] arr) {
//好比摸牌,从上到下一张一张去摸
for (int i = 0; i < arr.length; i++) {//一共length张牌要摸
//这张牌的点数是arr[i]
//手上的牌0~i-1
/*if(新手牌<原有手牌中最末的那个)
* 原有手牌后挪
* */
int last=i-1;//原手牌最后一张
int now=arr[i];//新摸的手牌
//last=0或者新来的更大则退出循环
while (last>=0&&now>arr[last]) {//last>=0防止下标越界到-1,即所有的都比新来的小的情况
arr[last+1]=arr[last];
last--;//更新最后一张牌
}
//新手牌合适的位置
arr[last+1]=now;
}
}
}
9.1 数组初始化及内存模型
/*
* 声明
* elementTypel ] arrayRefVar; (元秦类型[]数组引用变量﹔)
* double[] myList;
* 创建
* arrayRefVar = new elementType [ arraySize ];
* (元素类型[]数组引用变量= new元秦类型[数组大小]; )
* double[ ] myList = new double [10];
* 默认值
* 创建数组后,每个元素的值是这个类型的默认值
* 数值型为0/0.0,布尔型为false,引用型为null
*/
/*
* 快捷初始化
* double [] myList = { 1.9,2.9,3.4,3.5};
* 数组快捷初始化语法中不使用操作符new。
* 使用数组快捷初始化语法时,必须将声明、创建和初始化数组都放在一条语句中。
* 将它们分开会产生语法错误。
* 因此,下面的语句是错误的:
* double [ ] myList;
* myList = { 1.9,2.9,3.4,3.5 } ;
*/
/*
* 一个数组变量看起来似乎是存储了一个数组,但实际上它存储的是指向数组的引用。
* 严格地讲,一个数组变量和一个教组是不同的,但多教情况下它们的差别是可以忽略的。
* 因此,为了简化,通常可以说myList 是一个数组,而不用更长的陈述:myList是一个含有10个double型元秦数组的引用变量。
*/
//9.1数组初始化及内存模型
public static void test1() {
System.out.println("***9.1数组初始化及内存模型***");
/*
* 声明
* elementTypel ] arrayRefVar; (元秦类型[]数组引用变量﹔)
* double[] myList;
* 创建
* arrayRefVar = new elementType [ arraySize ];
* (元素类型[]数组引用变量= new元秦类型[数组大小]; )
* double[ ] myList = new double [10];
* 默认值
* 创建数组后,每个元素的值是这个类型的默认值
* 数值型为0/0.0,布尔型为false,引用型为null
*/
double[] dArr=new double[10];
for (int i = 0; i < dArr.length; i++) {
dArr[i]=i*3.14;
}
int[] iArr;
iArr=new int[10];
boolean[] bArr=new boolean[10];
System.out.println(dArr[0]);
for (int i = 0; i < dArr.length; i++) {
System.out.println(dArr[i]);
}
/*
* 快捷初始化
* double [] myList o- { 1.9,2.9,3.4,3.5};
* 数组快捷初始化语法中不使用操作符new。
* 使用数组快捷初始化语法时,必须将声明、创建和初始化数组都放在一条语句中。
* 将它们分开会产生语法错误。
* 因此,下面的语句是错误的:
* double [ ] myList;
* myList = { 1.9,2.9,3.4,3.5 } ;
*/
double[]dArr1= {1.9,20.0};
/*
* 一个数组变量看起来似乎是存储了一个数组,但实际上它存储的是指向数组的引用。
* 严格地讲,一个数组变量和一个教组是不同的,但多教情况下它们的差别是可以忽略的。
* 因此,为了简化,通常可以说myList 是一个数组,而不用更长的陈述:myList是一个含有10个double型元秦数组的引用变量。
*/
}
9.2 数组常见用法举例(1)
//1.随机数初始数组
//2.求和求平均
//3.最大(小)元素及其下标
9.3 数组常见用法举例(2)
//1.随机打乱
//2.向前(向后)依次移动
//3.简化编程
//4.foreach
9.4 命令行参数
代码不要加package!!!:
public class T9_MainTestDemo {
public static void main(String[] args) {
// TODO ??????????????
//?????��??? ???????????????
for (String str : args) {
System.out.println(str);
}
}
在终端编译:
javac T9_MainTestDemo.java
运行:
java T9_MainTestDemo 123 abc 你好
java T9_MainTestDemo "123 abc" 你好
9.5 引用的拷贝
/*
* 在Java中,可以使用斌值语句复制基本数据类型的变量,但不能复制数组。
* 将一个数组变量赋值给另一个数组变量,
* 实际上是将一个数组的引用复制给另一个变量,
* 使两个变量都指向相同的内存地址。(引用变量的拷贝,引用拷贝)
* */
/*赋值数组内容
* 1.用循环语句逐个复制
* 2.使用System类中的静态方法arraycopy:
* arraycopy (sourceArray, srcPos, targetArray, tarPos ,length) ;* 源数组 起始位置 目标数组 目标位置 长度
* arraycopy方法不会给目标数组分配内存空间。
* 复制前必须创建目标数组以及给它分配内存空间。
* 复制完成后,sourceArray和targetArray具有相同的内容, 但占有独立的内存空间
*/
//9.5引用的拷贝
public static void test5() {
System.out.println("***9.5引用的拷贝***");
/*
* 在Java中,可以使用斌值语句复制基本数据类型的变量,但不能复制数组。
* 将一个数组变量赋值给另一个数组变量,
* 实际上是将一个数组的引用复制给另一个变量,
* 使两个变量都指向相同的内存地址。
* */
int i=10;
int j=i;
i=20;
System.out.println("j="+j);
int[] list1= {1,2,3,4,5};
int[] list2=new int[5];
list2=list1;//地址拷贝,不是内容拷贝,让list1与list2指向同一块地址空间
list1[0]=0;
System.out.println("list2[0]="+list2[0]);
/*赋值数组内容
* 用循环语句逐个复制
* 使用System类中的静态方法arraycopy
* arraycopy (sourceArray, srcPos, targetArray, tarPos ,length) ;
* arraycopy方法不会给目标数组分配内存空间。
* 复制前必须创建目标数组以及给它分配内存空间。
* 复制完成后,sourceArray和targetArray具有相同的内容, 但占有独立的内存空间
*/
int[] list3= {1,2,3,4,5};
int[] list4=new int[5];
//把list3的2 3 4 拷贝到list4开头
System.arraycopy(list3, 1, list4, 0, 3);//复制内容
Util.printArr(list4);
}
9.6 方法传参与堆栈模型初步
/* int[] list1= {1,2,3,4,5};
* int n=1
* 对象存储在堆(heap)当中,堆用于动态内存分配,如list1数组的元素{1,2,3,4,5}
* 基本数据类型和引用放在栈里,如list1、n;栈用于方法调用
*/
//9.6方法传参与堆栈模型初步
public static void test6() {
System.out.println("***9.6方法传参与堆栈模型初步***");
/* int[] list1= {1,2,3,4,5};
* int n=1
* 对象存储在堆(heap)当中,堆用于动态内存分配,如list1数组的元素{1,2,3,4,5}
* 基本数据类型和引用放在栈里,如list1、n;栈用于方法调用
*/
int x=1;
int[] y=new int[10];
m(x, y);//x按值传递 y引用传递
System.out.println("x is "+x);
System.out.println("y[0] is "+y[0]);
}
public static void m(int number,int[] numbers) {
number=1001;
numbers[0]=5555;
}
x is 1
y[0] is 5555
基本数据类型和引用放在栈里
9.7 Case1:统计字母出现的次数
/*
* 统计字符(小写字母)数组中每个字母出现的次数
* */
思路:利用一维数组下标代表26个字母,数组内容是出现次数
//9.7 case1:统计字母出现的次数
public static void case1() {
System.out.println("***9.7 case1:统计字母出现的次数***");
/*
* 统计字符数组中每个字母出现的次数
* */
String ranString=fun6(10);//生成长度为30的随机小写字符串
System.out.println(ranString);
char[] arr=ranString.toCharArray();
int[] res=new int[26];
for (char c : arr) {
res[c-'a']++;
}
for (int i = 0; i < res.length; i++) {
if (res[i]>0) {
System.out.println((char)('a'+i)+"的个数为"+res[i]);
}
// System.out.println((char)('a'+i)+"的个数为"+res[i]);
}
}
//生成两个字符之间的随机字符[a,b]
public static char fun1(char a,char b) {
if (a>b) {
char t=a;
a=b;
b=t;
}
return (char)((int)(Math.random()*(b-a+1))+a);
}
//生成一个小写字母的字符
public static char fun2() {
return fun1('a', 'z');
}
//生成一个随机小写字母串
public static String fun6(int length) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(fun2());
}
return sb.toString();
}
9.8 顺序查找和二分查找
/*
* 设计一个方法,用于在指定的数组中查找指定的值,
* 如果找到,返回下标
* 如果没有找到,返回-1
* 思路∶顺序扫描
* */
//1.顺序查找 indexOf
//2.二分查找 binarySearch
/**
* 顺序查找
* @param arr 目标数组
* @param target 目标元素
* @return 找到返回 下标,否则返回-1
* */
public static int indexOf(int[] arr,int target) {
int res=-1;
for (int i = 0; i < arr.length; i++) {
if (arr[i]==target) {
res=i;
break;
}
}
return res;
}
/*
* 1.mid
* 2.比较,目标值和mid比较,
* 目标值大,去右侧找
* 目标值小,去左侧找
* 目标值和mid相同,返回mid的下标
* 3.再与新mid比较
* */
/**
* 二分查找
* @param arr 目标数组
* @param target 目标元素
* @return
* @return 找到返回 下标,否则返回-1
* */
// public static int binarySearch(int[] array, int key) {
// int low = 0;
// int high = array.length - 1;
// while (low <= high) {
// int mid = low + ((high - low) >> 1);
// if (array[mid] == key) {
// return mid;
// } else if (array[mid] < key) {
// low = mid + 1;
// } else {
// high = mid - 1;
// }
// }
// return -1;
//}
public static int binarySearch(int[] arr,int target) {
/*
* 1.mid
* 2.比较,目标值和mid比较,
* 目标值大,去右侧找
* 目标值小,去左侧找
* 目标值和mid相同,返回mid的下标
* 3.再与新mid比较
* */
//左右标尺
int begin=0;
int end=arr.length-1;
while (begin<=end) {
// int indexOfMid=length/2;
int mid=begin+((end-begin)>>1);
//或int mid=(begin+end)/2
int midValue=arr[mid];
if (target>midValue) {
begin=mid+1;
}
else if (target<midValue) {
end=mid-1;
}
else {
return mid;
}
}
return -1;
}
Util工具类:
class Util{
/**
* 获取指定范围指定个数的随机数组成的数组
* @param length 长度
* @param min 最小值
* @param max 最大值
* @return 数组
*/
public static int[] getRandomArr(int length,int min,int max) {
int[] arr=new int[length];
for (int i = 0; i < arr.length; i++) {
arr[i]=(int)(Math.random()*(max-min+1)+min);
}
return arr;
}
/**
* 打印数组
* @param arr 数组
*/
//两种方法
public static void printArr(int[] arr) {
// for (int i = 0; i < arr.length; i++) {
// System.out.print(arr[i]+"\t");
// }
for (int i : arr) {//i只读,只能正序输出
System.out.print(i+"\t");
}
System.out.println();
}
/**
*求数组元素和
*@param arr 数组
*@return 数组元素和
*/
public static int getSum(int[] arr) {
int sum=0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
return sum;
}
/**
*求数组元素平均值
*@param arr 数组
*@return 数组元素平均值
*/
public static int getAve(int[] arr) {
return getSum(arr)/arr.length;
}
/**
*最大元素及其下标
*@param arr 数组
*/
public static void getMax(int[] arr) {
int max=arr[0];
int indexOfMax=0;
for (int i = 0; i < arr.length; i++) {
if (arr[i]>max) {
max=arr[i];
indexOfMax=i;
}
}
System.out.println("最大值为:"+max);
System.out.println("下标为:"+indexOfMax);
}
/**
*最小元素及其下标
*@param arr 数组
*/
public static void getMin(int[] arr) {
int min=arr[0];
int indexOfMin=0;
for (int i = 0; i < arr.length; i++) {
if (arr[i]<min) {
min=arr[i];
indexOfMin=i;
}
}
System.out.println("最大值为:"+min);
System.out.println("下标为:"+indexOfMin);
}
/**
*随机打乱
*@param arr 数组
*/
public static void shuffle(int[] arr) {
for (int i = arr.length-1; i >= 0; i--) {
int j=(int) (Math.random()*(i+1));
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
/**
*向前依次移动
*@param arr 数组
*/
public static void moveForward(int[] arr) {
int temp = arr[0];//存第一个元素
for (int i = 1; i < arr.length; i++) {
arr[i-1]=arr[i];
}
arr[arr.length-1]=temp;
}
/**
*向后依次移动
*@param arr 数组
*/
public static void moveBack(int[] arr) {
int temp=arr[arr.length-1];
for (int i = arr.length-1; i > 0; i--) {
arr[i]=arr[i-1];
}
arr[0]=temp;
}
/**
*简化编程num2Month
*@param num 月份的数字形式
*/
//不用switch了
public static String num2Month(int num) {
String[] months= {"January","February","March","April",
"May","June","July","August",
"September","October","November","December"};
if (num<1||num>12) {
return "输入错误";
}
else {
return months[num-1];
}
}
/**元素交换
* @param arr int数组
* @param i 下标
* @param j 下标
*/
public static void swap(int[] arr,int i,int j) {
int tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
/**
* 顺序查找
* @param arr 目标数组
* @param target 目标元素
* @return 找到返回 下标,否则返回-1
* */
public static int indexOf(int[] arr,int target) {
int res=-1;
for (int i = 0; i < arr.length; i++) {
if (arr[i]==target) {
res=i;
break;
}
}
return res;
}
/**
* 二分查找
* @param arr 目标数组
* @param target 目标元素
* @return
* @return 找到返回 下标,否则返回-1
* */
// public static int binarySearch(int[] array, int key) {
// int low = 0;
// int high = array.length - 1;
// while (low <= high) {
// int mid = low + ((high - low) >> 1);
// if (array[mid] == key) {
// return mid;
// } else if (array[mid] < key) {
// low = mid + 1;
// } else {
// high = mid - 1;
// }
// }
// return -1;
//}
public static int binarySearch(int[] arr,int target) {
/*
* 1.mid
* 2.比较,目标值和mid比较,
* 目标值大,去右侧找
* 目标值小,去左侧找
* 目标值和mid相同,返回mid的下标
* 3.再与新mid比较
* */
//左右标尺
int begin=0;
int end=arr.length-1;
while (begin<=end) {
// int indexOfMid=length/2;
int mid=begin+((end-begin)>>1);
//或int mid=(begin+end)/2
int midValue=arr[mid];
if (target>midValue) {
begin=mid+1;
}
else if (target<midValue) {
end=mid-1;
}
else {
return mid;
}
}
return -1;
}
}
9.9 基础排序之冒泡
//可以类比站队
/**冒泡排序
* @param arr 数组
* */
public static void bubbleSort(int[] arr) {
//外层是天花板
for (int tianHuaBan = arr.length-1; tianHuaBan >= 0; tianHuaBan--) {//轮数
//在天花板内将最大的数组顶到天花板
for (int i = 0; i < tianHuaBan; i++) {//每轮比的次数
if (arr[i]>arr[i+1]) {
int temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
}
}
9.10 基础排序之选择排序
/**选择排序
* @param arr int数组
* */
public static void selectSort(int[] arr) {
//外层是天花板
for (int tianHuaBan = arr.length-1; tianHuaBan >= 0; tianHuaBan--) {
//在天花板范围内选一个最大的
int indexOfMax=0;
int max=arr[indexOfMax];
for (int i = 0; i <= tianHuaBan; i++) {
if (arr[i]>max) {
indexOfMax=i;
max=arr[i];
}
}
//内层for循环完成之后,天花板范围内的最大值及其下标就确定了
Util.swap(arr, indexOfMax, tianHuaBan);
}
}
9.11 基础排序之插入排序
//可以类比打扑克摸牌插牌
/**插入排序
* @param arr int数组
* */
// public static void insertionSort(int[] arr) {
// for (int i = 1; i < arr.length; i++) {
// int key = arr[i];
// int j = i - 1;
// while (j >= 0 && arr[j] > key) {
// arr[j + 1] = arr[j];
// j--;
// }
// arr[j + 1] = key;
// }
// }
public static void inserSort(int[] arr) {
//好比摸牌,从上到下一张一张去摸
for (int i = 1; i < arr.length; i++) {//一共length张牌要摸,开始时,手里有一张牌,还需要摸length-1张(1~length-1)
//这张牌的点数是arr[i]
//手上的牌0~i-1
/*if(新手牌<原有手牌中最末的那个)
* 原有手牌后挪
* */
int last=i-1;//原手牌最后一张
int now=arr[i];//新摸的手牌
//last=0或者新来的更大则退出循环
while (last>=0&&now<arr[last]) {//last>=0防止下标越界到-1,当last=-1时,是所有的都比新来的大的情况
arr[last+1]=arr[last];//原来的牌后挪
last--;//继续寻找更小的一张与新来的比
}
//新手牌合适的位置
arr[last+1]=now;
}
}
排序封装成类:
class SortDemo{
/**冒泡排序
* @param arr 数组
* */
public static void bubbleSort(int[] arr) {
//外层是天花板
for (int tianHuaBan = arr.length-1; tianHuaBan >= 0; tianHuaBan--) {
//在天花板内将最大的数组顶到天花板
for (int i = 0; i < tianHuaBan; i++) {
if (arr[i]>arr[i+1]) {
int temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
}
}
/**选择排序
* @param arr int数组
* */
public static void selectSort(int[] arr) {
//外层是天花板
for (int tianHuaBan = arr.length-1; tianHuaBan >= 0; tianHuaBan--) {
//在天花板范围内选一个最大的
int indexOfMax=0;
int max=arr[indexOfMax];
for (int i = 0; i < tianHuaBan; i++) {
if (arr[i]>max) {
indexOfMax=i;
max=arr[i];
}
}
//内层for循环完成之后,天花板范围内的最大值及其下标就确定了
Util.swap(arr, indexOfMax, tianHuaBan);
}
}
/**插入排序
* @param arr int数组
* */
// public static void insertionSort(int[] arr) {
// for (int i = 1; i < arr.length; i++) {
// int key = arr[i];
// int j = i - 1;
// while (j >= 0 && arr[j] > key) {
// arr[j + 1] = arr[j];
// j--;
// }
// arr[j + 1] = key;
// }
// }
public static void inserSort(int[] arr) {
//好比摸牌,从上到下一张一张去摸
for (int i = 0; i < arr.length; i++) {//一共length张牌要摸
//这张牌的点数是arr[i]
//手上的牌0~i-1
/*if(新手牌<原有手牌中最末的那个)
* 原有手牌后挪
* */
int last=i-1;//原手牌最后一张
int now=arr[i];//新摸的手牌
//last=0或者新来的更大则退出循环
while (last>=0&&now>arr[last]) {//last>=0防止下标越界到-1,即所有的都比新来的小的情况
arr[last+1]=arr[last];
last--;//更新最后一张牌
}
//新手牌合适的位置
arr[last+1]=now;
}
}
}
9.12 Arrays工具类
/*java.util.Arrays类包含一些实用的方法用于常见的数组操作,比如排序和查找
* 可以使用sort(使用了快排,从小到大排序)或者parallelSort方法对整个数组或部分数组进行排序
* 可以采用二分查找法(binarySearch方法)在有序数组中查找关键字
* 可以采用equals方法检测两个数组是否相等
* 可以使用fill 方法填充整个数组或部分数组
* 可以使用toString方法来返回一个字符串
*/
//9.12Arrays工具类
public static void test11(int[] arr) {
System.out.println("***9.12Arrays工具类***");
/*java.util.Arrays类包含一些实用的方法用于常见的数组操作,比如排序和查找
* 可以使用sort 或者parallelSort方法对整个数组或部分数组进行排序
* 可以采用二分查找法(binarySearch方法)在有序数组中查找关键字
* 可以采用equals方法检测两个数组是否相等
* 可以使用fill 方法填充整个数组或部分数组
* 可以使用toString方法来返回一个字符串
*/
Arrays.sort(arr);
int index=Arrays.binarySearch(arr, 45);
System.out.println(index);
Util.printArr(arr);
}
9.13 二维数组简介
如果不写第二维的长度,则地址指向为null。
//9.13二维数组简介
public static void test12() {
System.out.println("***9.13二维数组简介***");
int[][] a;//声明
int[][] arr=new int[5][];//创建
System.out.println(arr[0]);//输出null
int[][] arr1=new int[5][5];//创建
System.out.println(arr1[0]);//输出地址
System.out.println(arr1[0][0]);//默认0
//循环初始换
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr1[0].length; j++) {
arr1[i][j]=i*j;
}
}
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr1[i].length; j++) {
System.out.print(arr1[i][j]+"\t");
}
System.out.println();
}
//快捷初始化
int[][] arr2= {{1,3,5,7},{2,4,6,8}};
for (int i = 0; i < arr2.length; i++) {
for (int j = 0; j < arr2[i].length; j++) {
System.out.print(arr2[i][j]+"\t");
}
System.out.println();
}
//利用foreach输出
for (int i = 0; i < arr2.length; i++) {
for (int e:arr2[i]) {
System.out.print(e+"\t");
}
System.out.println();
}
//不规则二维数组
int[][] b= {{1,2},
{3,4,5,6},
{7,8,9}};
for (int i = 0; i < b.length; i++) {
int[] row=b[i];//把二维数组的每一个元素看出一维数组
for (int j : row) {
System.out.print(j+"\t");
}
System.out.println();
}
}
9.14 Case2:找出距离最小的点对
/*把10X2二维数组的每行的第1列作为x坐标,第2列作为y坐标,用二维坐标表示
* 找出距离最小的两个点
*/
//9.14 case2-找出距离最小的点对
public static void case2() {
System.out.println("***9.14 case2-找出距离最小的点对***");
/*把10X2二维数组的每行的第1列作为x坐标,第2列作为y坐标,用二维坐标表示
* 找出距离最小的两个点
*/
// double[][] arr=new double[10][2];//10行2列,即10个点
double[][] arr= {
{1,1},
{1,0.5},
{2,1},
{3,4},
{2.8,1},
{1,7},
{4,1.8},
{1.1,9},
{3,5},
{5,6}
};
// int mixDis=0;
double minDis=Double.MAX_VALUE;
int minI=0;
int minJ=0;
//i代表依次把每个点作为源点
for (int i = 0; i < arr.length; i++) {
//计算其余的点的距离,保留更小的距离
for (int j = i+1; j < arr.length; j++) {//j遍历除i之外的点
//(x1,y1)、(x2、y2)距离:
//((x1-x2)^2+(y1-y2)^2)^(1/2)
double x1=arr[i][0];
double x2=arr[j][0];
double y1=arr[i][1];
double y2=arr[j][1];
double dis = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
if (dis<minDis) {
minDis=dis;
minI=i;
minJ=j;
}
}
}
System.out.println("min distance:"+minDis+",i:"+minI+",j:"+minJ);
}
}