目录
打印乘法口诀表:
// 打印乘法口诀表(正排)
for (int i = 1; i <= 9; i++) { // 外循环控制行数
for (int j = 1; j <= i; j++) { // 内循环控制列数
System.out.print(j + " * " + i + " =" + j * i + "\t");
}
System.out.println();
}
test:
// 打印乘法口诀表(倒排)
for (int i = 9; i >= 1; i--) { // 外循环控制行数
for (int j = 1; j <= i ; j++) { // // 内循环控制列数
System.out.print(j + " * " + i + " =" + j * i + "\t");
}
System.out.println();
}
test:
打印长方形,平行四边形,三角形:
打印长方形:
// 长方形
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 10; j++) {
System.out.print("@ ");
}
System.out.println();
}
test:
// 前面有一定间距的长方形
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
System.out.print(" ");
}
for (int j = 0; j < 12; j++) {
System.out.print("<> ");
}
System.out.println();
}
test:
打印平行四边形:
// 打印平行四边形(正向)
for (int i = 0; i < 5; i++) { // 控制行数
for (int j = 0; j < 12 - i; j++) {//控制每行的空格个数
System.out.print(" ");
}
for (int k = 0; k < 9; k++) {// 控制每行的🐕的个数
System.out.print("🐕 ");
}
System.out.println();
}
test:
// 打印平行四边形(逆向)
for (int i = 0; i < 5; i++) { // 控制行数
for (int j = 0; j < i * 3 - i; j++) {//控制每行的空格个数
System.out.print(" ");
}
System.out.print('\t');
for (int k = 0; k < 9; k++) { // 控制每行的🐕的个数
System.out.print("🐕 ");
}
System.out.println();
}
test:
打印三角形:
// 打印三角形(正三角)
for (int i = 1; i <= 6; i++) { // 控制行数
for (int j = 1; j <= 11 - i; j++) { // 控制每行的空格个数
System.out.print(" ");
}
for (int j = 1; j <= 2 * i - 1; j++) { // 控制每行的A 的个数
System.out.print("A");
}
System.out.println();
}
test:
// 打印三角形(倒三角)
for (int i = 6; i >= 1; i--) { // 控制行数
for (int j = 1; j <= 11 - i; j++) { // 控制每行的空格个数
System.out.print(" ");
}
for (int j = 2 * i-1; j >= 1; j--) { // 控制每行的A 的个数
System.out.print("Y");
}
System.out.println();
}
test:
打印菱形和空心菱形:
实心菱形:
(可以使用正三角和倒三角的循环拼起来,不过这种方式没什么用。)
printLozenge(15);
private static void printLozenge(int size) {
// 打印实心菱形,菱形其实就是一个正方形每个角度是一样的切出来的形状
// 也是正三角和倒三角拼接出来的形状,菱形的每行都是奇数,没有偶数。
int highSize = size; //菱形行高
int startPlace = highSize / 2 + 1; // 开始位置
int endPlace = highSize / 2 + 1; // 结束位置
boolean mark = true;
for (int i = 1; i <= highSize; i++) { // 外循环控制高度
for (int j = 1; j <= highSize; j++) {// 内循环控制每行的打印的 A 的个数
// 如果当 j 大于等于 开始位置 且 小于等于结束位置,打印 A ,否则打印空格
if (j >= startPlace && j <= endPlace) {
System.out.print("A");
} else {
System.out.print(" ");
}
}
// 换行
System.out.println();
// 当 mark 为true的时候说明在打印菱形的上半,
// 当mark 为false的时候说明在打印菱形的下半。
if (mark) {
startPlace--; // 开始位置逐渐减小
endPlace++; // 结束位置逐渐增加,逼近与菱形的highSize。
} else {
// 下半的操作和上半的相反!
startPlace++;
endPlace--;
}
// 当endPlace等于highSize的时候,就把标记改为false
if (endPlace == highSize) {
mark = !mark;
}
}
}
test:
空心菱形:
// 打印空心菱形
printHollowLozenge(17);
private static void printHollowLozenge(int size) {
// 打印实心菱形,菱形其实就是一个正方形每个角度是一样的切出来的形状
// 也是正三角和倒三角拼接出来的形状,菱形的每行都是奇数,没有偶数。
int highSize = size; //菱形行高
int startPlace = highSize / 2 + 1; // 开始位置
int endPlace = highSize / 2 + 1; // 结束位置
boolean mark = true;
for (int i = 1; i <= highSize; i++) { // 外循环控制高度
for (int j = 1; j <= highSize; j++) {// 内循环控制每行的打印的 A 的个数
// 如果当 j 等于 开始位置 或者 等于结束位置,打印 A ,否则打印空格
if (j == startPlace || j == endPlace) {
System.out.print("A");
} else {
System.out.print(" ");
}
}
// 换行
System.out.println();
// 当 mark 为true的时候说明在打印菱形的上半,
// 当mark 为false的时候说明在打印菱形的下半。
if (mark) {
startPlace--; // 开始位置逐渐减小
endPlace++; // 结束位置逐渐增加,逼近与菱形的highSize。
} else {
// 下半的操作和上半的相反!
startPlace++;
endPlace--;
}
// 当endPlace等于highSize的时候,就把标记改为false
if (endPlace == highSize) {
mark = !mark;
}
}
}
test:
打印字母金字塔:
// 打印字母金字塔
printLetterPyramid(26);
private static void printLetterPyramid(int pySize) {
// 用给定的金字塔的大小 得到 打印字母之前的间距
int space = (pySize / 2 - pySize / 4) + pySize;
// 声明 4个变量
int i, j, k, l;
// 1号 外循环控制字母金字塔的行数!
for (i = 1; i <= pySize; i++) {
// 2号 内循环控制 每行打印之间留出来的空格!
for (j = 1; j < space - i; j++) {
System.out.print(' ');
}
// 3号 内循环 控制 从字母金字塔的中轴线起 左半边的字母打印,
// 3号内循环属于1号外循环!
for (k = 0; k < i; k++) {
// 进入循环之后用A的ASCII码 + k 的递增数 转成 字符,在条件满足的情况下,
// 3号内循环每循环一次,就转一次,随着 k 的递增,
// 每次转的字符一次在同一行排列好!
System.out.print((char) (65 + k));
}
// 4号 内循环 控制从字母金字塔的中轴线起 右半边的字母打印,
// 4号内循环属于1号外循环!
for (l = 1; l < i; l++) {
/*进来之后 用 A的ASCII码 + i 的递增数 - 4号内循环内部的 l 的递增数 再减 1,
转成相应的字符,随着 l 的递增,每次循环转换的字符都是不一样的!
(这里的-1就是细节,打个比方,比如 说1号外循环i的值已经是 5 了,
那么 3号内循环在这第5行打印的就是,ABCDE ,
那么到4号内循环在这第5行打印就应该要是 DCBA 才对,
到1号外循环是第5次循环的时候,
那么第5行 3号和4号内循环 的完整打印字母应该是 ABCDEDCBA )
故这个 算法一套,就是正确的, 1号外循环第5次循环的时候
4号内循环的执行流程就应该是:
第一次循环, 65 + 5(i) - 1(l) - 1 = 68 ,
68 刚好就是 D 这个字母的ASCII码,再转为字符就是D了!
第二次循环, 65 + 5(i) - 2(l) - 1 = 67 ,67 ASCII码转字符 ===> C
第三次循环, 65 + 5(i) - 3(l) - 1 = 66 ,66 ASCII码转字符 ===> B
第四次循环, 65 + 5(i) - 4(l) - 1 = 65 ,65 ASCII码转字符 ===> A
第五次4号内循环的条件不满足,结束循环! 故 第5行 3号内循环打印的是 ABCDE ,
4号循环打印的就是 DCBA , 在同一行就是 ABCDEDCBA
到 1 号外循环的 i 等于 6 的时候,即 开始了第6次循环,i等于7,i等于8,
i等于9,………… 都是一样的规律来转换字符。!*/
System.out.print((char) (65 + i - l - 1));
}
// 换行 1号外循环进行 下一次循环
System.out.print('\n');
}
}
test:
打倒序的字母金字塔就改一下代码的一些条件就好。不是很难。和倒三角一个思想。
嵌套循环的经典案例:百钱百鸡
方式1 较为麻烦:
// 公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱!
// 用100文钱买一百只鸡,其中公鸡,母鸡,小鸡都必须要有,公鸡,母鸡,小鸡要买多少只刚好凑足100文钱?。
// 设 公鸡为 x 只 ,母鸡为 y只, 小鸡为 z 只
// 故: 5x + 3y + z/3 = 100;
// 使用穷举法(效率低下)
int money = 100, cockPrice = 5, henPrice = 3, chickUnit = 3;
for (int x = 1; x <= money; x++) {
for (int y = 1; y <= money; y++) {
for (int z = 1; z <= money; z++) {
if ((x + y + z == money) && (cockPrice * x + henPrice * y + z / chickUnit == 100) && (z % chickUnit == 0)) {
System.out.println(x + "\t" + y + "\t" + z + "\t");
}
}
}
}
test:
方式2:方式1 优化后:
// 公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱!
// 用100文钱买一百只鸡,其中公鸡,母鸡,小鸡都必须要有,公鸡,母鸡,小鸡要买多少只刚好凑足100文钱?
// 假设法: 那么公鸡最多买 100 - 3 - 1 = 96 / 5 只,母鸡最多买 100 - 5 -1 = 94 / 3 只,最后求小鸡的只数,就可以
int money = 100, cockPrice = 5, henPrice = 3, chickUnit = 3;
for (int x = 1; x <= (money - henPrice - 1) / cockPrice; x++) {
for (int y = 1; y <= (money - cockPrice - 1) / henPrice; y++) {
int z = money - y - x;
if ((cockPrice * x + henPrice * y + z / chickUnit == money) && (z % chickUnit == 0)) {
System.out.println(x + "\t" + y + "\t" + z + "\t");
}
}
}
test:
遇到的面试题:求任意范围的质数。
方式1:
// 求100 - 200 之间的质数(面试题)
int i, j;
for (i = 100; i <= 200; i++) { // 控制多少范围
// 外循环循环一次,内循环循环一圈
for (j = 2; j <= i; j++) { // 从最小的质数开始到最大范围
// 如果外循环的数对内循环的每个j取余 为0!则结束
if (i % j == 0) {
// 如果是最后一次才取余为0的情况下,则j的值是和i的值相等的!直接跳出内循环
// 如果是其他合数匹配也会直接跳出内循环,但是j的值和i的值是不相等的!
// 细节:1: 如果条件判断是 j<=i - 1的情况,那么最后一次的才能取余为0的那个质数就不会再取余了,
// (比如,质数101,最后一个条件满足的是100,无法取余,所以无法满足break结束内循环,但是在条件不匹配后的
// j++最后操作的时候会把j的值加到101!所以匹配的时候打印质数就没有问题)
// 2:个人觉得 j <= i,可读性稍微高一些,(比如,质数101,最后一个条件也是101,所以质数会走取余为0的break直接跳出内循环,
// j++ 最后那个加到102的那个操作就被break打断了,直接执行后面的代码 if(j==i)的代码!)
break;
}
}
// 如果内循环的数等于外循环每次循环的数的情况下,则说明是个质数
if (j == i) {
System.out.print(i + "\t");
}
if (i % 25 == 0){
System.out.println();
}
}
test:
方式2:
// 求100 - 200 之间的质数(面试题)
for (int x = 100; x <= 200; x++) { // 控制多少范围
boolean flag = true; // 声明一个标记
for (int y = 2; y < x; y++) { // 最小的质数开始
if (x % y == 0) { // 如果能对y的递增值除尽则证明 (是合数)则标记取反并结束内循环
flag = !flag;
break;
}
}
if (flag) {
System.out.print(x + "\t");
}
if (x % 25 == 0){
System.out.println();
}
}
test:
方式3:
// 求300 - 500 之间的质数(面试题)
int i,n;
int pl = 0;
for (n=300;n<=500;n++){ // 控制多少范围
i=2; // 最小的质数
while (i<n){
if (n%i==0){ // 如果能被范围之内的数出尽,则是合数,跳出while循环
break;
}
++i; // 从最小的质数开始递增
}
if (i==n){ // 如果是质数则打印
++pl;
System.out.print(i +"\t");
if (pl % 10 == 0){ // 10个质数换一行
System.out.println();
}
}
}
test:
方式4:
// 2 ~ 100 之间的质数
for (int scope = 2;scope<=100;scope++){ // 控制多少范围
int count = 0;
for (int j = 2; j <= scope; j++) { // 最小的质数开始递增
if (scope%j==0){ // 如果能被范围的数出尽,则是合数
count++;
}
if (j==scope && count== 1){// 质数的递增值和外循环的范围相等并且只能被自身出尽1次
System.out.print(scope + "\t");
break;
}
if (count > 1){ // 如果是合数则跳出当前循环
break;
}
}
if (scope % 25 == 0){
System.out.println();
}
}
test:
方式5:
// 求100 ~ 200 之间的质数
for (int scope = 100; scope <= 200; scope++) { // 控制多少范围
for (int k = 2; k <= scope; k++) { // 最小的质数开始递增
if (scope % k == 0 && scope != k) { // 如果递增值能被范围的数出尽 且 范围的数等于 递增值 (就是合数!)就跳出循环
break;
}
if (scope % k == 0 && scope == k) { // 递增值能被范围的数除尽 且 范围的数等于它本身 (就是质数!)
System.out.print(scope + "\t");
}
}
if (scope % 25 == 0){ // 换行次数
System.out.println();
}
}
test:
方式6:
// 求 350 ~ 500 之间的质数
for (int scope = 350; scope <= 500; scope++) { // 控制多少范围
boolean flag = true; // 临时标记
// Math.sqrt:返回的正确舍入的正平方根 double值。(不是算术平方根!!!也不是平方根!)
for (int i = 2; i <= (int)Math.sqrt(scope); i++) { // 最小的质数开始递增
if (scope % i == 0) { // 如果递增的值能够被 范围的数整除 ,临时标记为 false 并结束内循环
flag = !flag;
break;
}
}
if (flag) { // 如果是质数
System.out.print(scope + "\t");
}
if (scope % 25 == 0){ // 换行次数
System.out.println();
}
}
test:
以上6种方式:个人认为 相对于 其他方式来比较 第一种方式 最精简,最直观,比较通俗易懂,最灵活。第二种方式次之。其他方式比较啰嗦。