目录
- 第二章
- 1、&—逻辑与 | —逻辑或 !—逻辑非
- 2、三元运算符
- 3、流程控制:顺序、分支、循环
- 从键盘获取值
- 第三章 数组
- 笔试题
- 随机生成数
- 数组的复制、反转、查找(线性查找、二分法查找)
- 排序算法
- 冒泡排序
- 快速排序
第一章
应用程序 = 算法 + 数据结构
int、byte范围:-128 ~ 127
基本数据类型的默认值,存储字节
从大到小需要强制转换
第二章
1、&—逻辑与 | —逻辑或 !—逻辑非
&& —短路与
“&”和“&&”的区别:
单&时,左边无论真假,右边都进行运算;
双&时,如果左边为真,右边参与运算,如果左边为假,那么右边不参与运算。
2、三元运算符
:(条件表达式)?a:b;
凡是可以使用三元运算符的地方,都可以改写为if-else
反之,不成立。
//如果程序既可以使用三元运算符,又可以使用if-else结构,那么优先选择三元运算符。原因:简洁、执行效率高。
class SanYuanTest{
public static void main(String[] args){
// 获取两个整数较大者
int m=12;
int n=5;
int max=(m>n)?m:n;
System.out.println(max);
n=12;
String maxStr=(m>n)?"m大":(m==n)?"m和n相等":"n大");
//三元运算符可以嵌套使用
System.out.println(maxStr);
//获取三个数的最大值
int n1 = 12;
int n2 = 30;
int n3 = -43;
int max1 = (n1 > n2)? n1 : n2;
int max2 = (max1 > n3)? max1 : n3;
System.out.println("三个数中的最大值为:" + max2);
//不建议,可读性差
//int max3 = (((n1 > n2)? n1 : n2) > n3)? ((n1 > n2)? n1 : n2) : n3;
System.out.println("三个数中的最大值为:" + max3);
}
}
3、流程控制:顺序、分支、循环
从键盘获取值
/*
如何从键盘获取不同类型的变量:需要使用Scanner类
具体实现步骤:
1.导包:import java.util.Scanner;
2.Scanner的实例化:Scanner scan = new Scanner(System.in);
3.调用Scanner类的相关方法(next() / nextXxx()),来获取指定类型的变量
注意:
需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型不匹配时,会报异常:InputMisMatchException
导致程序终止。
*/
//1.导包:import java.util.Scanner;
import java.util.Scanner;
class ScannerTest{
public static void main(String[] args){
//2.Scanner的实例化
Scanner scan = new Scanner(System.in);
//3.调用Scanner类的相关方法
System.out.println("请输入你的姓名:");
String name = scan.next();
System.out.println(name);
System.out.println("请输入你的芳龄:");
int age = scan.nextInt();//intx型
System.out.println(age);
System.out.println("请输入你的体重:");
double weight = scan.nextDouble();
System.out.println(weight);
System.out.println("你是否相中我了呢?(true/false)");
boolean isLove = scan.nextBoolean();
System.out.println(isLove);
//对于char型的获取,Scanner没有提供相关的方法。只能获取一个字符串
System.out.println("请输入你的性别:(男/女)");
String gender = scan.next();//"男"
char genderChar = gender.charAt(0);//获取索引为0位置上的字符
System.out.println(genderChar);
}
}
if语句例题2
编写程序:由键盘输入三个整数分别存入变量num1、num2、num3,
对它们进行排序(使用 if-else if-else),并且从小到大输出。
import java.util.Scanner;
class IfTest2{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
System.out.println("第一个数");
int num1=scanner.nextInt();
System.out.println("第二个数");
int num2=scanner.nextInt();
System.out.println("第三个数");
int num3=scanner.nextInt();
if(num1 >= num2){
if(num3 >= num1)
System.out.println(num2 + "," + num1 + "," + num3);
else if(num3 <= num2)
System.out.println(num3 + "," + num2 + "," + num1);
else
System.out.println(num2 + "," + num3 + "," + num1);
}
else{
if(num3 >= num2)
System.out.println(num1 + "," + num2 + "," + num3);
else if(num3 <= num1)
System.out.println(num3 + "," + num1 + "," + num2);
else
System.out.println(num1 + "," + num3 + "," + num2);
}
}
}
2)switch说明:
① 根据switch表达式中的值,依次匹配各个case中的常量。一旦匹配成功,则进入相应case结构中,调用其执行语句。
当调用完执行语句以后,则仍然继续向下执行其他case结构中的执行语句,直到遇到break关键字或此switch-case结构
末尾结束为止。
② break,可以使用在switch-case结构中,表示一旦执行到此关键字,就跳出switch-case结构
③ switch结构中的表达式,只能是如下的6种数据类型之一:
byte 、short、char、int、枚举类型(JDK5.0新增)、String类型(JDK7.0新增)
④ case 之后只能声明常量。不能声明范围。
⑤ break关键字是可选的。
⑥ default:相当于if-else结构中的else.
default结构是可选的,而且位置是灵活的。
格式
switch(表达式){
case常量1:
语句1;break;
default:语句;
//break;
}
例1
/*
例题:对学生成绩大于60分的,输出“合格”。低于60分的,输出“不合格”。
说明:如果switch-case结构中的多个case的执行语句相同,则可以考虑进行合并。
*/
class SwitchCaseTest1 {
public static void main(String[] args) {
//更优的解决方案:
switch(score / 60){
case 0:
System.out.println("不及格");
break;
case 1:
System.out.println("及格");
break;
}
}
}
例2
/*
编写程序:从键盘上输入某年的“year”“month”和“day”,要求通过程序输出输入的日期为2019年的第几天。
闰年2月29天: 1。能被4整除而不能被100整除。 2。能被400整除。
2 15: 31 + 15
5 7: 31 + 28 + 31 + 30 + 7
....
说明:break在switch-case中是可选的
*/
import java.util.Scanner;
class SwitchCaseTest2{
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
System.out.println(""输入year);
int year=scan.nextInt();
System.out.println(""输入mouth);
int mouth=scan.nextInt();
System.out.println(""输入mouth);
int mouth=scan.nextInt();
System.out.println(""输入2019年的day);
int day=scan.nextInt();
int sumDay=0;
swtich(mouth){//倒着写从case1往上写
case 12:
sumDay=30;
case 11:
sumDays += 31;
case 10:
sumDays += 30;
case 9:
sumDays += 31;
case 8:
sumDays += 31;
case 7:
sumDays += 30;
case 6:
sumDays += 31;
case 5:
sumDays += 30;
case 4:
sumDays += 31;
case 3:
if((year % 4 == 0 && year%100 != 0) ||year % 400==0{
sumDay=29;
}
else{sumDay=28;
}
case 2: sumDay=31;
case 1: sumDay+=day;
}
System.out.println("2019年"+mouth+"月"+day+"日是当年的第"+sumDay+"天");
}
}
3)do-while循环至少执行一次循环体
特殊流程控制语句说明
break只能用于switch语句和循环语句中。
continue 只能用于循环语句中。
二者功能类似,但continue是终止本次循环,break是终止本层循环。
break、continue之后不能有其他的语句,因为程序永远不会执行其后的语句。
标号语句必须紧接在循环的头部。标号语句不能用在非循环语句的前面。 很多语言都有goto语句,goto语句可以随意将控制转移到程序中的任意一条
语句上,然后执行它。但使程序容易出错。Java中的break和continue是不同
于goto的。
循环语句综合例题
题目:
从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入
为0时结束程序。
import java.util.Scanner;
class ForWhileTest{
public static void main(String[] args) {
Scanner scan =new Scanner(System.in);
int pNumber=0;//记录正数的个数
int nNumber=0;
while(ture){
int number=scan.nextInt();
if(number > 0){
pNumber++;
}else if(number <0){
nNumber++;
}else{
break;
}
}
System.out.println("zhengshu:"+pNumber+";fushu:"+nNumber);
}
}
打印如下的图形:菱形1
/*
----*
* *
* * *
* * * *
* * * * *
* * * *
* * *
* *
*
*/
// 上半部分
for (int i = 0; i < 5; i++) {
// 输出“-”
for (int j = 0; j < 4 - i; j++) {
System.out.print(" ");
}
// 输出“* ”
for (int k = 0; k < i + 1; k++) {
System.out.print("* ");
}
System.out.println();
}
// 下半部分
for (int i = 0; i < 4; i++) {
for (int j = 0; j < i + 1; j++) {
System.out.print(" ");
}
for (int k = 0; k < 4 - i; k++) {
System.out.print("* ");
}
System.out.println();
}
100以内质数,最小质数是2
class PrimeNumberTest{
public static void main (String[] args){
boolean isFlag = true;
for(int i=2;i<=100;i++){
for(int j=2;j<i;j++){
if(i%j==0){
isFlag= false;
}
}
if(isFlag == ture){
System.out.println(i);
}
}
}
}
dos命令
C:\Users\谢思琪>d:
D:\>cd D:\learning\java\code
D:\learning\java\code>javac HelloWorld.java
D:\learning\java\code>java HelloWorld
Hello,World!
项目一
import java.util.Scanner;
/**
Utility工具类:
将不同的功能封装为方法,就是可以直接通过调用方法使用它的功能,而无需考虑具体的功能实现细节。
*/
public class Utility {
private static Scanner scanner = new Scanner(System.in);
/**
用于界面菜单的选择。该方法读取键盘,如果用户键入’1’-’4’中的任意字符,则方法返回。返回值为用户键入字符。
*/
public static char readMenuSelection() {
char c;
for (; ; ) {
String str = readKeyBoard(1);
c = str.charAt(0);
if (c != '1' && c != '2' && c != '3' && c != '4') {
System.out.print("选择错误,请重新输入:");
} else break;
}
return c;
}
/**
用于收入和支出金额的输入。该方法从键盘读取一个不超过4位长度的整数,并将其作为方法的返回值。
*/
public static int readNumber() {
int n;
for (; ; ) {
String str = readKeyBoard(4); //键盘读取一个不超过4位长度的整数
try {
n = Integer.parseInt(str);
break;
} catch (NumberFormatException e) { //输入必须是数字
System.out.print("数字输入错误,请重新输入:");
}
}
return n;
}
/**
用于收入和支出说明的输入。该方法从键盘读取一个不超过8位长度的字符串,并将其作为方法的返回值。
*/
public static String readString() {
String str = readKeyBoard(8);
return str;
}
/**
用于确认选择的输入。该方法从键盘读取‘Y’或’N’,并将其作为方法的返回值。
*/
public static char readConfirmSelection() {
char c;
for (; ; ) {
String str = readKeyBoard(1).toUpperCase();
c = str.charAt(0);
if (c == 'Y' || c == 'N') {
break;
} else {
System.out.print("选择错误,请重新输入:");
}
}
return c;
}
private static String readKeyBoard(int limit) {
String line = "";
while (scanner.hasNext()) {
line = scanner.nextLine();
if (line.length() < 1 || line.length() > limit) {
System.out.print("输入长度(不大于" + limit + ")错误,请重新输入:");
continue;
}
break;
}
return line;
}
}
第三章 数组
1、Java中使用关键字new来创建数组
2、二维数组
格式一:int[ ][ ] arr= new int[3][ ]
格式二(动态初始化):int[][] arr = new int[3][2];
注:
int[][]ar1 = new int[][3]; //非法
格式3(静态初始化):int[][] arr1 = new int[][]{{3,8,2},{2,7},{9,0,1,6}};
获取数组长度
System.out.println(arr1.length);//行数,3
System.out.println(arr1[0].length);//3
System.out.println(arr1[1].length);//2
int[][] arr= new int [4] [3];
System.out.println(arr[0]);//输出地址值 0
String[][] arr2 = new String[4][2];
System.out.println(arr2[1]);//地址值
System.out.println(arr2[1][1]);//null
System.out.println("*****************");
double[][] arr3 = new double[4][];
System.out.println(arr3[1]);//null
// System.out.println(arr3[1][0]);//报错
- ⑤ 数组元素的默认初始化值
- 针对于初始化方式一:比如:int[][] arr = new int[4][3];
外层元素的初始化值为:地址值
内层元素的初始化值为:与一维数组初始化情况相同
- 针对于初始化方式二:比如:int[][] arr = new int[4][];
外层元素的初始化值为:null
内层元素的初始化值为:不能调用,否则报错。
多位数组练习2
int[][] arr =new int[][]{{3,4,5},{12,9},{7,0,6,4}};
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
}
}
System.out.println(""+);
练习3
int[] x, y[];//y是int型二维数组
y[0]=x;//yes,一维数组
y[0][0]=x[0];//值对应值
笔试题
创建一个长度为6的int型数组,要求数组元素的值都在1-30之间,且是随机赋值。同时,要求
元素的值各不相同。
1.赋值,2.遍历判断是否一样
class ArrayExer {
public static void main(String[] args) {
//方式一:
// int[] arr = new int[6];
// for (int i = 0; i < arr.length; i++) {// [0,1) [0,30) [1,31)
// arr[i] = (int) (Math.random() * 30) + 1;
//
// boolean flag = false;
// while (true) {
// for (int j = 0; j < i; j++) {
// if (arr[i] == arr[j]) {
// flag = true;
// break;
// }
// }
// if (flag) {
// arr[i] = (int) (Math.random() * 30) + 1;
// flag = false;
// continue;
// }
// break;
// }
// }
//
// for (int i = 0; i < arr.length; i++) {
// System.out.println(arr[i]);
// }
//方式二:
int[] arr = new int[6];
for (int i = 0; i < arr.length; i++) {// [0,1) [0,30) [1,31)
arr[i] = (int) (Math.random() * 30) + 1;
for (int j = 0; j < i; j++) {
if (arr[i] == arr[j]) {
i--;
break;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
数组中涉及的常见算法
- 数组元素的赋值(杨辉三角、回形数等)
- 求数值型数组中元素的最大值、最小值、平均数、总和等
- 数组的复制、反转、查找(线性查找、二分法查找)
- 数组元素的排序算法
回型数leetcode原题,算法题碰到原题概率不大
回形数格式方阵的实现
从键盘输入一个整数(1~20)
则以该数字为矩阵的大小,把1,2,3…n*n 的数字按照顺时针螺旋的形式填入其中。例如: 输入数字2,则程序输出: 1 2
4 3
输入数字3,则程序输出: 1 2 3
8 9 4
7 6 5
输入数字4, 则程序输出:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
class RectangleTest1 {
public static void main(String[] args) {
int n = 7;
int[][] arr = new int[n][n];
int count = 0; // 要显示的数据
int maxX = n - 1; // x轴的最大下标
int maxY = n - 1; // Y轴的最大下标
int minX = 0; // x轴的最小下标
int minY = 0; // Y轴的最小下标
while (minX <= maxX) {
for (int x = minX; x <= maxX; x++) {
arr[minY][x] = ++count;
}
minY++;
for (int y = minY; y <= maxY; y++) {
arr[y][maxX] = ++count;
}
maxX--;
for (int x = maxX; x >= minX; x--) {
arr[maxY][x] = ++count;
}
maxY--;
for (int y = maxY; y >= minY; y--) {
arr[y][minX] = ++count;
}
minX++;
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
String space = (arr[i][j] + "").length() == 1 ? "0" : "";
System.out.print(space + arr[i][j] + " ");
}
System.out.println();
}
}
}
随机生成数
- Math.random():[0.0,1)
- Math.random()*90 : [0.0,90.0)
- (int)(Math.random()*90) :[0,89]
- (int)(Math.random()*90+10) :[10,99]
公式 获取[a,b]之间的随机整数 : (int)(Math.random()(b-a+1)+a)
1、随机生成1-30之间:(int)(Math.random()*30+1)
数组的复制、反转、查找(线性查找、二分法查找)
stringbuff字符串反转
//查找
//线性查找
String[] arr= new String[]{"JJ",BB","MM"};
String dest = "BB";
boolean isFlag =true;
for(int i=0; i< arr.length;i++){
if(dest.equals(arr[i])){ //equals,比较内容
System.out.println("找到,位置为"+i);
isFlag =false;
break;
}
}
if(isFlag){
System.out.println("null");
}
}
//二分法查找
//前提:所要查找的数组必须有序。
int[] arr2 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
int dest1 = -34;
int head = 0;//初始的首索引
int end = arr2.length - 1;//初始的末索引
boolean isFlag1 = true;
while(head <= end){
int middle = (head + end)/2;
if(dest1 == arr2[middle]){
System.out.println("找到了指定的元素,位置为:" + middle);
isFlag1 = false;
break;
}else if(arr2[middle] > dest1){
end = middle - 1;
}else{//arr2[middle] < dest1
head = middle + 1;
}
}
if(isFlag1){
System.out.println("很遗憾,没有找到的啦!");
}
}
}
排序算法
*选择排序
直接选择排序、堆排序
*交换排序
冒泡排序、快速排序(要求会手写,笔试面试前复习下)
- 插入排序
直接插入排序、折半插入排序(面试不会问),Shell排序
*归并排序 - 桶式排序
- 基数排序
面试问:1、 排序有哪些?(冒泡排序、快速排序,Shell排序,堆排序)
2、归并排序、堆排序(平均时间复杂度低)怎么实现,基本思想
3、快速排序的时间复杂度为O(nlog(n)),冒泡O(n^2)
冒泡排序
冒泡排序
介绍:
冒泡排序的原理非常简单,它重复地走访过要排序的数列,一次比较两个元
素,如果他们的顺序错误就把他们交换过来。
排序思想:
- 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步
做完后,最后的元素会是最大的数。 - 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要
比较为止。
- 从小到大排,比较相邻两个大小,每趟最大放最后面
n个数,循环n-1次,每躺len-1-i
int[] arr =new int[]{45,2,4,3,5,0};
for(int i = 0;i < arr.length - 1 ;i++){//i < arr.length 也可
for(int j = 0;j < arr.length - 1 - i;j++){ // arr.length - 1不能少会超过数组个数
if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
for(int i = 0;i < arr.length ;i++){
System.out.print(arr[i]);
}
快速排序
介绍:
快速排序通常明显比同为O(nlogn)的其他算法更快,因此常被采用,而且快排采用了分治法的思想,所以在很多笔试面试中能经常看到快排的影子,快速排序(Quick Sort)由图灵奖获得者Tony Hoare发明,被列为20世纪十大算法之一,是迄今为止所有内排序算法中速度最快的一种。冒泡排序的升级版,交换排序的一种。快速排序的时间复杂度为O(nlog(n))。
排序思想:
- 从数列中挑出一个元素,称为"基准"(pivot),
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
- 递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代iteration)中,它至少会把一个元素摆到它最后的位置去。
关键:将第一个作为基准,比基准值小的摆放在基准前面,比基准
值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,
该基准就处于数列的中间位置。两边子数组重复递推。
package com.atguigu.array.sort;
/**
* 快速排序
* 通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,
* 则分别对这两部分继续进行排序,直到整个序列有序。
*/
public class QuickSort {
private static void swap(int[] data, int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
private static void subSort(int[] data, int start, int end) {
if (start < end) {
int base = data[start];
int low = start;
int high = end + 1;
while (true) {
while (low < end && data[++low] - base <= 0)
;
while (high > start && data[--high] - base >= 0)
;
if (low < high) {
swap(data, low, high);
} else {
break;
}
}
swap(data, start, high);
subSort(data, start, high - 1);//递归调用
subSort(data, high + 1, end);
}
}
public static void quickSort(int[] data){
subSort(data,0,data.length-1);
}
public static void main(String[] args) {
int[] data = { 9, -16, 30, 23, -30, -49, 25, 21, 30 };
System.out.println("排序之前:\n" + java.util.Arrays.toString(data));
quickSort(data);
System.out.println("排序之后:\n" + java.util.Arrays.toString(data));
}
}
Arrays工具类
1.理解:
① 定义在java.util包下。
② Arrays:提供了很多操作数组的方法。
2.使用:
//1.boolean equals(int[] a,int[] b):判断两个数组是否相等。
int[] arr1 = new int[]{1,2,3,4};
int[] arr2 = new int[]{1,3,2,4};
boolean isEquals = Arrays.equals(arr1, arr2);
System.out.println(isEquals);
//2.String toString(int[] a):输出数组信息。
System.out.println(Arrays.toString(arr1));//Arrays.toString(arr1)遍历数组
//3.void fill(int[] a,int val):将指定值填充到数组之中。
Arrays.fill(arr1,10); // arr1={10,10,10,10,10}
System.out.println(Arrays.toString(arr1));
//4.void sort(int[] a):对数组进行排序。
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));
//5.int binarySearch(int[] a,int key) //二分查找
int[] arr3 = new int[]{-98,-34,2,34,54,66,79,105,210,333};//必须是有序数组
int index = Arrays.binarySearch(arr3, 210);
if(index >= 0){
System.out.println(index);
}else{
System.out.println("未找到");
}
报错
1、数组脚标越界异常(ArrayIndexOutOfBoundsException)
访问到了数组中的不存在的脚标时发生。
2、空指针异常(NullPointerException)
int[] arr = null;
System.out.println(arr[0]);
arr引用没有指向实体,却在操作实体中的元素时。