目录
(6)输出0~999之间的所有水仙花数(153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27)(水仙花数是一个三位数)
一:运算符
Java运算符来源于C,大体相同,稍有区别
1.除法/
注意:1.Java在整型运算中,除数是不能为0的,否则直接运行异常
2.在浮点数运算(float/double)中,引入了Infinity无穷大和NaN(Not a Number)不是一个数字这两个概念,来解决分母是0.0的情况和分子分母都是0.0的情况
3.关于正无穷、负无穷和0直接的一些运算java中的NAN和INFINITY - maozs - 博客园 (cnblogs.com)
https://www.cnblogs.com/zhisuoyu/p/5314541.html
2.取模%
注意:1.取模的结果由被除数的符号决定
2.小数之间也可以进行取模操作
3.类似的%运算符关于0.0和无穷大的一些运算
3.增量运算符+=、-=、%=、\=
注意:1.增量运算符会对不同类型的数据自动进行类型转换,比如+=
4.自增/自减运算符++、--
注意:1.a=0;a = a++; 这种操作并不会使得最后a=1,原因是a++先把a=0赋值给a,然后把a=0拷贝到一个临时变量区,再++,如此,a的值不会发生改变
2.a=a++的一道笔试题
5.关系运算符>、<、!=、==、>=、<=
注意:1.C中if(1<a<5)这种代码可以通过,但是Java不允许,因为1<a会有一个boolean值,但boolean类型并不包含非0为真,0为假的结论,即boolean类型不能和其他类型进行比较
6.逻辑运算符&&、||、!
注意:1.&&、||两边操作数必须是布尔表达式或布尔值,也就是只能是 true && false或 a<5 && b>6
2.(短路与)&&中第一个表达式为假,则不会执行第二个表达式;(短路或)||中第一个表达式为真,则不会执行第二个表达式,由此第二个表达式有语法错误也可能不会报错;短路操作可以提高程序的性能,避免不必要的计算
3.!接布尔表达式,比如:不能出现!a,能出现!(a<5)
4.|、&也存在或和与的功能,但是不存在短路或和短路与的功能,也就是int a = 0;(a<1 | a\0)这就会报错
5.逻辑运算符优先顺序: !> && > || ;逻辑运算符的结合性是从左到右的
7.位运算符&、|、~、^
按位与&
按位或|
按位异或^
按位取反~
注意:1.当&、|的操作数(int、short、long、byte)的时候,表示按位运算,当操作数位boolean的时候,表示逻辑运算,也就是具有了&&,||的部分功能
2.位运算操作符操作的是二进制数
8.移位运算
<<左移:扩大到两倍
>>右移:缩小到一半
无符号右移>>>:负数补码右移左边补上0
注意:1.左移、右移是移二进制位
2.左移、右移移动的都是补码,比如-1无符号右移1位
3.由于计算机计算移位效率高于计算乘除,程序乘除2的N次方的时候可以采用移位运算代替
4.移动负数位或者移动位数过大都没有意义
9.条件运算符
布尔表达式1 ?布尔表达式2 :布尔表达式3
注意:1.返回值必须符合接受变量的类型,除非发生隐式类型转换;表达式2和表达式3的结果要同类型的
2.表达式必须被引用,不能单独存在
10.运算符的优先级
运算符的优先级具体规则不必记忆,注意括号的使用即可
二:逻辑控制
顺序结构
选择结构
分支结构
1.if(布尔表达式)
2.switch语句
注意:1.可以做switch语句参数类型:char、byte、short、int、Character、Byte、Short、Integer、String 或枚举
2.不能做switch语句参数类型:long、float、double、boolean
循环结构
1. for
2.while(布尔表达式)
3.do while
输入输出
1.输出到控制台
int a = 0;
System.out.print(a);//输出不换行
System.out.println(a);//输出并换行
System.out.printf("%d ", a);//格式化输出,与C基本一致
2.从键盘输入
在笔试或者题目上经常需要用户自己输入数据
//导入Scanner包
import Java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
//scanner变量名可随便取
//System.in 从键盘获取数值
System.out.println("输入你的年龄:");
int age = scanner.nextInt();
System.out.println("年龄:"+age);
//scanner变量认为是一个资源,使用完需要关闭
scanner.close();
}
注意:1.sanner.next();读到空格结束
2.scanner.nextLine();读一行,能读空格
3.scanner.nextInt()和scanner.nextLine()的代码顺序会影响输出结果,当int在前的时候,line的输入会被省略;如:这个程序输入19后,在打印完"年龄19"和"请输入你的名字"后应该等待用户继续输入名字,但是控制台直接打印完"姓名:"后就结束进程了;所以我们输入数据有很多不同的类型时,优先取处理字符串的输入。
三: 基础练习:
(1)使用Scanner循环读取N个数字,并求取其平均值
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double sum = 0;//记录数的和
int num = 0;//记录输入了几个数
System.out.println("请输入N个数");
while(scanner.hasNextDouble()) {
double tmp = scanner.nextDouble();
sum += tmp;
num++;
}//idea中按ctrl+d退出输入
//cmd命令行中按ctrl+z退出输入
System.out.println("sum = "+sum);
System.out.printf("这%d个数的平均值是%.2f", num, sum/num);
scanner.close();
}
}
(2)写一个猜数字的游戏
import java.util.Random;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Random random = new Random();
//Random( seed: 6)只要有参数,根据固定参数生产的随机数是固定的,所以一般不写参数
Scanner scanner = new Scanner(System.in);
int num = random.nextInt(101);
//bound:101->[0,101) 0到100
//(bound:51)+50 ->[50,101) 50到100
System.out.println("请猜一个0~100之间的整数");
while(scanner.hasNextInt()) {
int num1 = scanner.nextInt();
if(num1>num){
System.out.println("猜大了");
continue;
}
else if(num1<num){
System.out.println("猜小了");
continue;
}
else{
System.out.println("猜对了");
break;
}
}
scanner.close();
}
}
(3)打印1~100之间的所有素数
//可优化地方:
//1.i%j的除数j可以是1~i、1~i/2、1~根号i
//2.除了2之外的偶数都不是素数,而规定1不是素数,从3开始的奇数,
// 所以外层循环i从3开始+=2
//3.在第二点的情况下,i%j,i是奇数,故奇数%偶数必定不为0,
// 所以j可以从3开始+=2
public class Main {
public static void main(String[] args) {
System.out.print(2+" ");
for (int i = 3; i <=100 ; i+=2) {
boolean flag = true;
for (int j = 3; j <= Math.sqrt(i); j+=2) {
if(i%j==0){
flag = false;
break;
}
}
if(flag) {
System.out.printf("%d ", i);
}
}
}
}
(4)输出1000~2000之间的闰年
public class Main {
public static void main(String[] args) {
//1.能被4而不能被100整除的是闰年
//2.每400年一闰
for (int i = 1000; i <= 2000 ; i++) {
if((i%4==0 && i%100!=0) || i%400==0 ) {
System.out.print(i+" ");
}
}
}
}
(5)输出乘法口诀表
//倒三角乘法表
public class Main {
public static void main(String[] args) {
int k = 1;
for (int i = 1; i <=9; i++) {
for (int j = k++; j <= 9; j++) {
System.out.print(i+"*"+j+"="+(j*i)+"\t" );// \t是制表符,打印出来的乘法表更规整
}
System.out.print("\n");
}
}
}
(6)输出0~999之间的所有水仙花数(153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27)(水仙花数是一个三位数)
public class Main {
public static void main(String[] args) {
for (int i = 100; i <= 999 ; i++) {//水仙花数定义是一个三位数
int a = i/100;//百位
int b = i%100/10;//十位
int c = i%10;//各位
if(a*a*a+b*b*b+c*c*c==i){
System.out.print(i+" ");
}
}
}
}
(7)写一个函数返回一个整数二进制原码中1的个数
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//问题:求一个数二进制中补码1的个数
//注意:正数的二进制补码是其本身,负数的补码与原码不一致
//思路:
//1.正数:利用按位与,与上1结果为1说明二进制最后一位是1,再利用右移操作进行移位操作,用一个变量count记录1的个数,输出count即可
//2.负数:负数的补码与原码不一致,我们如果采用正数的操作,会理所当然认为输出的count是负数的补码下的1的个数,其实不然,因为这里我们的右移操作对于负数来讲,右移在左边添加1,不仅count记录是错误的,连while循环也无法结束,我们需要改为无符号右移(>>>),每右移一位,左边加上0,这样输出1的个数就是补码中1的个数;
//具体操作:
//1.正数:(1)定义变量count用于记录二进制中补码1的个数
// (2)既然要进行移位操作,就需要用到循环,可以循环执行32次判断每一位是否是1;这里可以优化,只要每一位都是0,也就是这个数十进制就是0的时候,就不要进行判断了,所以可以先令count=0;如果这个数就是0,不需要进入循环进行判断
//2.负数:与正数操作同理
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个整数");
int count = 0;
int num = scanner.nextInt();
while (num != 0) {
if ((num & 1) == 1) {
count++;
}
num = num >>> 1;//无符号右移操作符:>>>
}
System.out.println("这个数二进制补码中1的个数为:"+count);
scanner.close();
}
}
(8)写一个函数返回一个整数二进制补码中1的个数
//问题:求一个整数二进制补码中1的个数
//思路一:1.正数与原码求1的个数一致
// 2.负数是以补码保存的,如何显示地表示出它的原码呢?负数原码到反码是符号位不变,其他位均相反,再加一就是补码;那么有人会认为我们让输入的整数-1再进行取反就可以,其实很明显是行不通的,因为补码进行的是位操作,而输入的整数-1通过底层原理实现的,其操作位数不是一位一位进行的;所以我们要进行位操作实现-1,那么谁能够实现-1操作呢?
// 我们可以想到负数中奇数不管是原码还是补码,最后一位都是1,偶数则是0;所以奇数按位与上0,最后一位从1变成了0,相当于补码减一;偶数要想实现减1,就需要找到从右往左的第一个1,该位的1变成0,右边的0都变成1;
// 也就是与上1,让1左移,用变量i记录位置,直到结果是1,退出循环。//其实这里可以一步到位,按位异或上1,将1左移,直到结果是0即可
// 完成了-1操作,再除符号位按位取反即可,反31次;但我们同时把符号位也变成0,这样记录的count就是除了符号位1的其余31位中1的个数
public class Main{
public void static main(String[] args){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个整数:");
int num = scanner.nextInt();
int count = 0;
//减一操作:1.奇数补码最后一位按位与上按位取反的1即可,偶数需要循环按位异或1
int i = 1;
if(num<0) {
count = 1;
if (num % 2 != 0) {
//奇数
num = num & (~1);
} else {
//偶数
//找到从右往左的第一个1
int j = 1;
while ((num & j) != 1) {
i++;
j = j << 1;
}
//第i位右边的0都取反
int k = 1;
while (i-- > 1) {
num = num | (k << 1);
}
}
//取反操作
num = ~num;
}
while (num != 0) {
if ((num & 1) == 1) {
count++;
}
num = num >>> 1;//无符号右移操作符:>>>
}
System.out.println("这个数二进制补码中1的个数为:"+count);
scanner.close();
}
}
public class Main{
public static void main(String[] args) {
System.out.println("请输入一个整数:");
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
int count = 0;
if(num<0)
{
count = 1;
//先取反
num = ~num;
//再+1
num += 0B001;
}
while (num != 0) {
if ((num & 1) == 1) {
count++;
}
num = num >>> 1;//无符号右移操作符:>>>
}
System.out.println("这个数二进制补码中1的个数为:"+count);
scanner.close();
}
}
(9)分别输出一个数二进制中奇数位和偶数位的序列
public class Main{
public static void main(String[] args) {
System.out.println("请输入一个整数:");
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
int i = 31;
int j = 30;
//输出偶数位
System.out.print("偶数序列是:");
while(i>=1) {
System.out.print(((num&(1<<i))>>i)+" ");
//System.out.print(((num>>i)&1)+" ");
i-=2;
}
System.out.println("\n");
//输出奇数位
System.out.print("奇数序列是:");
while(j>=0){
System.out.print(((num&(1<<j))>>j)+" ");
//System.out.print(((num>>j)&1)+" ");
j-=2;
}
scanner.close();
}
}