0709(005天 习题课 旧题新作)
1. 计算输入数据的阶乘(注意数据溢出)
通过这个程序得知整形的存储最多可以算到 12!
System.out.print("请输入一个正整数:");
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
if (num < 0 && num >= 13) {
// 12!*13 = 479001600*13 = 6,227,020,800
// 13! = 1,932,053,504
System.out.println("本程序仅能计算1-12的阶乘");
} else {
int res = 1;
for (int i = 1; i <= num; i++) {
res *= i;
}
System.out.println(num + "! = " + res);
}
2. 互换两个数的值(不允许使用中间变量)
- 建立临时变量
- 加减运算交换
- 位运算方法
加减法
num1 = 10, num2 = 6;
num1 = num1 + num2; // num1 = 16 num2 = 6
num2 = num2 - num1; // num1 = 16 num2 = 10
num1 = num1 - num2; // num1 = 6 num2 = 10
3. 输出三个数中的最大值和最小值
- if_else语句
- 三目运算
- math.max()、math.min()
// if else
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个整数:");
int num1 = sc.nextInt();
System.out.println("请输入第二个整数");
int num2 = sc.nextInt();
System.out.println("请输入第三个整数");
int num3 = sc.nextInt();
int max = num1;
if (num2 > max) {
max = num2;
}
if (num3 > max) {
max = num3;
}
int min = num1;
if (num2 < min) {
min = num2;
}
if (num3 < min) {
min = num3;
}
System.out.println(
"num1 = " + num1 + ", " + "num2 = " + num2 + ", num3 = " + num3 + ", max = " + max + ", min = " + min);
// 三目运算符
min = num1 < num2 ? num1 : num2;
min = min < num3 ? min : num3;
max = num1 > num2 ? num1 : num2;
max = max > num3 ? max : num3;
// math.max()、math.min()
min = Math.min(num1, num2);
min = Math.min(min, num3);
max = Math.max(num1, num2);
max = Math.max(max, num3);
4. 输出1-100的奇数(每行输出6个)
判定奇数
- 暴力循环+条件判断
- 合适的起始点+合适的步长
每行输出6个
- 在循环中判定循环控制变量的特定值就可以
- 在外边添加一个计数器来判定并输出换行(这里要注意的是要判定输出换行的程序要和输出数据的程序放在一起,要不就会出现多次的输出回车的现象)
// 输出1-100的奇数(每行输出6个)
for (int i = 1; i <= 100; i++) {
if (i % 12 == 0) {
System.out.println("");
}
if (i % 2 == 1) {
System.out.print(i + "\t");
}
}
5. 1-100求和(for while以及do/while的写法)
// 1-100求和(for while以及do/while的写法)
// for
int res = 0;
for (int i = 1; i <= 100; i++) {
res += i;
}
System.out.println("sum(1-100) = " + res);
// while
res = 0;
int i = 0;
while (++i <= 100) {
res += i;
}
System.out.println("sum(1-100) = " + res);
// do/while
res = 0;
i = 1;
do {
res += i;
i++;
} while (i <= 100);
System.out.println("sum(1-100) = " + res);
6. 1-100奇数求和
// 1-100奇数求和
int res = 0;
for (int i = 1; i < 100; i += 2) {
res += i;
}
System.out.println("1-100奇数和为" + res);
7. 1~100可以被3整除的数
// 1~100可以被3整除的数
int res = 0;
int n = 0;
for (int i = 0; i <= 100; i++) { // 这里可以将步长设定为 3 从0开始加3肯定可以被3整除
if (i % 3 == 0) {
res += i;
n++;
}
}
System.out.println("1~100可以被3整除的数有" + n + "个,求和为" + res);
8. 求100 以内所有能被3 整除但不能被5 整除的个数
// 求100 以内所有能被3 整除但不能被5 整除的个数
int n = 0;
for (int i = 0; i <= 100; i++) {
if (i % 3 == 0 && i % 5 != 0) {
n++;
}
}
System.out.println("100以内能被 3 整除不能被 5 整除的个数有 " + n);
9. 打印出所有的水仙花数
// 打印出所有的水仙花数
// 水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身
// (例如:1^3 + 5^3+ 3^3 = 153)。
System.out.print("水仙花数:有");
for (int i = 100; i < 1000; i++) {
int num1 = i % 10;
int num2 = (i / 10) % 10;
int num3 = i / 100;
//System.out.println(i + " 1 = " + num1 + " 2 = " + num2 + " 3 = " + num3);
if ((num1 * num1 * num1 + num2 * num2 * num2 + num3 * num3 * num3) == i) {
System.out.print(i + "、");
}
}
10. 键盘录入判断一个数是否质数
这里的for循环的次数可以改成 根号num 来减少循环次数
比根号num小的数都有可能成为num的因数,而对于在根号num到num之间的数作为其中一个因数,那么另一个因数必定是0~根号num之间。
// 判断一个数是否质数
// 质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数
// 否则称为合数(规定1既不是质数也不是合数)。
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个需要判断的整数");
int num1 = sc.nextInt();
if (num1 < 1) {
System.out.println("请输入一个大于1的自然数");
} else if (num1 == 1) {
System.out.println(num1 + "既不是质数也不是合数");
} else {
int i = 1;
while (++i < num1) {
if (num1 % i == 0) {
System.out.println(num1 + "不是质数");
break;
}
}
if (num1 == i) {
System.out.println(num1 + "是质数");
}
}
11. 自然数101-205中的所有质数
// 编程求出自然数101-205中的所有质数
System.out.println("101-205中所有的质数如下所示:");
for (int i = 101; i <= 205; i++) {
int n = 2;
for (; n <= i; n++) {
if (i % n == 0)
break;
}
if (n == i) {
System.out.println(i);
}
}
System.out.println("结束");
12. 求两个数的最大公约数和最小公倍数
题目要求:输入两个正整数m和n,求其最大公约数和最小公倍数
while:用来判定用户输入的正确性
// 输入两个正整数m和n,求其最大公约数 和 最小公倍数
Scanner sc = new Scanner(System.in);
int num1 = 0;
System.out.println("请输入第一个整数:");
while (true) {
num1 = sc.nextInt();
if (num1 > 0) {
break;
} else {
System.out.println("超出范围,请重新输入(>0)");
}
}
int num2 = 0;
System.out.println("请输入第二个整数");
while (true) {
num2 = sc.nextInt();
if (num1 > 0) {
break;
} else {
System.out.println("超出范围,请重新输入(>0)");
}
}
int gongBei = Math.max(num1, num2);
int gongYue = Math.min(num1, num2);
while (gongYue > 1) {
if (num1 % gongYue == 0 && num2 % gongYue == 0) {
break;
}
gongYue--;
}
while (true) {
if (gongBei % num1 == 0 && gongBei % num2 == 0) {
break;
}
gongBei++;
}
System.out.println(gongYue);
if (gongYue != 1) {
System.out.println(num1 + "和" + num2 + "的最大公约数为" + gongYue);
} else {
System.out.println(num1 + "和" + num2 + "没有最大公约数");
}
System.out.println(num1 + "和" + num2 + "的最小公倍数为" + gongBei);
sc.close();
13. 找出五位数的各个位数之和为5
100 ~ 50000之间有多少整数,其各位数字之和为5,分别是哪些数(例如整数1324的各位数字之和为 1+3+2+4 等于10(不为5)),并统计满足条件的整数有多少个
暴力解法:循环100到50000,挨个判断
// 100 ~ 50000之间有多少整数,其各位数字之和为5,
// 分别是哪些数(例如整数1324的各位数字之和为 1+3+2+4 等于10(不为5)),并统计满足条件的整数有多少个
// 其各位数字之和为5,
//
int n = 0; // 计数器
for (int i = 100; i <= 50000; i++) {
int num1 = i % 10;
int num2 = (i / 10) % 10;
int num3 = (i / 100) % 10;
int num4 = (i / 1000) % 10;
int num5 = (i / 10000) % 10;
// System.out.println(num1 + "、" + num2 + "、" + num3 + "、" + num4 + "、" + num5);
if ((num1 + num2 + num3 + num4 + num5) == 5) {
n++;
System.out.println(i + "其各位数字之和为5,");
}
}
System.out.println("100 ~ 50000之间有" + n + "个整数,其各位数字之和为5");
歪路子:多层循环,每层循环代表一位数(循环的范围控制在5以内),在最里边拼接出来一个 整数,就很奈斯,
这里的多层循环由于循环次数已知,所以时间复杂度其实还是常数级
// 拼接解法
int n = 0;
int i = 0;
for (int n1 = 0; n1 <= 5; n1++) {
for (int n2 = 0; n2 <= 5 - n1; n2++) {
for (int n3 = 0; n3 <= 5 - (n1 + n2); n3++) {
for (int n4 = 0; n4 <= 5 - (n1 + n2 + n3); n4++) {
i++;
int n5 = 5 - (n1 + n2 + n3 + n4);
int num = n1 * 10000 + n2 * 1000 + n3 * 100 + n4 * 10 + n5;
if (num < 100) { // 坑:没用这个判断之前是直接限定百位数从1到5;但是这样就有多数就找不到,这里加一个判断
break;
}
if ((n1 + n2 + n3 + n4 + n5) == 5 && n5 >= 0) {
System.out.println(num);
n++;
}
}
}
}
}
System.out.println("\n" + n + "个");
System.out.println("共循环了" + i + "次");
这个遍历次数感觉上当了呀
14. 鸡兔同笼
鸡兔同笼共80个头,208只脚,鸡和兔各有几只
- 纯纯暴力破解:双层循环一层代表一个
// 鸡兔同笼共80个头,208只脚,鸡和兔各有几只
int ji = 0;
int tu = 80;
while ((ji * 2 + tu * 4) != 208) {
ji++;
tu--;
}
System.out.println("鸡兔同笼共80个头,208只脚,鸡有" + ji + "只、兔有" + tu + "只");
- 歪路子:这个其实可以找到一个动物的取值范围(另一个动物的只数可以通过条件计算出来),判断动物的分区是否满足指定的脚数
// 鸡兔同笼共80个头,208只脚,鸡和兔各有几只
int tuZi = 0;
int ji = 0;
for (; tuZi < 208 / 4; tuZi++) {
ji = (208 - 4 * tuZi) / 2;
if ((tuZi + ji) == 80) {
System.out.println("鸡兔同笼共80个头,208只脚,鸡有" + tuZi + "兔有" + ji);
}
}
15. 百鸡百钱
鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。
百钱买百鸡,问鸡翁、鸡母、鸡雏各几何,公鸡一只5钱,母鸡一只3钱,小鸡一钱3只
- 暴力破解
// 鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何
int jiWong = 0;
int jiMu = 0;
int jiChu = 0;
for (; jiWong <= 20; jiWong++) {
for (jiMu = 0; jiMu <= 34; jiMu++) {
for (jiChu = 0; jiChu <= 300; jiChu += 3) {
//System.out.println((jiWong + jiMu + jiChu) + "只" + (jiWong * 5 + jiMu * 3 + (int) (jiChu / 3)) + "钱");
if ((jiWong + jiMu + jiChu) == 100 && (jiWong * 5 + jiMu * 3 + (int) (jiChu / 3)) == 100) {
System.out.println("鸡翁" + jiWong + "只、鸡母" + jiMu + "只、鸡雏" + jiChu + "只满足百钱买白鸡");
}
}
}
}
System.out.println("结束");
- 歪路子
- 最内层循环控制的变量可以通过外层循环来计算得来,及可以少一层循环
- 公鸡循环次数可以控制在
总钱数/公鸡价值
以内 - 母鸡的循环次数可以控制在
(总钱数 - 公鸡数量*公鸡价值)整除以母鸡价值
以内
// 百钱白鸡 鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。
int gong = 0;
int mu = 0;
int xiao = 0;
for (gong = 0; gong < 20; gong++) {
for (mu = 0; mu < (100 - gong * 5) / 3; mu++) {
xiao = (100 - gong * 5 - mu * 3) * 3;
if ((gong + mu + xiao) == 100) {
System.out.println("公鸡=" + gong + "、母鸡=" + mu + "、小鸡=" + xiao);
}
}
}
B
1. 统计位数为偶数的数字
给你一个整数数组 nums,请你返回其中位数为偶数的数字的个数。
- 暴力:没有技巧全是时间
// 统计位数为偶数的数字
Scanner sc = new Scanner(System.in);
// int[] numList = { 1, 2, 3 };
System.out.println("请输入一个大于0的正整数来表示你要输入多少个数据");
int nNum = 0;
while (true) {
nNum = sc.nextInt();
if (nNum <= 0) {
System.out.println("输入有误请重新输入");
} else {
break;
}
}
int[] numList = new int[nNum];
for (int i = 0; i < nNum; i++) {
System.out.print("\n请输入第" + (i + 1) + "个整数:");
numList[i] = sc.nextInt();
}
int ouNum = 0; // 用于存储偶数的个数
System.out.println("您输入的数据如下所示:");
for (int tempNum = 0; tempNum < numList.length; tempNum++) {
System.out.print(numList[tempNum] + "、");
while (numList[tempNum] != 0) { // 循环除以 10 以获取各个位数上的数据
if (numList[tempNum] % 2 == 0) { // 这个数是偶数,这个数的个位数一定也就是一个偶数
ouNum++;
break;
} else {
numList[tempNum] /= 10;
}
}
}
System.out.println("\n这里一共有" + ouNum + "个数里含有偶数");
2. 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返 回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
扩展芝士
数组
你是否还在为变量名的创建而发愁,是不是还在用n1、n2、n3…在为同类型变量命名,是不是已经因为声明变量而频繁的使用cv大法,数组他来了,抛弃原有的变量名,你只需要给他一个长度、一个类型,用于告知它你要存放的数据的数量和数据类型,同是在赋予它一个优雅的名字(数组),他就可以放下海量数据,同是还可以通过索引的方法来操作数组内部的任意一个值,同是他还亲切的提供了很多操作方法属性,让你随心所欲并且高效的数据处理。
数组的应用可是说是相当的广泛了,大家所熟知的数据库一样,他可以将拥有一定模式信息的信息以二维表的形式存储到数据库中,我们想要找啥数据直接select就行了,当然增删改查都得是基本功。一维数组就相当于只有一个标签的表格,它的索引就像是表格中的主键。
这里的数组就像是一个书架一样,只不过书架中有很多的格子,格子等宽,(在java中为了方便为数组分配空间,有定长数组和可变数组两种这里说的是定长的),我们想要往里边放一本书(数据),只需要找到想要放的书架的编号,把书塞进去,要用的时候,可以通过编号在从书架中吧对应的书拿出来看。
数组在这里充当的就是这个书架的作用,用于存储同一类型的不同数据值。方便我们后期调用
基本创建赋值
// 定长数组创建 存储类型[] 变量名 = new 存储类型[数组大小];
int[] numList = new int[2];
// 声明并赋值 存储类型[] 变量名 = {指定类型的数据 以',' 分割};
// type[] arrayName = new type[]{值 1,值 2,值 3,值 4,• • •,值 n};
int[] numList1 = { 1, 2, 3 };
// 数组赋值
numList[0] = 4;
numList[1] = 5;
// 数组索引
int x = numList[0];
System.out.println(x);
循环遍历
For-Each 循环
JDK 1.5 引进了一种新的循环类型,被称为 For-Each 循环或者加强型循环,它能在不使用下标的情况下遍历数组。
语法格式如下:
// for(存储的类型 变量名: 数组名){System.out.println(变量名);}
for(int tempNum: numList){ // 遍历循环
System.out.println(tempNum);
}
// 索引遍历循环
for (int tempNum = 0; tempNum < numList.length; tempNum++) {
System.out.println(numList[tempNum]);
}
常用操作
package com.b.xiti;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Test02 {
public static void main(String[] args) {
// 判断元素是否存在于数组中
Integer[] numList = { 1, 2, 3, 4, 5, 6, 4 };
Set<Integer> numSet = new HashSet<>(Arrays.asList(numList));// 先将数组转换为List
System.out.println(numSet.contains(5));// 再用contains判断是否存在
}
}
// 比较数组:通过 equals 方法比较数组中元素值是否相等。
int[] numList = { 1, 2, 3, 4, 5, 6, 4 };
int[] numList2 = { 2 };
System.out.println(numList.equals(numList2));
System.out.println(numList.equals(numList));
// 获取元素在数组中的索引
// 存在
// 返回索引位置
// 不存在
// 返回负值
// 值的大小表示这个值如果按照顺序插入的或应该会存放的位置
Integer[] nums = { 2, 7, 11, 15 };
System.out.println(Arrays.binarySearch(nums, 0));