JavaSE笔记(语法基础篇)
文章目录
- 语法基础篇
- 第1章 概述
- 1.1 计算机组成部分
- 1.2 人机交互方式
- 1.3 计算机语言
- 1.4 软件与软件开发
- 1.5 Java语言介绍
- 1.6 Java开发环境搭建
- 1.7 常见错误
- 第2章 基本数据与运算
- 2.1 关键字
- 2.2 标识符
- 2.3 注释
- 2.4 常量与进制
- 2.5 变量
- 2.6 数据类型
- 2.7 运算符
- 2.8 常见错误
- 第3章 流程控制语句
- 3.1 if条件语句
- 3.2 switch分支语句
- 3.3 for循环语句
- 3.4 while循环语句
- 3.5 break、continue跳转语句
- 3.6编程练习题
- 第4章 常用类
- 4.1 Math类
- 4.2 Scanner类
- 4.3 Random类
- 4.4 String类
- 4.5 Character类
- 第5章 函数
- 5.1 函数的概念
- 5.2 函数的运行原理
- 5.3 函数重载
- 5.4 函数的递归
- 5.5 编程练习题
- 第6章 数组
- 6.1 数组的概念及定义
- 6.2 常用数组操作
- 6.3 二维数组
- 6.4 编程练习题
- 6.4 LeetCode题
语法基础篇
第1章 概述
1.1 计算机组成部分
计算机的组成主要分为两大类:硬件,软件
硬件是可以看的到的一些物理部分,都是一些电子元器件
软件是看不得到的部分,它是一些列的指令,这些指令主要用于控制硬件来完成一些列特定的工作
常见的硬件:
- CPU:Center Processing Unit 中央处理器 主要指令控制和数值计算功能(日常工作任务)
- 内存:临时性存储数据的存储设备RAM,当内存不通电的时候,这数据也就消失了
- 显卡GPU:Graphic Processing Unit 图形图像处理单元 主要用于计算图形数据(图形图像任
务)- 存储设备:永久性存储设备ROM 任何数据都是以二进制的形式存储的
机械硬盘 固态硬盘 U盘 光盘 移动硬盘- 输入输出设备:
键盘 鼠标 显示器 扬声器 麦克风 打印机 扫描仪- 网络设备
输入:从互联网上下载数据
输出:从本地上传数据到互联网
1.2 人机交互方式
常用dos命令:
c: 进入C盘根目录
d: 进入D盘根目录
cd xxx 进入xxx目录
dir 查看当前目录下有什么文件和目录
cd / 进入到当前所在盘符的根目录
cd … 返回上一级目录
cls 清屏
exit 退出cmd窗口
1.3 计算机语言
- 静态编译语言:C C++ Java
静态:在定义变量的时候有明确的数据类型的区分
编译:将源代码全部进行编译 生成一个可执行的二进制文件 计算机去执行这个二进制文件来运行程序。
- 动态解释语言:Python JS
动态:在定义变量的时候没有明确的数据类型的区分
解释:将源代码从头到尾 读取一行 编译一行 运行一行(同声传译)
1.4 软件与软件开发
软件的定义
软件 是 指一系列按照特定顺序组织的 计算机数据与指令 的 集合
说明:再用编程去解决一个问题的时候,先去获取该问题所需要的数据,然后再根据数据讨
论计算的具体流程,最后再用编程语言去实现这个计算的流程
软件的分类
系统软件:也称之为是操作系统,主要是用来控制和管理底层硬件的一套指令,操作系统为用
户提供最基本的计算机功能。
应用软件:基于系统软件之上的,为用户带了特定领域服务的软件
软件开发
- 需求分析
2. 编码实现
3. 测试编码
4. 上线运维
5. 更新迭代
6. 下线
软件岗位
移动端软件研发 Anroid IOS - 物联网
Web前端研发 - 数据可视化工程师
PC端研发
后端研发
1.5 Java语言介绍
Java就属于Oralce的子产品。
Oracle公司主要业务:
数据库 Oralce数据库 随后也把民间产品MySQL也收购了
Linux服务器操作系统Solaris(redhat Ubuntu 深度 SUSE)
编程语言Java
Microso公司主要业务:
SQL Server
Windows/Windows Server
C++/C#
Java技术架构
JavaSE Java Standard Edition Java标准版:桌面型应用程序
JavaEE Java Enterprise Edition Java企业版:服务器应用程序
JavaME Java Micro Edition Java微型版:嵌入式应用程序
Java最大的特点——跨平台
跨平台的意思就是说,一个软件可以在多个平台上运行,而不用更改软件的内容。
是因为JVM的功劳:JVM(Java Virtual Machine)Java虚拟机。
Java源代码文件后缀名为xxx.java 所编译出来的二进制文件后缀名为xxx.class
JVM主要负责将java语言的字节码文件转换为本地操作系统指令的一个工具软件。
所以,最终是字节码文件在跨平台!
1.6 Java开发环境搭建
JRE与JDK
JRE(Java Runtime Environment)Java运行环境:如果我们的计算机仅仅想运行Java程序的话,装这个软件即可。JRE = JVM + 核心类库。
JDK(Java Development Kit)Java开发工具包:如果我们的计算机想要去开发一个Java程序的话,装这个软件即可。JDK = 开发工具 + JRE。
jdk安装目录介绍
bin目录:binary放的都是开发工具
javac.exe:java编译工具
用法: javac
java.exe:java运行工具
用法: java [-options] class [args…]
( 执行类)
或 java [-options] -jar jarfile [args…]
( 执行 jar 文件)
db目录:放的是支持数据库开发的一些工具包
include目录:放的是一些链接底层的一些C头文件代码
jre目录:jdk自带的运行环境
lib目录:library 存放的是一些第三方Java库
javafx-src.zip:javafx图形化界面开发的源码包
src.zip:Java本身的源代码包
1.7 常见错误
语法错误
单词评写
遗漏分号
使用中文符号的问题
大括号不匹配
遗漏关键字单词
运行错误
逻辑错误
遗漏括号
遗漏分号
遗漏引号
非法使用中文符号
单词拼写错误
第2章 基本数据与运算
2.1 关键字
关键字是指被高级编程语言赋予特殊含义的一些单词,关键字一般都是由小写字母组成。
用于定义数据类型的关键字:byte short int long float double char boolean void class interface
用于定义数据类型值的关键字:true false null
用于定义流程控制语句的关键字:if else switch case default while do for break continue return
用于定义访问权限修饰符的关键字:public protected private
用于定义继承关系的关键字:extends implements
用于定义实例对象的关键字:new this super instanceof
用于定义函数类型的关键字:static final abstract synchronized
用于处理异常的关键字:try catch finally throw throws
用于包的关键字:package import
其他的一些修饰关键字:native assert volatile transient
2.2 标识符
标识符指的是我们在程序中对变量、函数、类、接口、常量所定义的名称,也就是说这些名称是我们自定义的。
标识符必须满足以下组成规则:
标识符可以由数字、字母、下划线 _ 、美元符 $ 组成
标识符不能以数字开头,当然下划线和美元符其实是可以开头的,但不推荐
标识符不能是关键字
标识符也不能是Java内置类的名称
标识符可以为任意长度,但必须是一个连续的词
标识符严格区分大小写
标识符命名的规范:
大驼峰式:主要针对类名,接口名。所有单词的首字母大写
小驼峰是:主要针对于变量名,函数名。除了第一个单词之外,其他单词首字母大写
常量规范:所有单词字母大写,单词与单词之间用下划线分隔
包名规范:所有单词字母小写,单词与单词之间用句号 . 分隔
myAge 变量名
getMax() 函数名
MyMoney 类名接口名
MAX_VALUE 常量名
com.oupeng.java 包名
2.3 注释
注释是用于注解和说明程序的一些程序中的内置文本信息的,但这些内置文本不属于代码的范畴。
所以在对含有注释的源代码进行编译时,所生成的字节码中不含有注释。注释给人看的!
注释主要有三种:
单行注释 //注释内容直到换行为止
多行注释 /* 注释内容内部可以进行换行 /
文档注释 /* 注释内容内部可以进行换行 */ :文档注释可以被编译器识别,并生成相应的程序说明书。对某一个类进行文档生成时,该类必须是public型
注意:
- 注释除了有解释说明程序的功能之外,还可以用来调试程序。
- 多行注释中,不能再出现多行注释
- 在写代码时,一定要先写注释,并且,注释最好详细一些
2.4 常量与进制
常量就是指在程序中直接出现的一些数据,也叫字面量
常量都有哪些:
整数常量
小数常量
字符常量:由一个字母、数字、符号被单引号( ‘’ )标识的数据
字符串常量:由若干个字母、数字、符号被双引号( “” )标识的数据
布尔类型常量
null常量
进制
一个二进制位称之为是一个比特 bit;八个比特称之为一个字节 byte;字节是计算机当中的最小计数单元。
负数的二进制:
-29的二进制 将正数部分的二进制先取反 再加1 即为负数的二进制
00011101 =>取反 11100010 =>加1 11100011
2.5 变量
- 变量的本质就是在内存中程序所处的进程中的一个临时存储区域
- 该区域的存储值有限制的
- 该区域值的变化必须是同类型的或向下兼容的
- 该区域有其自身的物理内存地址-指针
该区域中 存储值的限制 和 数据的变化类型 由数据类型 来决定
该区域中 其空间的分配 和 空间的物理内存地址 由计算机底层来决定
回顾一下指针:
#include<stdio.h>
void main() {int a = 3; //创建一个普通的整型变量存3这个常量
int* b; //创建一个一重指针变量存的是a变量的地址
b = &a;
int** c; //创建一个二重指针变量存的是b变量的地址
c = &b;
printf("a的地址:%d\n",&a); //打印a的地址 0x123
printf("a的内容:%d\n",a); //打印a空间的内容 3
printf("b的地址:%d\n",&b); //0x456
printf("b的内容:%d\n",b); //0x123
printf("拿着b的内容去找变量a:%d\n",*b); //3
printf("c的地址:%d\n",&c); //0x789
printf("拿着c的内容去找变量b:%d\n",*c); //0x123
printf("拿着c的内容去找变量b,拿着b的内容去找变量a:%d\n",**c); //3
//printf("%d\n",*a);
printf("%d\n",*&*c); //0x123
printf("%d\n",&*&**&c); //0x456
}
结果如下:
a的地址:6422300
a的内容:3
b的地址:6422296
b的内容:6422300
拿着b的内容去找变量a:3
c的地址:6422292
拿着c的内容去找变量b:6422300
拿着c的内容去找变量b,拿着b的内容去找变量a:3
6422300
6422296
2.6 数据类型
- 基本数据类型:在变量的空间中存储数据
整型
byte 1字节 2^8 256 -128~127 -2^7 ~ 2^7 - 1
short 2字节 2^16 65536 -32768~32767 -2^15 ~ 2^15 - 1
int 4字节
long 8字节
浮点型
float 4字节
double 8字节
字符型
char 2字节
布尔型
boolean 不确定
注意:
在常量中,整型常量默认int类型,小数常量默认是double类型
布尔类型,如果是单一变量的话,在JVM中true被认为是1 false被认为是0 所以是4字节存
如果是布尔类型数组的话,在JVM中true和false被认为是byte类型 1字节
- 引用数据类型:数据是在堆内存中存储,变量仅仅存放的是数据在堆内存中的地址
字符串
数组
对象
注意:在Java中,但凡存储在堆内存中的数据,统称为对象
2.7 运算符
算术运算符
赋值运算符
比较运算符
运算的结果为布尔类型
逻辑运算符
& 单与
| 单或
^ 异或
!非
&& 双与
|| 双或
位运算符
& 位与
| 位或
^ 位异或
/>> 右移
<< 左移
三目运算符
数据类型变量名 = 布尔表达式?值1:值2;
2.8 常见错误
- 未声明变量,未初始化变量而使用变量
整型溢出问题 - 取整错误
一个是小数的问题,小数主要去的是近似值 想要得到一个0.5这个值的话 有可能会得到0.4999999
一个是整数的问题,1/3 = 0.3333 * 3 = 0.99999 数学上1
- 超出预期的除法问题
左右两边是整数,结果为整数,如果出现小数则结果为小数
- 额外冗余的输入对象
第3章 流程控制语句
3.1 if条件语句
单分支if语句
...CodeAif (布尔表达式) {语句组;}...CodeB
双分支if-else语句
...CodeAif (布尔表达式) {语句组A;} else {语句组B;}....CodeB
多分支if-else-if语句
...CodeAif (布尔表达式1) {语句组A;} else if (布尔表达式2) {语句组B;} else if (布尔表达式3) {语句组C;} else {语句组D;}...CodeB
3.2 switch分支语句
与if分支语句一样,都是对条件的判断。switch一般用在条件较多的情况下,但是有一个重要的细节
及时,if语言可以对区间值或固定值进行判断,switch只能对固定值进行判断。
switch (变量) {case 值1: //if (变量==值1) {语句组A;}语句组A;break;case 值2:语句组B;break;...case 值n: //if (变量==值n) {语句组N;}语句组N;default: // else {语句组N+1;}语句组N+1;break;}
switch的一些使用细节
- switch所传入的变量,char,byte,short,int,String或者枚举类型
- 值1,值2,一直到值n,这几个值必须是同一个数据类型的
- 当变量匹配的相关case的值的时候,执行case中的语句,直到遇到break结束;如果该case语句
中没有break,则继续向下执行,直到遇到另外一个break结束
3.3 for循环语句
循环主要解决具有规律性的且具有重复性的代码问题,避免程序冗余
//将一个数字所有位数拆开相加
//number = 123
number % 10 = 3
number /= 10 12
number % 10 = 2
number /= 10 1
number % 10 = 1
number /=10 0
循环四要素
1循环的初始化:循环的第1次执行从哪里开始
2循环的继续条件:循环从当前轮是否向后执行下一轮
3循环体:需要被循环执行的部分
4循环的步长、周期:当前循环到下一轮循环之间的变化
我们常见的循环问题可以分为两大类:
已知循环次数的 一般用for语句做
未知循环次数但是已知循环结束条件 一般用while语句做
for (1循环的初始化;2.循环的继续条件;4.循环的步长) {
3.循环体
}
1-2-3-4-2-3-4-2-3-4-2不满足则结束循环
for循环演示
见练习Sample
3.4 while循环语句
while循环主要用于解决循环次数未知,但循环结束条件已知的情况。
while其实和for循环是可以相互转换的,是因为都逃不开循环四要素
for (int i = 1; i <= 5; i++) {System.out.println(i);
}
可以转换为while循环
int i = 1;
while (i <= 5) {System.out.println(i);i++;
}
while的语法格式
1.循环的初始化
while (2.循环继续条件) {3.循环体4.循环的步长、周期
}
3.5 break、continue跳转语句
break在循环语句中叫做终止语句,终止的是break最近的一层循环
continue在循环语句中叫做跳过语句,跳过本次循环开启下一轮循环
import java.util.Scanner;
public class Sample {public static void main(String[] args) {for (int i = 1; i <= 5; i++) {if (i == 3) {break;} else {System.out.println(i);}}
//结果 1 2
for (int i = 1; i <= 5; i++) {if (i == 3) {continue;} else {System.out.println(i);}}
//结果 1 2 4 5}
}
3.6编程练习题
- Dome18
import java.util.Scanner;
public class Demo18{public static void main(String[] args){Scanner input = new Scanner(System.in);//1.提示用户输入年份System.out.print("");int x =input.nextInt();//2.判断if((x % 4 == 0 && x % 100 !=0) || (x % 400 == 0)){System.out.println(x + "是闰年");}else{System.out.println(x + "不是闰年");}}
}
- Demo20
import java.util.Scanner;
public class Demo20{public static void main(String[] args){Scanner input = new Scanner(System.in);//1.提示用户输入a,b,cSystem.out.print("Enter a,b,c: ");double a = input.nextDouble();double b = input.nextDouble();double c = input.nextDouble();//2.计算deltedouble delte = b * b - 4 * a * c;//3.判断求解if(delte > 0){double x1 = ((- b) + Math.sqrt(delte)) / (2 * a);double x2 = ((- b) - Math.sqrt(delte)) / (2 * a);System.out.println("The equation has two roots : x1 = " + x1 +"and x2 = " + x2);}else if(delte == 0){double x = ((- b) + Math.sqrt(delte)) / (2 * a);System.out.println("The equation has one roots : x = " + x );}else{System.out.println("The equation has no real roots");}}
}
- Demo23
import java.util.Scanner;
public class Demo23{public static void main(String[] args){Scanner input = new Scanner(System.in);//1.提示用户输入System.out.print("Enter a number: ");int number = input.nextInt();//保存一份numberint num = number;//2.颠倒数字123456/*123456 % 10 = 6 sum * 10 + 6 = 612345 % 10 = 5 sum * 10 + 5 = 651234 % 10 = 4 sum * 10 + 4 = 654*/int sum = 0;while(number != 0){sum = sum * 10 + number %10;number /= 10;}if(sum == num){System.out.println(num + " is a palindrome");}else{System.out.println(num + " is not a palindrome");}}
}
Demo24
import java.util.Scanner;
import java.util.Random;
public class Demo24{/*剪刀(0),石头(1),布(2)usr com0 1 21 0 22 0 1usr == com 平局usr - com -2 1 用户赢*/public static void main(String[] args) {int usrcount = 0;int comcount = 0;while(comcount < 2 && usrcount < 2){Scanner input = new Scanner(System.in);Random random = new Random();int com = random.nextInt(3);//[0,3)整数System.out.print("剪刀(0),石头(1),布(2):");int usr = input.nextInt();if (usr == 0) {System.out.print("用户:剪刀 ,");} else if (usr == 1) {System.out.print("用户:石头 ,");} else {System.out.print("用户:布 ,");}if (com == 0) {System.out.print("电脑:剪刀 ,");} else if (com == 1) {System.out.print("电脑:石头 ,");} else {System.out.print("电脑:布 ,");}if (usr == com) {System.out.println("平局");} else if (usr - com == -2 || usr - com == 1) {System.out.println("用户赢");usrcount++;} else {System.out.println("电脑赢");comcount++;}if(comcount == 2 || usrcount == 2){break;}}if(comcount == 2){System.out.println("电脑胜利!");}else{System.out.println("用户胜利!");}}
}
Demo26
import java.util.Scanner;
public class Demo26{public static void main(String[] args){Scanner input = new Scanner(System.in);//1.提示用户输入一个点的坐标System.out.print("Enter a point with two coordinates:");double x = input.nextDouble();double y = input.nextDouble();//2.计算和原点的距离double d =(double)(Math.sqrt(Math.pow(x , 2) + Math.pow(y , 2)));//3.判断if(d > 10){System.out.println("Point (" + x + "," + y + ") is not in the circle" );}else{System.out.println("Point (" + x + "," + y + ") is in the circle" );}}
}
Demo28
import java.util.Scanner;
public class Demo28{public static void main(String[] args){Scanner input = new Scanner(System.in);//1.提示用户输入一个点的坐标System.out.print("Enter a point's x- and y-coordinates:");double x = input.nextDouble();double y = input.nextDouble();//2.计算和(200,0)形成的比例double d =(double)(y / (200 - x));//3.判断if(x >= 0 && y >= 0 && d <= 0.5){System.out.println("The point is in the triangle" );}else{System.out.println("The point is not in the triangle" );}}
}
Demo30
import java.util.Scanner;
public class Demo30{public static void main(String[] args){Scanner input = new Scanner(System.in);//1.提示用户输入两个圆的圆心坐标 半径System.out.print("输入圆1的圆心坐标 半径:");double x1 = input.nextDouble();double y1 = input.nextDouble();double r1 = input.nextDouble();System.out.print("输入圆2的圆心坐标 半径:");double x2 = input.nextDouble();double y2 = input.nextDouble();double r2 = input.nextDouble();//2.计算圆心距distancedouble distance = (double)(Math.sqrt(Math.pow(x1 - x2, 2) +Math.pow(y1 - y2,2)));//3.判断distance<=|r1 - r2| 圆内//判断|r1 - r2|<distance< r1 + r2 相交if(distance <= r1 - r2){System.out.println("圆2在圆1内");}else if(distance < r1 + r2){System.out.println("圆2和圆1相交");}else{System.out.println("圆2在圆1外");}}
}
Demo32
import java.util.*;
public class Demo32{public static void main(String[] args){Scanner input = new Scanner(System.in);//随机获取一个0~100的随机整数Random random = new Random();int sum = (int)(Math.random() * 101);while(true){//提示用户输入一个整数System.out.print("输入一个0~100 的整数:");int number = input.nextInt();if(number < sum){System.out.println("偏小");}else if(number > sum){System.out.println("偏大");}else{System.out.println("你可真厉害!!!");break;}}}
}
Demo33
import java.util.Scanner;
public class Demo33{public static void main(String[] args){/*24 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16-----2416 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16-----16*///输入两个数字并判断大小Scanner input = new Scanner(System.in);System.out.print("输入两个数字:");int num1 = input.nextInt();int num2 = input.nextInt();int min = num1 < num2 ? num1 : num2;//2.从min开始向1循环递减,如果找到一个数字i能够把num1和num2同时整除int g = 1;for (int i = min; i > 0;i-- ){if(num1 % i == 0 && num2 % i == 0){g = i;break;}}System.out.println("最大公约数为:" + g);}
}
Demo35
import java.util.Scanner;
public class Demo35{public static void main(String[] args){Scanner input = new Scanner(System.in);/*对于字符串中的每一个字符我们都可以使用角标来访问黄山落叶松叶落山黄01 2 3 4 5 6 7 8通过字符串对象的charAt(int index)方法来获取指定index处对应的字符*/System.out.print("请输入一段文字:");//输入的一行文字String str = input.nextLine();int l = 0;int r =str.length() - 1;//默认它是回文boolean flag = true;while(l < r){if(str.charAt(l) == str.charAt(r)){l++;r--;}else{flag = false;break;}}if(flag){System.out.println(str + "这句话是回文");}else{System.out.println(str + "这句话不是回文");}}
}
Demo36
public class Demo36{public static void main(String[] args){//素数的个数int count = 0;int num = 2;while(count < 50){//默认是素数boolean flag = true;for(int i = 2;i <= num / 2; i++){if(num % i == 0){flag = false;break;}}if(flag){System.out.print(num + "\t");count++;if(count % 10 == 0){System.out.println();}}num++;}}
}
Demo41
import java.util.Scanner;
public class Demo41{public static void main(String[] args){Scanner input = new Scanner(System.in);//1.提示用户输入一个1~15的数字System.out.print("Enter the number of lines:");int number = input.nextInt();/*12 1 23 2 1 2 3 4 3 2 1 2 3 45 4 3 2 1 2 3 4 5*/for(int i = 1;i <= number;i++){for(int k = 1;k <= number - i;k++){System.out.print(" ");}for(int j = 1 - i;j <= i - 1;j++){System.out.print(Math.abs(j) + 1 + " ");}System.out.println();}}
}
Demo44
public class Demo44{public static void main(String[] args){//素数的个数int count = 0;for(int num = 2;num <= 1000;num++){//默认是素数boolean flag = true;for(int i = 2;i <= num / 2; i++){if(num % i == 0){flag = false;break;}}if(flag){System.out.print(num + "\t");count++;if(count % 8 == 0){System.out.println();}}}}
}
Demo45
public class Demo45{public static void main(String[] args){double sum= 0;for(double i = 1;i < 98;i += 2){sum += (double) (i /(i + 2));}System.out.println(sum);}
}
Demo47
public class Demo47{public static void main(String[] args){double e = 1;int item = 1;int max = 10;for(int i= 1;i <= max;i++){item = item * i ;//n!e += 1.0 / item; }System.out.println(e);}
}
Demo49
import java.util.Scanner;
import java.util.Random;
public class Demo24{/*剪刀(0),石头(1),布(2)usr com0 1 21 0 22 0 1usr == com 平局usr - com -2 1 用户赢*/public static void main(String[] args) {int usrcount = 0;int comcount = 0;while(comcount < 2 && usrcount < 2){Scanner input = new Scanner(System.in);Random random = new Random();int com = random.nextInt(3);//[0,3)整数System.out.print("剪刀(0),石头(1),布(2):");int usr = input.nextInt();if (usr == 0) {System.out.print("用户:剪刀 ,");} else if (usr == 1) {System.out.print("用户:石头 ,");} else {System.out.print("用户:布 ,");}if (com == 0) {System.out.print("电脑:剪刀 ,");} else if (com == 1) {System.out.print("电脑:石头 ,");} else {System.out.print("电脑:布 ,");}if (usr == com) {System.out.println("平局");} else if (usr - com == -2 || usr - com == 1) {System.out.println("用户赢");usrcount++;} else {System.out.println("电脑赢");comcount++;}if(comcount == 2 || usrcount == 2){break;}}if(comcount == 2){System.out.println("电脑胜利!");}else{System.out.println("用户胜利!");}}
}
Demo50
import java.util.Scanner;
public class Demo50{public static void main(String[] args){//1.输入一个数字System.out.print("输入一个十进制整数:");Scanner input = new Scanner(System.in);int number = input.nextInt();/*13 / 2 = 6 ~1*/String str = "";while(number != 0){str = number % 2 +str;number /= 2;}System.out.println("二进制为:" +str);}
}
课后作业
Demo17
import java.util.Scanner;
public class Demo17{public static void main(String[] args){Scanner input = new Scanner(System.in);//1.提示用户输入体重和身高System.out.print("请输入体重和身高:");double m = input.nextDouble();double h = input.nextDouble();//2.计算BMIdouble BMI = m / h / h;//3.判断指标if(BMI < 18.5){System.out.println("偏瘦");}else if(BMI <25.0){System.out.println("正常");}else if(BMI <25.0){System.out.println("超重");}else {System.out.println("过胖");}}
}
Demo19
思路: 后台随机产生一个两位数,获取产生两位数的十位和个位,将其与用户输入的数字做比较,得出奖金。
import java.util.Scanner;
import java.util.Random;
public class Demo19{public static void main(String[] args){Scanner input = new Scanner(System.in); //2.随机生成一个二位数comint com = (int)(Math.random() * 90 + 10);System.out.println(com);//1.提示用户输入一个两位数sumSystem.out.print("请输入一个两位数:");int sum = input.nextInt();//3.进行拆分 用户sum 十位a,个位b 系统com 十位m,个位nint a = sum / 10;int b = sum % 10;int m = com / 10;int n = com % 10;//4.判断if(sum == com){System.out.println("恭喜获得10000美金");}else if((a == n) && (b == m)){System.out.println("恭喜获得3000美金");}else if((a == m) || (a == n) || (b ==m) || (b==n)){System.out.println("恭喜获得1000美金");}else{System.out.println("您没有中奖");}}
}
Demo21
思路: 根据用户输入的数据,判断ad-bc是否等于0,为0就结束程序,输出提示信息,否则就将数据带入公式进行计算
import java.util.Scanner;
public class Demo21{public static void main(String[] args){Scanner input = new Scanner(System.in);//1.提示用户输入a,b,c,d,e,fSystem.out.print("Enter a,b,c,d,e,f: ");double a = input.nextDouble();double b = input.nextDouble();double c = input.nextDouble();double d = input.nextDouble();double e = input.nextDouble();double f = input.nextDouble();//判断double x = (e * d - b * f) / (a * d - b * c);double y = (a * f - e * c) / (a * d - b * c);if(a * d - b * c == 0){System.out.println("方程式无解");}else{System.out.println("x = " + x + " y = " +y);}}
}
Demo22
思路: 根据用户输入的星期和天数做一个相加,并对7取余数,根据余数判断将来天数的星期。
import java.util.*;
public class Demo22{public static void main(String[] args){Scanner input = new Scanner(System.in);System.out.print("Enter today's day:");int today = input.nextInt();System.out.print("Enter the nnumber of days elapsed since today:");int nextday = input.nextInt();//相除取余int i = (nextday + today) % 7;switch(i){case 0:System.out.println("周日");break;case 1:System.out.println("周一");break;case 2:System.out.println("周二");break;case 3:System.out.println("周三");break;case 4:System.out.println("周四");break;case 5:System.out.println("周五");break;case 6:System.out.println("周六");break;}}
}
Demo25
思路: 思路基本与上一题相似,将用户输入的数据,带入公式计算即可。
import java.util.*;
public class Demo25{public static void main(String[] args){Scanner input = new Scanner(System.in);System.out.print("Enter year:");int year = input.nextInt();System.out.print("Enter month:");int m = input.nextInt();System.out.print("Enter the day of the month(1~31):");int q = input.nextInt();//计算if(m <= 2){m = m + 12;year = year -1;}int k = year % 100;int j = Math.abs(year / 100);int h = (int)((q + (26 * (m + 1) / 10) + 1.25 * k + 5.25 * j) % 7);switch(h){case 1:System.out.println("周日");break;case 2:System.out.println("周一");break;case 3:System.out.println("周二");break;case 4:System.out.println("周三");break;case 5:System.out.println("周四");break;case 6:System.out.println("周五");break;case 0:System.out.println("周六");break;}}
}
Demo27
思路: 获取用户输入点的坐标,判断该坐标与矩形宽高的关系,得出该点是否在矩形内。
import java.util.*;
public class Demo27{public static void main(String[] args){Scanner input = new Scanner(System.in);//1.提示用户输入一个点的坐标System.out.print("Enter a point two coordinates:");double x = input.nextDouble();double y = input.nextDouble();//2.取绝对值x = Math.abs(x);y = Math.abs(y);//3.判断,如果|x|<=10/2 |y|<=5/2 则点在矩形内if(x <= 5 && y <= 2.5){System.out.println("Point (" + x + "," + y + ") is in the rectangle");}else{System.out.println("Point (" + x + "," + y + ") is not in the rectangle");}}
}
Demo29
import java.util.*;
public class Demo29{public static void main(String[] args){Scanner input = new Scanner(System.in);//1.提示用户输入两个矩形的坐标,宽度和长度System.out.print("Enter R1 (x,y) width and height:");double x1 = input.nextDouble();double y1 = input.nextDouble();double w1 = input.nextDouble();double h1 = input.nextDouble();System.out.print("Enter R1 (x,y) width and height:");double x2 = input.nextDouble();double y2 = input.nextDouble();double w2 = input.nextDouble();double h2 = input.nextDouble();//2.判断if(x2 - x1 <= (w1 - w2) / 2 &&x1 - x2 <= (w1 - w2) / 2 &&y2 - y1 <= (h1 - h2) / 2 &&y1 - y2 <= (h1 - h2) / 2 ){System.out.println("R2 is inside R1");}else if(x2 - x1 >= (w1 + w2) / 2 ||x1 - x2 >= (w1 + w2) / 2 ||y2 - y1 >= (h1 + h2) / 2 ||y1 - y2 >= (h1 + h2) / 2 ){System.out.println("R2 does not overlap R1");}else {System.out.println("R2 overlaps R1");}}
}
Demo31
import java.util.*;
public class Demo31{public static void main(String[] args){Scanner input = new Scanner(System.in);System.out.print("Enter an integer:");int number = input.nextInt();if(number % 5 == 0 && number % 6 == 0){System.out.println("Is " + number + " divisible by 5 and 6? true");}else if(number % 5 == 0 || number % 6 == 0){System.out.println("Is " + number + " divisible by 5 and 6? false");System.out.println("Is " + number + " divisible by 5 or 6? true");}else if(number % 5 != 0 && number % 6 != 0){System.out.println("Is " + number + " divisible by 5 or 6,but not both? false");}else{System.out.println("Is " + number + " divisible by 5 or 6,but not both? true");}}
}
Demo34
思路: 对输入十进制数循环对16取余数,如果得余数小于10就直接将该数转为字符数字,否则就变为对应的A,B,C,D,E,F存入一个字符数组,循环完后逆序输出该字符数组即可。
import java.util.Scanner;
public class Demo34{public static void main(String[] args){//1.输入一个数字System.out.print("输入一个十进制整数:");Scanner input = new Scanner(System.in);int number = input.nextInt();/*13 / 2 = 6 ~1*/String str = "";while(number != 0){int strValue = number % 16;char strDigit = (strValue <= 9 && strValue >= 0)?(char) (strValue + '0'):(char)(strValue - 10 +'A');str = strDigit +str;number /= 16;}System.out.println("十六进制为:" +str);}
}
Demo48
思路: 从1开始循环到10000,内循环每次从1开始到该数的半值,判断当前内循环的数是否可以被外循环的数整除,可以的话就加入总和,内循环循环完后就判断总和和当前的值是否相等,相等就输出,否则就继续循环。
public class Demo48{public static void main(String[] args){for(int num = 1;num <= 10000;num++){int sum = 0;for(int i = 1;i <= num / 2; i++){if(num % i == 0){sum += i;} }if(num == sum){System.out.println(num + "\t");}}}
}
第4章 常用类
4.1 Math类
Math类是用于数学计算的一个工具类
对于工具类而言,里面的大部分成员都是静态的static
通过 Math 类可以在主函数中直接调用
自带常量
常量 | 含义 |
---|---|
static double E | 自然对数 |
static double PI | 圆周率 |
取整方法
方法 | 备注 |
---|---|
static double ceil(double a) | 向上取整 |
static double floor(double a) | 向下取整 |
static long round(double a) | 四舍五入 |
三角函数
方法 | 备注 |
---|---|
static double sin(double a) | 正弦函数 参数是弧度值 |
static double cos(double a) | 余弦函数 |
static double tan(double a) | 正切函数 |
static double toDegrees(double a) | 将弧度转角度 |
static double toRadians(double angles) | 将角度转弧度 |
static double asin(double a) | 反正弦函数 |
static double acos(double a) | 反余弦函数 |
static double atan(double a) | 反正切函数 |
指数函数
方法 | 备注 |
---|---|
static double pow(double a, double b) | 求a的b次幂 |
static double sqrt(double a) | 求a的平方根 |
static double cbrt(double a) | 求a的立方根 |
其他方法
方法 | 备注 |
---|---|
static double abs(double a) | 求a的绝对值 |
static double hypot(double deltX, double deltY) | 返回 两点间距离 |
static double max(a,b) | 返回a和b之间的最大值 |
static double min(a,b) | 返回a和b之间的最小值 |
static double random() | 返回[0,1)之间的随机小数 |
public class Sample {public static void main(String[] args) {System.out.println(Math.E);
System.out.println(Math.PI);
System.out.println(Math.ceil(3.1));
System.out.println(Math.ceil(3.9));
System.out.println(Math.ceil(-3.1));
System.out.println(Math.ceil(-3.9));
System.out.println(Math.floor(3.1));
System.out.println(Math.floor(3.9));
System.out.println(Math.floor(-3.1));
System.out.println(Math.floor(-3.9));
4.2 Scanner类
主要用于负责数据输入的类,底层是和IO流相关。
方法 | 备注 |
---|---|
String next() | 获取直到遇到空格为止的一个字符串 |
String nextLine() | 获取直到遇到回车为止的一个字符串 |
int nextInt() | 获取下一个整数 byte short long |
double nextDouble() | 获取下一个小数 |
boolean nextBoolean() | 获取下一个布尔类型 |
4.3 Random类
主要用于产生随机数
方法 | 备注 |
---|---|
boolean nextBoolean() | 随机产生布尔类型值 |
double nextDouble() | 随机生成0.0~1.0之间的小数 |
double nextInt() | 随机生成一个整数0~232的整数 |
double nextInt(n) | 随机生成一个整数[0,n)的整数 |
import java.util.Scanner;
public class Sample {public static void main(String[] args) {Scanner input = new Scanner(System.in);
System.out.print("输入一句话:");
String line = input.nextLine();
System.out.println(line);
System.out.print("输入三个单词:");
String word1 = input.next();
String word2 = input.next();
String word3 = input.next();
System.out.println(word1);
System.out.println(word2);
System.out.println(word3);
}
}
4.4 String类
String是一个类,它描述的是字符串。在Java代码当中,所有字符串常量(字符串字面量)都是String类的一个实例对象。
字符串一旦创建,则不可修改! 不可修改其长度,不可修改其内容 。所以将来对字符串内容的改变,不能在原地改,只能重新创建一个字符串。
public class Sample {public static void main(String[] args) {String s1 = "abc";String s2 = "ab" + "dc";//上述代码一共有几个字符串?//四个"abc" "ab" "dc" "abdc"}
}
获取相关
方法 | 备注 |
---|---|
char charAt(int index) | 获取指定角标index处的字符 |
int indexOf(int ch) | 获取指定字符(编码)在字符串中第一次(从左到右)出现的地方返回的是角标。如果是-1 表示不存在 |
int lastIndexOf(int ch) | 获取指定字符(编码)在字符串中第一次(从右到做)出现的地方返回的是角标 |
int indexOf(String str) | 获取指定字符串在本字符串中第一次(从左到右)出现的地方返回的是角标 |
int lastIndexOf(String str) | 获取指定字符串在本字符串中第一次(从右到左)出现的地方返回的是角标 |
int length() | 获取字符串的长度(字符的个数) |
String[] split(String regex) | 将字符串按照regex的定义进行切割(regex指的是正则表达式) |
String substring(int beginIndex) | 截取一段子字符串,从beginIndex开始到结尾 |
String substring(int beginIndex, int endIndex) | 截取一段子字符串,从beginIndex开始到endIndex(不包含) |
判断相关
方法 | 备注 |
---|---|
int compareTo(String anotherString) | 按照字典顺序比较两个字符串的大小 |
boolean contains(String another) | 判断当前字符串中是否包含指定字符串another |
boolean equals(String another) | 比较当前字符串与指定字符串的内容是否相同 |
boolean isEmpty() | 判断当前字符串是否为空,length() == 0 |
boolean startsWith(String prefix) | 判断该字符串是否以prefix开头 |
boolean endsWith(String suix) | 判断该字符串是否已suix结尾 |
Random random = new Random();
for (int i = 1; i <= 10; i++) {System.out.print(random.nextBoolean() + " ");
}
System.out.println();
for (int i = 1; i <= 10; i++) {System.out.print(random.nextInt(2) + " ");
}
System.out.println();
for (int i = 1; i <= 10; i++) {System.out.print(random.nextInt() + " ");
}
System.out.println();
}
}
修改相关
方法 | 备注 |
---|---|
String toLowerCase() | 将字符串中所有的英文字母全部变为小写 |
String toUpperCase() | 将字符串中所有的英文字母全部变为大写 |
String trim() | 将字符串中两端的多余空格进行删除 |
String replace(char oldCh,char newCh) | 将字符串中oldCh字符替换成newCh字符 |
- 如何删除字符串中左右两端出现的空格,不用trim
public class Sample {public static void main(String[] args) {String str = " 123123123 12123 ";//去空格后"123123123 12123"//定义两端的下标int l = 0;int r = str.length() - 1;while (str.charAt(l) == ' ') {l++;}while (str.charAt(r) == ' ') {r--;}//用下标截取字符串System.out.println("[" + str.substring(l,r + 1) + "]");}
}
- 在字符串"abcbcbcbcbcbc"中统计"bcb"出现的次数?
贪心/非贪心算法
public class Sample {public static void main(String[] args) {String s1 = "abcbcbcbcbcbc";String s2 = "bcb";//贪心算法 5个int count = 0;for (int i = 0; i < s1.length() - s2.length() + 1; i++) {if (s1.charAt(i) == s2.charAt(0)) {if (s2.equals(s1.substring(i,i + s2.length()))) {count++;}}}System.out.println(count);//非贪心算法 3个/*String temp = s1;int count = 0;while (true) {int index = temp.indexOf(s2);if (index == -1) {break;}count++;temp = temp.substring(index + s2.length());}System.out.println(count);*/}
}
- 查找两个字符串中最长的公共子串?
//查找两个字符串中最长的公共子串
public class Sample01{public static void main(String[] args){String s1 = "老帅哥,来份酸汤肥牛豆花吗";String s2 = "酸汤肥牛老帅哥,今天吃啥";for(int len = s2.length();len > 0;len--){for(int l = 0,r = len -1;r < s2.length();l++,r++){String temp = s2.substring(l,r+1);if(s1.contains(temp)){System.out.println(temp);return;}}}}
}
4.5 Character类
Character它是char基本数据类型的 包装类 ,有这么几个静态方法
方法 | 备注 |
---|---|
static boolean isDigit(char ch) | 判断字符是否是数字 |
static boolean isLetter(char ch) | 判断字符是否是字母 |
static boolean isLetterOrDigit(char ch) | 判断字符是否是数字或字母 |
static boolean isLowerCase(char ch) | 判断是否是小写字母 |
static boolean isUpperCase(char ch) | 判断是否是大写字母 |
static boolean isSpaceChar(char ch) | 判断是否空白字母(空格 制表符 回车) |
- 将十六进制数字转为十进制
import java.util.Scanner;
public class Sample{public static void main(String[] args){System.out.print("请输入一个十六进制数字: ");Scanner input = new Scanner(System.in);String hex = input.nextLine().toUpperCase();//输入长度为0则无输入if(hex.length() == 0){System.out.println("无输入!");return;}//循环判断输入的字符是否为非法字符//排除非数字,字母和非A-F字符for(int i=0; i<hex.length(); i++) {char ch = hex.charAt(i);if(Character.isDigit(ch) || Character.isLetter(ch)) {if(Character.isLetter(ch) && (ch < 'A' || ch > 'F')) {System.out.println("非法字符:"+ch);return;}}else {System.out.println("非法字符:"+ch);return;}}//循环计数16进制的十进制数int sum=0;for(int i=hex.length() - 1; i>=0; i--) {char ch = hex.charAt(i);//如果为数字则就字符-48得当前数字if(Character.isDigit(ch)) {sum += (int) Math.pow(16, hex.length()-i-1) * (ch - 48);}else {//字符就-65+10获得字符对应的十进制数sum += (int) Math.pow(16,hex.length()-i-1) * (ch - 55);}}System.out.println(sum);}
}
第5章 函数
5.1 函数的概念
函数
指一段具有独立功能的代码,减少代码冗余,提高程序的利用率和效率。
如何去定义函数
- 需要一个封闭的空间,将这段独立性的代码进行封装,用一对大括号
- 需要对每一个封闭的空间进行命名,函数名
- 函数所需要的一些原始数据
- 函数所产生的一些结果数据
语法格式
修饰符 函数类型 返回值类型 函数名(数据类型数据1,数据类型 数据2,...) {独立功能的代码片段;return 函数的计算结果;
}
修饰符:指的是函数的访问权限,public private 默认 protected
函数类型:函数的分类,本地函数native,静态函数static,同步函数 synchronized
返回值类型:指的就是函数计算结果的数据类型 如果函数没有返回值 则为void
函数名:就是函数的名称
参数列表:指的是外界向函数传入的数据(实际参数),由这些参数变量进行接收(形式参
数)
函数体:具有独立功能的代码片段;
return:仅仅表示函数结束!如果函数有返回值,则return后跟返回值;如果没有返回值,则
return可以不写,但是是存在的(隐藏的 在最后一行)
分类
有参数有返回值
有参数无返回值
无参数有返回值
无参数无返回值
public class Sample {public static void main(String[] args) {int max = getMax(1,2,3);System.out.println(max);}public static int getMax (int a , int b , int c) {/*if (a >= b && a >= c) {return a;}else if (b >= a && b >= c) {return b;}else {return c;}*/if (a >= b && a >= c) {return a;}if (b >= a && b >= c) {return b;}if (c >= a && c >= b) {return c;}return -10000;}
}
案例1:计算一个数字a的b次幂
案例2:将三个字符串的反转,并拼接打印
案例3:获取当前时间的字符串
5.2 函数的运行原理
函数的运行是基于栈运行的
栈:是一种先进后出的容器,我们这里面所说的栈是指JVM中的栈内存空间
每一个函数,叫做栈帧,栈帧中所包含的内容有函数的定义,参数列表,函数的执行内容代码
每一个函数要运行,就相当于这个栈帧进入到栈内存中-入栈
如果一个函数即将结束,将这个栈帧从栈顶移出-出栈
如果栈内存中有多个栈帧,运行的是最上面的栈帧,底下的栈帧暂停运行,直到该栈帧为栈顶元素
比如:主函数先进栈,开始逐行运行,如果执行到第n行,调用另外一个函数A,则主函数在第n行暂停运行,将另一个函数A的栈帧入栈,再继续逐行运行,直到函数A的内容执行完毕,函数A出栈,主函数接着从第n行继续向下执行。以此类推。
public class Sample {public static void main(String[] args) {int a = 10;int b = 20;String s1 = "123";String s2 = "456";int c = test1(a,b);System.out.println(a);System.out.println(b);System.out.println(c);String s3 = test2(s1,s2);System.out.println(s1);System.out.println(s2);System.out.println(s3);}public static int test1(int a, int b) {a = 20;b = 30;return a + b;}public static String test2(String s1, String s2) {s1 = s1.replace("1","hehe");s2 = s2.replace("4","heihei");return s1 + s2;}
}
import java.util.*;
public class Demo68{public static void main(String[] args){Scanner input = new Scanner(System.in);System.out.print("Enter a number:");int num = input.nextInt();System.out.println(isPalindrome(num));}//判断是否是回文public static boolean isPalindrome(int num){int com = reverse(num);return num == com;}//将数字颠倒public static int reverse(int num){int com = 0;while(num != 0){com = com *10 +num % 10;num /= 10;}return com;}
}
5.3 函数重载
定义
同一个类中可以出现多个同名函数,这个现象就叫做函数的重载(overload)
区分同名函数是否是重载?
前提必须是同名,和返回值类型无关(返回值类型只和函数的计算功能相关),和权限也没有关系,和形式参数的名称也无关!只和形式参数的数据类型有关(数量,排列组合)
public static void show(int a ,float b ,char c){}
下列哪些是该函数的重载:
int show(int x, float y, char z) :不算重载 数据类型都是int float char
void show(float b,int a,char c):算重载,顺序不一样float int char
void show(int a,int b,int c):算重载,顺序不一样int int int
double show():算重载,参数不一样
寻找重载函数的流程:
- 看是否有确切的参数定义匹配,int int 找 int int
- 看是否有可兼容的参数定义匹配,int int找double double或int double或double int
- 如果可兼容的参数定义匹配较多,会报引用确定报错 引用不明确
5.4 函数的递归
函数的递归就是指函数自身调用自身。
- 但凡迭代能够解决的问题,递归都可以解决;递归能够解决的问题,迭代就不一定了
- 相对而言,从内存的角度而言,函数如果过多的自我调用,势必会对内存不友好,占用过多
- 通常来讲,同样的问题用递归写要比用迭代写代码量较少
写递归时,一定要先确定递归结束条件-递归边界
public class Sample {public static void main(String[] args) {//show(); //无限递归test(10);}public static void test(int n) {System.out.println(n);if (n == 1) {return;} else {test(n - 1);}}public static void show() {System.out.println("Hello!");show();}
}
案例1:用递归实现1+2+…+99+100
import java.util.Scanner;
public class Sample {public static void main(String[] args) {System.out.println(f(100));//System.out.println(f(10000000));//StackOverflowErrorint sum = 0;for (int i = 1; i <= 10000000; i++) {sum += i;}System.out.println(sum);}/*求1+2+...+99+100设函数f(x) = 1 + 2 + 3 + ... + x-3 + x-2 + x-1 + xf(3) = 1 + 2 + 3f(2) = 1 + 2f(3) = f(2) + 3=>1 ,x = 1f(x) =f(x-1) + x , x>1递归实现斐波那契数列f(x) = f(x- 1) + xf(100) = f(99) + 100 1+2+3+...+99 + 100f(99) = f(98) + 99 1+2+3+...+98 + 99.....f(4) = f(3) + 4 1+2+3 + 4f(3) = f(2) + 3 1+2 + 3f(2) = f(1) + 2 1 + 2f(1) = 1 递归的边界*/public static int f(int x) {if (x == 1) {return 1;} else {return f(x - 1) + x;}}
}
案例2:递归实现斐波那契数列
public class Sample {public static void main(String[] args) {/*1 1 2 3 5 8 13 21 34 55 ...1 x=1,x=2f(x) =f(x-1) + f(x-2) x>2f(5)f(4) f(3)f(3) f(2) f(2) f(1)f(2) f(1)*///递归O(2^n)System.out.println(f(35));//迭代O(n)System.out.println(fibo_it(35));}public static int fibo_it(int x) {if (x == 1 || x == 2) {return 1;}/*1 1 2 3ca b*/int a = 1;int b = 1;int c = 0;for (int i = 3; i <= x; i++) {c = a + b;a = b;b = c;}return c;}public static int f(int x) {if (x == 1 || x == 2) {return 1;}else {return f(x-1) + f(x-2);}}
}
5.5 编程练习题
Demo81
public class Demo81 {public static void main(String[] args) {String x = "x";String y = "y";String z = "z";hano(3,x,y,z);//前3层从 x->z//前2层从 x->y}/// <param name="begin">承载最初圆盘的柱子</param>/// <param name="mid">起到中转作用的柱子</param>/// <param name="end">移动到的目标柱子</param>public static void hano(int level,String begin,String mid,String end) {if (level == 1) {System.out.println(begin+"->"+end);} else {//将begin柱子上的从上到下n-1个盘移到mid柱子上hano(level - 1,begin,end,mid);System.out.println(begin+"->"+end);//将mid柱子上的n-1个盘子移到end柱子上hano(level - 1,mid,begin,end);}}
}
第6章 数组
6.1 数组的概念及定义
数组主要用于解决大量数据计算与存储的问题
数组是Java提供的一种最简单的数据结构,可以用来存储一个元素 个数固定 且 类型相同 的有序集。
数组在内存中的情况:
栈:主要用于运行函数的内存
堆:主要用于存储数据对象的内存
每一个数组而言,都是存在堆内存当中,每一个数组都是一个对象
- 数组本质上就是在堆内存中一系列地址连续且空间大小相等的存储空间(变量),每一个存储空间用来存储数据(基本,引用)
- 数组是在堆内存中存储,称之为是一个对数对象,并且在堆内存中存储的数据都有 默认初始化 的流程。所以数组创建之初,每一个存储空间里面都会被JVM初始化该数据类型对应的零值。
- 数组的地址是连续的,所以通过公式:An=A1+(n-1)*d可以快速访问到其他的元素,所以对于数组而言查找元素比较快的。将元素的真实物理地址转换成对应的角标获取元素。
- 如何来调用数组呢?通过一个变量存储该数组在堆内存当中的首元素的地址。
- 当数组一旦定义出来,其长度不可变,存储空间的内容是可变的
- 所以我们在定义数组的时候,要么把长度固定,要么直接输入相关的元素。
数组的定义方式
//创建一个指定长度且指定数据类型的一维数组,名称为数组名,虽然没有指定元素,但是会有默认值
数据类型[] 数组名 = new 数据类型[长度];
//创建一个指定元素且指定数据类型的一维数组,名称为数组名,虽然有指定元素,还是有默认初始化这个步骤的!
数据类型[] 数组名 = new 数据类型[]{数据1,数据2,...,数据n};
数据类型[] 数组名 = {数据1,数据2,...,数据n};
示例:
public class Sample {public static void main(String[] args) {int[] arr = new int[5];System.out.println(arr[0]);//System.out.println(arr[5]);//ArrayIndexOutOfBoundsExceptionarr[2] = 10;int[] arr2 = arr;System.out.println(arr2[2]);arr2 = null;//System.out.println(arr2[2]);//NullPointerException/*String s = null;s.length();*/arr = null;}
}
6.2 常用数组操作
数组遍历问题
public class Sample {public static void main(String[] args) {int[] arr = new int[]{1,2,3,4,5,6,7,8,9};//String str str.length()-函数//int[] arr arr.length-属性for (int i = 0; i < arr.length; i++) {arr[i] = arr[i] * 10;System.out.println(arr[i]);}//通过角标遍历 可以在遍历的过程中对指定的元素进行修改//foreach遍历 主要针对的是一些可迭代对象 Iterable/*for (数据类型 变量名 : 可迭代容器) {}*/for (int num : arr) {//num -> arr[i]num = num / 10;System.out.println(num);}//这种遍历方式 只能获取元素,不能修改元素for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}
}
数组最值问题
public class Sample {public static void main(String[] args) {int[] arr = new int[]{3,6,8,2,9,4,5,1,7};int min = arr[0];int max = arr[0];for (int i = 1; i < arr.length; i++) {if (arr[i] < min) {min = arr[i];}if (arr[i] > max) {max = arr[i];}}System.out.println(max);System.out.println(min);}
}
数组扩容问题
public class Sample {public static void main(String[] args) {int[] arr = new int[]{1,2,3,4,5};arr = add(arr,6);arr = add(arr,6);arr = add(arr,6);arr = add(arr,6);for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}//在指定的数组arr中添加元素elementpublic static int[] add(int[] arr, int element) {int[] newArr = new int[arr.length + 1];for (int i = 0; i < arr.length; i++) {newArr[i] = arr[i];}newArr[newArr.length - 1] = element;return newArr;}
}
选择排序算法
思路: 每次将首位数字与后面的所有数字比较,找出其中的最小值放到第一位,在将首位数字移到第二位,在循环比较剩下的数字,找出第二小的数字,以此类推。
public class Sample {//选择排序public static void main(String[] args) {int[] arr = {8,9,2,6,7,1,4,5,3};for (int i = 0; i < arr.length - 1; i++) { //-1 n个数字没有第n轮for (int j = i + 1; j < arr.length; j++) {if (arr[i] > arr[j]) {swap(arr,i,j);}}}print(arr);}//[1, 2, 3, 4, 5]public static void print(int[] arr) {System.out.print("[");for (int i = 0; i < arr.length;i++) {System.out.print(arr[i]);if (i == arr.length - 1) {System.out.println("]");} else {System.out.print(", ");}}}public static void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}
}
冒泡排序算法
思路: 每次将第一个数字,与后面的数字比较,比后面的大就交互位置,反之不交换,一直两两比较,冒出最大值到最后一位,下一次循环减少一次,因为每一次循环比较都会找到当前的最大值,以此类推循环,得出升序。
public class Sample {//冒泡排序public static void main(String[] args) {int[] arr = {8,9,2,6,7,1,4,5,3};for (int i = 0; i <arr.length - 1; i++) {//-1 表示n个数字只有n-1轮for (int j = 0; j < arr.length - 1 - i; j++) {//-1 避免重复比较(当前最大和上一轮最大)if (arr[j] > arr[j + 1]) {swap(arr,j,j+1);}}}print(arr);}public static void print(int[] arr) {System.out.print("[");for (int i = 0; i < arr.length;i++) {System.out.print(arr[i]);if (i == arr.length - 1) {System.out.println("]");} else {System.out.print(", ");}}}public static void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}
}
插入排序算法
- 从数组的第二个数据开始往前比较,即一开始用第二个数和他前面的一个比较,如果 符合条件(比前面的大或者小,自定义),则让他们交换位置。
- 然后再用第三个数和第二个比较,符合则交换,但是此处还得继续往前比较,比如有 5个数8,15,20,45, 17,17比45小,需要交换,但是17也比20小,也要交换,当不需 要和15交换以后,说明也不需要和15前面的数据比较了,肯定不需要交换,因为前 面的数据都是有序的。
- 重复步骤二,一直到数据全都排完。
public class Sample {//插入排序public static void main(String[] args) {int[] arr = {8,9,2,6,7,1,4,5,3};for (int i = 1; i < arr.length; i++) {int e = arr[i];int j = 0;for (j = i; j > 0 && arr[j - 1] > e; j--) {arr[j] = arr[j - 1];}arr[j] = e;}print(arr);}public static void print(int[] arr) {System.out.print("[");for (int i = 0; i < arr.length;i++) {System.out.print(arr[i]);if (i == arr.length - 1) {System.out.println("]");} else {System.out.print(", ");}}}
}
二分查找算法
思路: 在有序数组中,每次找到最小值,最大值,中间值,比较中间值和当前寻找值的大小,大于则在有序数组的右边,重新定义最大值,最小值,中间值为右边部分,小于则重复上述步骤(定义与左边),找到就返回下标,当最小值的下标大于最大值的下标时表示没找到返回-1.
public class Sample {//二分查找public static void main(String[] args) {int[] arr = {1,2,3,4,5,6,7,8,9};int min = 0;int max = arr.length - 1;int mid = (min + max) / 2;int key = 10;while (arr[mid] != key) {if (key < arr[mid]) {max = mid - 1;}if (arr[mid] < key) {min = mid + 1;}if (min > max) {mid = -1;break;}mid = (min + max) / 2;}System.out.println(mid);}
}
计数排序法
public class Sample {//计数排序public static void main(String[] args) {int[] arr = {-2,9,-1,12,8,-3,6,7,4,5,2,1,0,8,6,7,4,-3,-2,-1,-1,7};int min = arr[0];int max = arr[0];//O(n)for (int i = 1; i < arr.length; i++) {if (arr[i] < min) {min = arr[i];}if (arr[i] > max) {max = arr[i]; }}int[] temp = new int[max - min + 1];//对应关系 index = number - min number = index + min//O(n)for (int i = 0; i < arr.length; i++) {temp[arr[i] - min]++;}//temp[index] 表示index对应的数字number出现的次数int k = 0;//O(n)for (int index = 0; index < temp.length; index++) {while (temp[index] != 0) {arr[k] = index + min;k++;temp[index]--;}}print(arr);}public static void print(int[] arr) {System.out.print("[");for (int i = 0; i < arr.length;i++) {System.out.print(arr[i]);if (i == arr.length - 1) {System.out.println("]");} else {System.out.print(", ");}}}
}
基数排序法
import java.util.LinkedList;public class Sample {//基数排序public static void main(String[] args) {int[] arr = {102,203,321,13,12,78,96,34,37,28,6,8,5,6};//1.先找到最大值 决定轮数int max = arr[0];for (int i = 0; i < arr.length; i++) {if (arr[i] > max) {max = arr[i];}}int radex = (max + "").length();//2.创建十个桶 每一个桶是LinkedListLinkedList<Integer>[] queues = new LinkedList[10];for (int i = 0; i < queues.length; i++) {queues[i] = new LinkedList<Integer>();}//3.进行数字分类和规整//r=0个位 r=1十位 r=2百位...for (int r = 0; r < radex; r++) {//先按照r进行分类for (int i = 0; i < arr.length; i++) {int index = getIndex(arr[i],r);//获取数字的r位 返回该数字要去的桶的角标0~9queues[index].offer(arr[i]);}//然后在重新规整到arr里int k = 0;for (int index = 0; index < queues.length; index++) {while(!queues[index].isEmpty()) {arr[k++] = queues[index].poll();}}}print(arr);}public static int getIndex(int number, int r) {//123 r=0//123 r=1//123 r=2int index = 0;for (int i = 0; i <= r; i++) {index = number % 10;number /= 10;}return index;}public static void print(int[] arr) {System.out.print("[");for (int i = 0; i < arr.length;i++) {System.out.print(arr[i]);if (i == arr.length - 1) {System.out.println("]");} else {System.out.print(", ");}}}
}
6.3 二维数组
二维数组,在表现形式上就是一个表格,在操作表格的时候以行列来操作
所谓的二维数组,本质上就是一个一维数组,只不过该一维数组里面的元素是另一个一维数组而已
二维数组的定义
public class Sample {public static void main(String[] args) {//数据类型[][] 矩阵名 = new 数据类型[row][col];int[][] matrix = new int[3][2];/*数据类型[][] 矩阵名 = new 数据类型[][] {{...},{...},{...}};数据类型[][] 矩阵名 = {{...},{...},{...}};*/int[][] matrix2 = {{1,2,3},{4,5,6},{7,8,9}};for (int i = 0; i < matrix2.length; i++) {for (int j = 0; j < matrix2[i].length; j++) {System.out.print(matrix2[i][j] + " ");}System.out.println();}int[][] matrix3 = {{1},{1,2,3},{1,2,3,4},{7,6,5,4,3,2,1}};for (int i = 0; i < matrix3.length; i++) {for (int j = 0; j < matrix3[i].length; j++) {System.out.print(matrix3[i][j] + " ");}System.out.println();}}
}
输入8个点坐标,然后计算这些点中,那两个点的距离是最近的
定义一个二维数组,来接受用户输入的八个点的坐标,在循环判断两个坐标的距离,从而获取两点间的最短距离。
import java.util.Scanner;
public class Sample {public static void main(String[] args) {Scanner input = new Scanner(System.in);//定义一个8行两列的二维数组double[][] points = new double[8][2];//1.获取输入的点坐标for (int i = 0; i < points.length; i++) {System.out.print("请输入第" + (i + 1) + "个点坐标:");points[i][0] = input.nextDouble();points[i][1] = input.nextDouble();}//默认最短距离为点0和点1double shortestDistance = getDistance(points,0,1);int p1 = 0;int p2 = 1;for (int i = 0; i < points.length - 1; i++) {for (int j = i + 1; j < points.length; j++) {double distance = getDistance(points,i,j);//比较判断最短距离,小于就获取该下标if (distance < shortestDistance) {shortestDistance = distance;p1 = i;p2 = j;}}}System.out.printf("(%.1f,%.1f)和(%.1f,%.1f)的距离为最短%.1f",points[p1][0],points[p1][1],points[p2][0],points[p2][1],shortestDistance);}public static double getDistance(double[][] m , int p1 , int p2) {//用函数计算两点间的距离return Math.hypot(m[p1][0] - m[p2][0] , m[p1][1] - m[p2][1]);}
}
6.4 编程练习题
思路: 计数排序思路,根据下标来对对应出现的数字计数,最后在输出。
import java.util.Scanner;
public class Demo82{public static void main(String[] args) {System.out.print("Enter the number between 1 and 100:");Scanner input = new Scanner(System.in);//数组保存用户输入的数字0表示输入结束int[] array = new int[101];while(true) {int num = input.nextInt();if(num == 0){break;}//输入数字的对应数组下标加1array[num]++;}//循环输出数组中角标出现的次数,次数为0不管,1次输出time,否则输出timesfor(int i=0;i<array.length;i++){if(array[i] != 0){if(array[i] == 1){System.out.println(i+" occurs "+array[i]+" time");}else{System.out.println(i+" occurs "+array[i]+" times");}}}}
}
思路1:动态扩容数组,定义一个长度为0的数组,从0开始循环10次,每次都判断数组中是否包含用户输入的数组,包含则跳过,否则,就扩容定义的数组,没次扩容一个数字。
思路2:固定数组长度 用标记表示有效数据,定义数组长度为10,在定义一个变量size来标记有效数字的个数和角标。
import java.util.*;
public class Demo83{public static void main(String[] args) {//思路1:动态扩容数组// int[] array = new int[0];// System.out.print("Enter ten numbers:");// Scanner input = new Scanner(System.in);// for(int i=0;i<10; i++) {// int num = input.nextInt();// if(!container(array,num)){// array = add(array,num);// }// }// System.out.println(Arrays.toString(array));//思路2:固定数组长度,用标记表示数据int[] array = new int[10];//即表示有效数字的个数,也表示当前数组的角标int size = 0;System.out.print("Enter ten numbers:");Scanner input = new Scanner(System.in);for(int i=0;i<10; i++) {int num = input.nextInt();if(!container(array,num,size)){array[size++] = num;}}System.out.println(toString(array,size));}//自定义Arrays.toString();方法public static String toString(int [] arr,int size){String s="[";for(int i=0;i<size; i++) {if(arr[i] !=0){if(i == size-1){s += arr[i]+"]";}else{s += arr[i]+",";}}}return s;}//重载方法(思路2)public static boolean container(int[] arr,int num,int size){for(int i=0;i<size; i++) {if(arr[i] == num){return true;}}return false;}//动态扩容该数组,每次扩容一个数字public static int[] add(int[] arr,int num){int[] newArr = new int[arr.length+1];for(int i=0;i<arr.length; i++) {newArr[i] = arr[i];}newArr[arr.length] = num;return newArr;}//循环遍历数组当期数字是否已经在该数组中public static boolean container(int[] arr,int num){for(int i=0;i<arr.length; i++) {if(arr[i] == num){return true;}}return false;}
}
获取数组中的最小值,从改值倒序遍历,查找一个可以整除数组中的所有数字,找到就返回输出该数
import java.util.*;
public class Demo85{public static void main(String[] args) {System.out.println(gcd(35,40,20,55));System.out.println(gcd(28,16));} //返回最大公约数方法public static int gcd(int ... numbers) {int min = getMin(numbers);//每次从最小值遍历,循环判断该数是否可以整除数组中的每一个数,可以就返回输出for(int i=min; i>=1; i--) {boolean flag = true;for(int j=0; j<numbers.length; j++){if(numbers[j] % i != 0){flag = false;break;}}if(flag) {return i;}}return 1;}//获取输入数组中的最小值public static int getMin(int[] array) {int min = array[0];for(int i=1; i<array.length;i++) {if(array[i] < min){min = array[i];}}return min;}
}
随机数来模拟小球的路径,1表示R,0表示L,每次产生输入小球的个数个路径,并统计其中R的个数,根据R的个数来判读小球落进那个槽子,对应的槽子的个数加1,在打印槽子的数组即可。
import java.util.*;
public class Demo88{public static void main(String[] args) {Scanner input = new Scanner(System.in);//随机数1表示R,0表示LRandom random = new Random();System.out.print("请输入球的个数:");int balls = input.nextInt();System.out.print("请输入槽子的个数:");int slots = input.nextInt();//定义一个槽子的数组,保存的值为落进小球的个数int[] temp = new int[slots];//定义一个路径的个数,随机产生的每个小球的路径String[] paths = new String[balls];//循环次数为小球的个数for(int i=0; i<balls; i++) {//每一个小球的具体路径String path = "";//路径中R出现的个数int Rcount = 0;for(int j=0; j<slots-1; j++){if(random.nextInt(2) == 0) {path += "L";}else{path += "R";Rcount++;}}paths[i] = path;System.out.println(path);temp[Rcount]++;}System.out.println(Arrays.toString(temp));}
}
import java.util.*;
public class Demo90{public static void main(String[] args){//获取输入个数据System.out.print("请输入数字的个数:");Scanner input = new Scanner(System.in);int num = input.nextInt();System.out.print("请输入"+num+"个数字:");int[] arr = new int[num];//定义一个数字长度为num的一维数组,来保存用户输入的数字for(int i=0; i<arr.length; i++){arr[i] = input.nextInt();}//方法判断该数组中是否有连续出现的四个数字isConsecutiveFour(arr);}public static void isConsecutiveFour(int[] arr) {//循环判断数组中连续相等的数字,相等计数器就加一,到4就输出true,结束程序运行,否则就从J开始重新循环for(int i=0; i < arr.length;) {//count为1,提前去除了一个,用来判断int count = 1,j=0;for(j=i+1; j < arr.length; j++) {if(arr[i] == arr[j]){count++;}else {break;}}if(count >= 4){System.out.println("true");return;}else{i=j;}}System.out.println("false");}
}
如上图比较两个数组中的值,但是每次比较是要先判断两个数组的其中一个下标是否已经越界,对于越界的就直接拼接没有越界数组的后面数字即可,没越界的就进行两数组的比较。
import java.util.*;
public class Demo91{public static void main(String[] args) {int[] list1 = {1,3,5,7,9,50,90};int[] list2 = {2,4,6,8,10};//调用方法获取拼接两个排序后的最终数组int[] list3 = merge(list1,list2);System.out.println(Arrays.toString(list3));}public static int[] merge(int[] arr1,int[] arr2) {//返回数组的长度为两数组长度的总和int[] arr3 = new int[arr1.length + arr2.length];//下标都从0开始int p1=0,p2=0,p3=0;//先判断两个下标是否越界(数组的长度)while(p1 < arr1.length || p2 < arr2.length){//每次都先判断两个数组中是否有一个下标,越界(如果先直接判断两个值的大小的话,会出现下标越界的异常)if(p1 >= arr1.length && p2 < arr2.length){arr3[p3++] = arr2[p2++];}else if(p2 >= arr2.length && p1 < arr1.length){ arr3[p3++] = arr1[p1++];}else if(arr1[p1] > arr2[p2]) {arr3[p3++] = arr2[p2++];}else{arr3[p3++] = arr1[p1++];}}return arr3;}
}
import java.util.*;
public class Demo92{public static void main(String[] args) {//定义一个字符串数组,为要猜的单词词库String[] words = {"apple","banana","python","computer"};Scanner input = new Scanner(System.in);Random random = new Random();while(true){//随机从词库中获取一个单词String word = words[random.nextInt(words.length)];//定义一个单词的状态数组,true代表明文显示单词,false代表密文显示单词boolean[] status = new boolean[word.length()];//统计猜错的次数int count = 0;while(!isOver(status)){//每次根据状态数组显示要密文或明文显示的字符String password = getPassWord(word,status);System.out.print("Enter a letter in word "+password+" > ");//获取用户输入的单词String letter = input.nextLine();//判断字母是否在单词中if(word.contains(letter)){//在改变状态数组,如该状态已经为true就输出下面的提示if(!changeStatues(word,letter,status)){System.out.println("\t" + letter + " is alreay in the word");}}else{//不包含输入的字符就记录输入错误的次数,并打印信息System.out.println("\t"+letter+" is not in the word.");count++;}}System.out.println("The word is " + word + ". You missed " + count);//循环玩游戏System.out.print("Do you want again?(y/n):");String choice = input.nextLine();if(choice.equals("n")){break;}}}public static boolean changeStatues(String word,String letter, boolean[] status){//改变状态数组中的值,先获取相等字符的下标,在判断该状态数组中的该下标是否为true,为true返回false(表示该字符以猜出,去除重复猜),否则返回truechar ch = letter.charAt(0);for(int i=0; i<word.length(); i++) {if(word.charAt(i) == ch){if(status[i]){return false;}else{status[i] = true;}}}return true;}//判断是否继续如果状态数组全为true,就结束游戏了public static boolean isOver(boolean[] status){for(int i=0;i<status.length;i++){if(!status[i]){return false;}}return true;}public static String getPassWord(String word,boolean[] status) {//判断状态数组为true,明文显示对应下标的字母,为false显示*密文String password = "";for(int i=0; i<status.length; i++){if(status[i]){password += word.charAt(i);}else {password += "*";}}return password;}
}
import java.util.Scanner;
public class Demo101 {//1.定义15 * 15一个棋盘public static String[][] baord = new String[15][15];//玩家轮次计数(同样也是棋子的个数)偶数表示黑棋,奇数表示白棋public static int player = 0;//黑棋(O)和白棋(X)public static final String BLACK_CHESS = "O";public static final String WHITE_CHESS = "X";public static Scanner input = new Scanner(System.in);public static void main(String[] args) {//2.初始化棋盘和打印棋盘initBoard();printBoard();//3.开始下棋startGame();}public static void startGame() {//只要棋盘没有5子相连就继续下棋while(!isGameOver()){if(player % 2 ==0) {//黑棋下System.out.println(">>>请黑方下棋");playChess(BLACK_CHESS);}else{ //白棋下System.out.println(">>>请白方下棋");playChess(WHITE_CHESS);}player++;}//棋数等于棋盘数则为和棋if(player == 15 * 15){System.out.println(">>>和棋,游戏结束!");}else {//根据棋数判断哪个棋子赢(-1表示循环出来后加了1所有这里要减去)if((player-1) % 2 == 0) {System.out.println(">>>黑棋赢,游戏结束!");}else {System.out.println(">>>白棋赢,游戏结束!");}}}//判断棋盘是否有棋子连成5子(游戏是否结束)public static boolean isGameOver() {for(int row=0; row<baord.length;row++) {for(int col=0;col<baord[row].length;col++) {if(!baord[row][col].equals("+")){//棋子向右判断(11,为向右的边界值)if(col < 11){ boolean flag = true;for(int c=col + 1; c<=col+4; c++){if(!baord[row][col].equals(baord[row][c])){flag = false;break;}}if(flag){return true;}}//棋子向下判断if(row < 11){ boolean flag = true;for(int r=row + 1; r<=row+4; r++){if(!baord[row][col].equals(baord[r][col])){flag = false;break;}}if(flag){return true;}}//棋子向右上判断if(row > 3 && col < 11){ boolean flag = true;for(int r=row - 1,c = col + 1; c <= col+4;r--,c++){if(!baord[row][col].equals(baord[r][c])){flag = false;break;}}if(flag){return true;}}//棋子向右下判断if(row < 11 && col < 11){ boolean flag = true;for(int r=row + 1,c = col + 1; c <= col+4;r++,c++){if(!baord[row][col].equals(baord[r][c])){flag = false;break;}}if(flag){return true;}}}}}return false;}//下棋方法public static void playChess(String chess) {System.out.print("请输入棋子的坐标:");int x = input.nextInt() - 1;int y = input.nextInt() - 1;if(!baord[y][x].equals("+")) {//判断该处是否有棋子,有的话下棋数--返回上一次System.out.println("此处已有棋子,请重新下!");//--回到上一步player--;return;}//为棋盘下相应的棋子,并重新打印棋盘baord[y][x] = chess;printBoard();}//格式化打印棋盘以及棋盘上面,和左边对应的序号public static void printBoard(){System.out.print(" ");for(int i=1; i<=baord[0].length; i++){System.out.printf("%-3d",i);}System.out.println();for(int i=0;i<baord.length;i++){System.out.printf("%2d ", i + 1);for(int j=0;j<baord[i].length;j++) {System.out.print(baord[i][j]+" ");}System.out.println();}}//初始化棋盘public static void initBoard(){//循环棋盘为棋盘赋值(+)for(int i=0;i<baord.length;i++){for(int j=0;j<baord[i].length;j++) {baord[i][j]="+";}}}
}
八皇后
简单理解递归就是循环嵌套循环,循环完就返回执行上一个,直到顶部最外层的循环执行完毕才结束,整个循环,输出的话,就是根据具体的条件,输出结果即可。
public class NQueen{//N皇后public static int N = 8;//棋盘public static int[][] board = new int[N][N];//统计有几种解法public static int count = 0;public static void main(String[] args) {nqueen(0);}public static void nqueen(int row) {//如果行增到和N相等表示,该组合就是一种解法,直接打印输出即可if(row == N){count++;System.out.printf("这是第%d种解法:\n",count);for(int i=0; i<board.length; i++){for(int j=0; j<board[i].length; j++){System.out.print(board[i][j]+" ");}System.out.println();}}else{//否则就从第一行每个格开始下for(int col=0; col<N; col++) {//如果该空可以下就先清空该行,在将皇后放在对应的坐标上if(!isDangerous(row,col)){for(int c=0; c<N; c++){board[row][c] = 0;}board[row][col] = 1;//递归到下一行(循环的嵌套)nqueen(row+1);}}}}//判断当期空格是否可以放皇后public static boolean isDangerous(int row,int col) {//向上判断,行递减for (int r = row - 1;r >= 0; r--) {if (board[r][col] == 1) {return true;}}//向左上判断,行列都递减for (int r = row - 1,c = col - 1; r >= 0 && c >= 0;r--,c--) {if (board[r][c] == 1) {return true;}}//向右上判断,行递减,列递增for (int r = row - 1,c = col + 1; r >= 0 && c < N; r--,c++) {if (board[r][c] == 1) {return true;}}//可以就返回falsereturn false;}
}
6.4 LeetCode题
倒序循环判断是否产生进位,产生进位就继续循环,没进位就直接退出,如果循环完还有进位,就对数组进行扩容,将首位赋值为1即可。
import java.util.*;
public class LeetCode66{public static void main(String[] args) {int[] arr1 = {9,9,9};int[] arr2 = {9,9,9,9,9};System.out.println(Arrays.toString(plus(arr1,arr2)));}public static int[] plus(int[] digits1,int[] digits2) {//将两个数组扩容到长度相等,比较谁小就扩谁if(digits1.length < digits2.length) {digits1 = kuorong(digits1,digits2.length);}else if(digits1.length > digits2.length) {digits2 = kuorong(digits2,digits1.length);}//进位符int carry = 0;//数组从后开始加for(int i=digits1.length-1; i>=0; i--){//两个数组中每两个数相加,并加上进位符,第一次为0,每次加后要对进位符进行重新赋值int num = digits1[i] + digits2[i] + carry;//判断当前相加的两个数字是否产生进位carry = num / 10;//将相加结果赋值给数组1digits1[i] = num % 10;}//循环完后进位符为1则表示要对数组扩容,产生进位if(carry == 1){//定义一个新数组,第一位为1,后面的位数遍历digits1来赋值,最后返回digits3int[] digits3 = new int[digits1.length + 1];digits3[0] = 1;for(int i=0;i<digits1.length;i++){digits3[i+1] = digits1[i];}return digits3;}//循环完没产生进位返回digits1return digits1;}//数组扩容num 为要扩容的长度public static int[] kuorong(int[] arr, int num) {int[] newArr = new int[num];//定义两个下标都从数组的最后一位开始递减int i = arr.length - 1,k = newArr.length - 1;//为新的数组赋值,从后往前赋,角标低的为0while(i >= 0){newArr[k--] = arr[i--];}return newArr;}
}
public class LeetCode283{public void moveZeroes(int[] nums) {//思路1:选择排序思路// for(int i=0; i<nums.length - 1; i++) {// for(int j=i+1; j<nums.length; j++){// //左边为0右边不为0就交换// if(nums[i] == 0 && nums[j] != 0){// int temp = nums[i];// nums[i] = nums[j];// nums[j] = temp;// break;// }// }// }//思路2:插入排序思路// for(int i=1; i<nums.length; i++) {// //为0就跳过这次循环// if(nums[i] == 0){// continue;// }// //只要j-1为0的话就交换位置// for(j=i; j>0 && nums[j-1] == 0; j--){// int temp = nums[i];// nums[j] = nums[j-1];// nums[j-1] = temp;// }// }//思路3:双指针做法 k一直卡着第一个0//数组为空直接结束程序if(nums == null){return;}//定义一个k始终指向数组中的第一0int k = 0;for(int i=0; i<nums.length; i++){//如果当前元素不为0就交换i和k角标对应的值(不为0就自己交互自己),为0就不管直接到下一个不为0的数字if(nums[i] != 0){int temp = nums[i];nums[i] = nums[k];nums[k] = temp;k++;}}}
}
对数组排序,排序后取出n/2位置的数即是该数组的多数元素。
class Solution {public int majorityElement(int[] nums) {//思路1:插入排序做 排序之后中间的位置一定是众数/*for (int i = 0; i < nums.length; i++) {int e = nums[i];int j = 0;for (j = i; j > 0 && nums[j - 1] > e; j--) {nums[j] = nums[j - 1];}nums[j] = e;}return nums[nums.length / 2];*///思路2:正负相消//默认出现数组中第一个数,出现次数为1int num = nums[0];int count = 1;//从数组中第二个数开始循环判断,等于出现的数就次数加1//不等于就次数减1,抵消一个数,如果次数小于0,表示出现了另外一个数,将另外一个数赋值,将次数赋为1for(int i=1; i<nums.length; i++){if(nums[i] == num){count++;}else{if(count > 0){count--;}else{num = nums[i];count = 1;}}}return num;}
}
定义左右指针,判断左右奇偶情况,根据情况来替换,或移动指针。
class Solution {public int[] sortArrayByParity(int[] A) {int l = 0;int r = A.length - 1;while(l < r){//左奇右偶if(A[l] % 2 == 1 && A[r] % 2 == 0) {int temp = A[l];A[l] = A[r];A[r] = temp;//左偶右奇}else if(A[l] % 2 == 0 && A[r] % 2 == 1){l++;r--;//左奇右奇}else if(A[l] % 2 == 1 && A[r] % 2 == 1){r--;//右偶右偶}else{l++;}}return A;}
}
对数组求和,对求和数除三,分为三组,循环数组,用求和除三的数对每个数组的值进行相减,如果求和除三的数减到0则为一组,对组计数,并对求和除三的数重新赋值,在继续循环判断,返回判断组计数是否为3。
class Solution {public boolean canThreePartsEqualSum(int[] arr) {int sum = 0;//求和数组for(int i=0; i < arr.length; i++){sum += arr[i];}//对求和数分三份int key = sum / 3;//组计数器int group = 0;for(int i=0; i < arr.length; i++){key -= arr[i];//如果key为0则为一组,并对key出现赋值if(key == 0){group++;key = sum / 3;}}//返回结果,如果总和为0,且组数大于3,则可以自由组合为三组返回truereturn group == 3 || sum == 0 && group >=3;}
}
定义左右指针,用数组总和计算左右的和,并判断左右的和是否相等,相等就返回角标,结束程序的运行,循环完,没有结果,就返回-1。
class Solution {public int pivotIndex(int[] nums) {//对数组求和int sum = 0;for(int i=0; i<nums.length; i++) {sum += nums[i];}//定义数组左右两边的总和int leftSum=0,rightSum=0;for(int i=0; i<nums.length; i++){if(i == 0){leftSum = 0;}else{//对数组左边求和累加leftSum += nums[i-1];}//对数组右边求和,总和减左边的和,在减当前角标对应的数值rightSum = sum - leftSum - nums[i];//左右两边相等就结束程序,返回下标if(rightSum == leftSum) {return i;}}return -1;}
}
class Solution {public int minSubArrayLen(int s, int[] nums) {int len = 0, i = 0, sum = 0;for(int j=0; j<nums.length; j++){//总数相加sum += nums[j];//总数大于s的话就先判断该长度是否小于len,小于就为len重新赋值,否则就缩小左边的窗口//左边弹出一个值,对应的总数将弹出的值,如果总和比s小,就扩大右边的窗口,右边加入一个值总数加一,后面的数依次类推while(sum >= s) {len = len == 0 ? j-i+1 : Math.min(len,(j-i+1));sum -= nums[i++];}}return len;}
}
JavaSE笔记(语法基础篇)相关推荐
- 深度学习word2vec笔记之基础篇
深度学习word2vec笔记之基础篇 声明: 1)该博文是多位博主以及多位文档资料的主人所无私奉献的论文资料整理的.具体引用的资料请看参考文献.具体的版本声明也参考原文献 2)本文仅供学术交流,非商用 ...
- 《算法笔记》——基础篇习题选择结构
<算法笔记>--基础篇习题 第二章 C/C++快速入门--2.3选择结构 [习题A] 一元二次方程求根 Problem Description Thinking Notes Code Im ...
- jqGrid 学习笔记整理——基础篇
jqGrid 学习笔记整理--基础篇 jqGrid 实例中文版网址:http://blog.mn886.net/jqGrid/ 国外官网:http://www.trirand.com/blog/ 本人 ...
- 极客时间 Redis核心技术与实战 笔记(基础篇)
Redis 概览 Redis 知识全景图 Redis 问题画像图 基础篇 基本架构 数据结构 数据类型和底层数据结构映射关系 全局哈希表 链式哈希解决哈希冲突 渐进式 rehash 不同数据结构查找操 ...
- Java学习笔记之基础篇
Java学习笔记之基础篇 目录 Java如何体现平台的无关性? 面向对象(OO)的理解 面向对象和面向过程编程的区别 面向对象三大特征 静态绑定和动态绑定(后期绑定) 延伸:类之间的关系 组合(聚合) ...
- CSS阅读笔记---CSS基础篇
本文是这些天阅读慕课网的css基础篇部分所作的笔记. 文章目录 一.基本知识 二.选择器 1.标签选择器 2.类选择器 3.ID选择器 4.子选择器 5.包含(后代)选择器 6.通用选择器 7.伪类选 ...
- Excel学习笔记之基础篇
记录一下跟着网易云课堂大饼老师Excel课程学习的笔记,只能起一个大纲的作用吧,用来练习的数据表不方便上传,也懒得截图录屏做成GIF操作啥的.课程共分为基础篇,进阶篇之函数,进阶篇之数据透视,进阶篇之 ...
- Win32汇编学习笔记之基础篇
基础篇 第一章 背景知识 1.1 Win32的软硬件平台 1.1.1 80x86系列处理器简史 Win32可以在多种硬件平台上运行,但使用最广泛的硬件平台是基于Intel公司80x86系列处理器 ...
- MySQL学习笔记(基础篇未完待补充)
一.MySQL数据库基 目录 一.MySQL数据库基础篇 1.数据库概述与MySQL安装篇 第1章:数据库概述 1.为什么要使用数据库 2. 数据库与数据库管理系统 2.2 数据库与数据库管理系统的关 ...
最新文章
- 一步一步学Silverlight 2系列(32):图形图像综合实例—“功夫之王”剧照播放_转载...
- 大型机,说爱你不容易
- 2019牛客暑期多校训练营(第五场)
- 动态规划之硬币表示问题
- 小学生计算机舞蹈,最近“泼水成画”很火?舞蹈生VS体育生,看到计算机:你是来添乱的?...
- LeetCode 1533. Find the Index of the Large Integer(二分查找)
- page.ClientScript.RegisterStartupScript
- 用java输入学生姓名查询成绩_编写一个Java程序,提示用户输入学生数量,学生姓名和他们的成绩,并按照成绩的降序打印学生姓名...
- linux arm9视频哪个好,谈谈ARM7与ARM9的区别
- 基于JAVA+SpringBoot+Mybatis+MYSQL的旅游管理系统
- ubuntu 12 04下安装JDK7
- linux中脚本后台执行的方法
- 分数的计算机应用教案,计算机应用实训实验
- ZMQ源码阅读 ---- zmq创建线程的过程
- Ubuntu14.04创建WiFi热点
- linux终端怎么设置monaco,ubuntu16.04安装monaco字体
- EXCEL实现按照奇偶行填充
- 支持DDR5,超频更简单,小雕够给力,技嘉B760M小雕WIFI主板上手
- java表格组件_表格组件 java
- Hibernate复杂查询——多参数分页 in()查询(多参数、分页、in())
热门文章
- 关于Z变换及其物理含义
- 计算机网络期末复习攻略
- A component required a bean of type ‘XXX‘ that could not be found 解决办法
- 2020上海交通大学考研专业课之DHCP
- 猜猜这是icpc20年那一场的a题,高斯消元re
- 线扫相机DALSA-采集卡指示灯说明
- 手机计算机游戏攻略,手机游戏攻略_电脑游戏攻略_单机游戏攻略 - zd423
- css鼠标经过样式记录
- 【数据结构】通讯录整理
- bzoj 4009: [HNOI2015]接水果 整体二分+k-d tree