练习
前言
只有练习才能更好地巩固知识:
Practice makes perfect!
开始学习!
一、打印 1 - 100 之间所有的素数(方法:判断一个数是否为素数)
素数: for循环–i初始放到外面–好判断
优化: 循环效率-缩小范围- 2~sqrt(n) or 2~n/2 (取等号)
注意参数类型–隐式转换–可以使用方法
- 代码:
import java.util.Scanner;
/**
* 打印 1 - 100 之间所有的素数
* 方法:判断素数
*/
public class PrimeNum {
public static boolean isPrime(int n) {
if(1 == n) {
return false;
} else {
for (int i = 2; i <= Math.sqrt(n); i++) { //优化循环次数
if((0 == n % i)) {
return false;
}
}
return true;
}
}
public static void main(String[] args) {
/* Scanner reader = new Scanner(System.in); //键盘输入
//如果键盘输入需要判断是否 >0
System.out.print("从键盘输入一个数字:");
int n = reader.nextInt();
if(n > 0) {
if(isPrime(n)) {
System.out.print(n+"是素数");
} else {
System.out.print(n+"不是素数");
}
} else{
System.out.println("输入错误!");
}*/
System.out.println("1 - 100 之间所有的素数:");
for(int i =1; i <= 100; i++) {
if(isPrime(i)) {
System.out.print(i+" ");
}
}
}
}
- 结果:
二、求自幂数
1.自幂数
自幂数:如果在一个固定的进制中,一个n位自然数等于自身各个数位上数字的n次幂之和,则称此数为自幂数
2.思路:
- 求出一个数字一共有多少位数字
- 每一位的数字是多少
- 注意:
注意:sum += Math.pow(); //不报错,+=自动进行类型转换
sum = sum + Math.pow(); //报错,类型提升,应该用double接收
3.代码(为了运行效率,此处只求至六位数-思路一样)
/**
* 自幂数
* 一位自幂数:独身数
* 两位自幂数:没有
* 三位自幂数:水仙花数
* 四位自幂数:四叶玫瑰数
* 五位自幂数:五角星数
* 六位自幂数:六合数
*/
public class SelfPowerNum {
// 判断位数
public static int count(int n) {
int count = 0;
while(n != 0) {
count++;
n /= 10;
}
return count;
}
// 判断自幂数
public static boolean isSelfPower(int n, int count) {
int sum =0;
int tmp = n; //一定要设置临时值,不然会被改变值
while(tmp != 0) {
//Math.pow(double,double)--此处参数被隐式转换为double类型
// 返回值是double型,但是+= 带有自动转换机制
// sum = sum + Math.pow((n%10),count); //error!!
sum += Math.pow((tmp%10),count);
tmp /= 10;
}
if(sum == n) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
for (int i = 1; i <= 999999; i++) {
int count = count(i);
if(isSelfPower(i,count) == true) {
switch(count) {
case 1:
System.out.println("独身数:"+i+" ");
break;
case 2:
break;
case 3:
System.out.println("水仙花数:"+i+" ");
break;
case 4:
System.out.println("四叶玫瑰数:"+i+" ");
break;
case 5:
System.out.println("五角星数:"+i+" ");
break;
case 6:
System.out.println("六合数:"+i+" ");
break;
default:
System.out.println("error!");
break;
}
}
}
}
}
- 结果:
三、求两个正整数的最大公约数
1. 注意点:
- 求最大公约数–辗转相除法–余数为0,则除数为最大公约数
- 补充:最小公倍数=两个数相乘/最大公约数
- 作业:求最小公倍数!
2. 最大公约数代码
import java.util.Scanner;
/**
* 求两个正整数的最大公约数
* 辗转相除法
* 除数/余数,直至余数=0
* 除数就是这两个数的最大公约数
*/
public class MaxDiv {
public static int maxDiv(int a, int b) {
int c = a % b;
while(c != 0) {
a = b;
b = c;
c = a % b;
}
return b;
}
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("请输入任意两个整数:");
int a = reader.nextInt();
int b = reader.nextInt();
System.out.println("最大公约数:");
System.out.println(maxDiv(a,b));
}
}
- 结果:
3. 最小公倍数
import java.util.Scanner;
/**
* 求两个正整数的最小公倍数
* 辗转相除法求最大公约数
* 两个数相乘/最大公约数
*/
public class MinMul{
//最大公约数
public static int maxDiv(int a, int b) {
int c = a % b;
while(c != 0) {
a = b;
b = c;
c = a % b;
}
return b;
}
//最小公倍数
public static int minMul(int a, int b, int c) {
return (a*b/c);
}
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("请输入任意两个整数:");
int a = reader.nextInt();
int b = reader.nextInt();
int c = maxDiv(a,b);
System.out.println("最小公倍数:");
System.out.println(minMul(a,b,c));
}
}
- 结果:
四、写一个函数返回参数二进制中 1 的个数
比如: 15 0000 1111 4 个 1
1. 注
- 移位+按位与1–效率太低
- 优化: 移位后判断原来的数是否已经等于0-- while循环+无符号右移
- 再优化: n = n & (n-1);
2. 代码:(包含以上三种方式)
import java.util.Scanner;
/**
* 写一个函数返回参数二进制中 1 的个数
*/
public class Num1 {
//方法一:移位+按位与1
public static int count1(int n) {
int count1 =0;
for(int i =0; i < 32; i++) {
if(1 == ((n>>i)&1)) {
count1++;
}
}
return count1;
}
// 移位后判断原来的数是否已经等于0: while循环+无符号右移
public static int count2(int n) {
int i = 0;
int count2 =0;
while((n>>>i) != 0) {
if(1 == ((n>>>i)&1)) {
count2++;
}
i++;
}
return count2;
}
// 方法三:n=n&(n-1) n!=0的次数就是1的个数
public static int count3(int n) {
int count =0;
while(n !=0) {
n &= (n-1);
count++;
}
return count;
}
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.print("请输入任意一个整数:");
int n = reader.nextInt();
System.out.println("1的个数:");
System.out.println("方法一:"+count1(n));
System.out.println("方法二:"+count2(n));
System.out.println("方法三:"+count3(n));
}
}
- 结果:
3.扩展:判断一个正整数是不是2的k次方
思路:2的k次方二进制只有一个1,so:n=n & (n-1) ==0
代码:
import java.util.Scanner;
/**
* 判断一个正整数是不是2的k次方
* 思路:2的k次方二进制只有一个1,so:n=n & (n-1) ==0
*/
public class Is2Pow {
public static boolean is2Pow(int n) {
if(0 == ((n & (n-1)))) {
return true;
}
return false;
}
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("请任意输入一个整数:");
int n = reader.nextInt();
if(is2Pow(n)) {
System.out.println("是2的次方");
} else {
System.out.println("不是2的次方");
}
}
}
结果:
五、 获取一个数二进制序列中所有的偶数位和奇数位,分别输出二进制序列
代码:
import java.util.Scanner;
/**
* 获取一个数二进制序列中所有的偶数位和奇数位,分别输出二进制序列
*/
public class Print {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("请任意输入一个整数:");
int n = reader.nextInt();
System.out.println("偶数位:");
for (int i = 31; i >=0 ; i-=2) { //注意循环条件
//偶数位
System.out.print(((n>>i)&1)+" ");
}
System.out.println(); //换行
System.out.println("奇数位:");
for (int i = 30; i >=0 ; i-=2) { //注意循环条件
//偶数位
System.out.print(((n>>i)&1)+" ");
}
System.out.println(); //换行
}
}
结果:
六、模拟登陆:输入字符串、比较字符串内容
- == 判断的是地址
- 代码:
import java.util.Scanner;
/**
* 编写代码模拟三次密码输入的场景。
* 最多能输入三次密码,密码正确,提示“登录成功”,密码错误, 可以重新输 入,
* 最多输入三次。三次均错,则提示退出程序
*/
public class Log {
public static void main(String[] args) {
int n = 3;
String password = "lovejava88";
Scanner reader = new Scanner(System.in);
System.out.println("请输入密码:");
while(n > 0) {
n--; //一进来就进行--
String input = reader.nextLine();// 可有空格
if(password.equals(input)) { //比较两个字符串内容相等吗
System.out.println("登陆成功");
break;
} else if(n >= 1){
System.out.println("请重新输入密码:");
continue;
}
}
if(n < 0) {
System.out.println("三次输入密码失败 退出程序");
}
}
}
- 结果:
THINK
今日份练习结束啦!
主要掌握:
- 计算二进制表示的1的个数的方法
- 2的k次方只有1个1-- n & (n-1)
- 比较字符串内容以及地址
- 最大公约数(辗转相除法)
- 最小公倍数(两个数相乘/最大公约数)