我们可以使用数组保存多个数据
比如我们这个教室,坐着的都是大数据14期的学生,这个教室就相当于数组,我们就是数组中的元素
但是隔壁还有一个前端07期,里面都是07期的学生,
这两个教室都在1808,如果把07和14当成数组的话,1808就是二维数组
二维数组本质 就是一个平面数据结构(表)
二维数组中的元素都是一维数组
接收控制台输入
public class Array_03 {
public static void main(String[] args) {
// 创建一个接收器
Scanner sc = new Scanner(System.in);
// 程序执行到这里的时候就不执行了
// 等待用户输入 并敲回车结束
// next : 读取一个数据 多个数据使用 空格隔开
// String userInput = sc.next();
// 读取一行数据
// String userInput = sc.nextLine();
// 接收int值 nextInt : 分隔符是空格,只接收一个数据
// 必须是纯数字才可以,小数点也不能有
// int userInput = sc.nextInt();
// 读取小数,同上,只是可以有小数点
double userInput = sc.nextDouble();
System.out.println(userInput);
}
}
使用Scanner 完成计算器功能
只需要实现 加减乘除取余即可
只需要考虑两个数 比如 1+2 或者 3*2 这种
思路 :
根据题目得知,我们需要接收三个参数 , 比如 1+2 需要把 1 和 + 和 2 都获取
import java.util.Scanner;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
/**
* 使用Scanner完成计算器功能,只需要实现,加减乘除取余即可 + - * / %
*
* 只需要考虑两个数 比如 1+2 或者 3*2 这种
*
* 思路 : 根据题目得知,我们需要接收三个参数 , 比如 1+2 需要把 1 和 + 和 2 都获取 1 创建接收器Scanner 2 接收 三个参数 3
* 判断第二个参数(运算符) , 如果是 + 就相加,如果是- 就相减... 4 如果是 / 需要判断,除数不能为0
*
* @author lenovo
* @Date 2020年7月1日
* @Time 下午9:25:27
*/
public class Array_04 {
public static void main(String[] args) throws ScriptException {
// TODO Auto-generated method stub
// m1();
test();
}
public static void m1() {
System.out.println("请输入 : n +-*/ m");
// 创建接收器Scanner
Scanner sc = new Scanner(System.in);
// 接收 三个参数
double number1 = sc.nextDouble();
String number2 = sc.next();
double number3 = sc.nextDouble();
switch (number2) {
case "+":
System.out.println(number1 + number3);
break;
case "-":
System.out.println(number1 - number3);
break;
case "*":
System.out.println(number1 * number3);
break;
case "/":
// 如果是 / 需要判断,除数不能为0
if (number3 == 0) {
System.out.println("除数不能为0");
return;
}
System.out.println(number1 / number3);
break;
case "%":
System.out.println(number1 % number3);
break;
default:
System.out.println("暂不支持该运算符");
break;
}
}
public static void test() throws ScriptException {
// JDK自带的类可以实现调用JS的功能,可以实现执行字符串中的运算公式
ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
// 接收控制台输入
Scanner sc = new Scanner(System.in);
// 读取一行数据
String strs = sc.nextLine();
// 运算结果
int result = (int) jse.eval(strs);
System.out.println(result);
}
}
交换两个变量的值
public class Array_05 {
public static void main(String[] args) {
/**
* 第一种 : 中间变量(开发常用)
*/
int x = 10;
int y = 20;
int temp = x;
x = y;
y = temp;
System.out.println("x=" + x);
System.out.println("y=" + y);
/**
* 第二种 : 位移运算交换(面试常用)
*
* 先把a和b转换为对应的二进制,然后 用 a和b的每一位二进制 进行比较,如果相等,就是0,不一样就是 1
*/
int a = 2;
int b = 3;
b = a ^ b;
a = a ^ b;
b = a ^ b;
System.out.println("a=" + a);
System.out.println("b=" + b);
/**
* 3 加和运算
*/
int c = 10;
int d = 20;
c = c + d;
d = c - d;
c = c - d;
}
}
很多情况下都需要对数据的大小进行排序,比如统计成绩,查询前三名
就需要按照成绩进行降序,然后取 0,1,2即可
实现 :
public class Array_06 {
public static void main(String[] args) {
int[] a = { 3, 2, 4, 5, 1 };
bubbleSort(a);
for (int i : a) {
System.out.println(i);
}
// 1 2 3 4 5
}
public static void bubbleSort(int[] a) {
// 外层循环决定循环次数(共比较几轮)
for (int i = 0; i < a.length - 1; i++) {
// 内层循环决定每一次循环的循环次数
for (int j = 0; j < a.length - 1 - i; j++) {
// 如果是降序 就换成 < 即可
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}
}
实现 :
public class Array_07 {
public static void main(String[] args) {
int[] arr = { 1, 3, 4, 5, 2 };
selectSort(arr);
// m1(arr);
for (int i : arr) {
System.out.println(i);
}
}
public static void m1(int[] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
if (arr[i] > arr[j]) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}
public static void selectSort(int[] arr) {
// 从小到大排序
for (int i = 0; i < arr.length - 1; i++) {
// 最小元素的下标,默认是第一个元素
int min = i;
for (int j = i + 1; j < arr.length; j++) {
// 如果 min 大于 j 说明 i 不是最小的元素
// 就交换下标
if (arr[min] > arr[j]) {
min = j;
}
}
// 如果min不等于 i 说明最小值不是 i 需要换位
if (min != i) {
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
}
}
当数据过大的时候,想要查找某个数据,并不是一件容易的事,尤其是我们要找的数据可能在最后几条,如果依次比较数据,效率太低
算法实现 :
- 确定数据的开始位置和结束位置
- 确定数据的中间位置,判断中间位置元素是否是目标数据,如果是,就直接返回中间数据对应的下标
3.如果不是,分为两种
- 目标数据大于中间数据 起始值 = 中间值 + 1 , 结束值不变
- 目标数据小于中间数据
结束值 = 中间值 -1 , 起始值不变
更改起始值或结束值之后,必须重新计算中间值
终止条件 : 当起始值大于结束值的时候,说明没有这个目标数据
public class Array_08 {
public static void main(String[] args) {
// int[] arr = { 1, 3, 4, 5, 6, 7, 9, 15, 17, 19, 38, 41, 52, 63, 73, 78 };
int[] arr = new int[21111111];
for (int i = 0; i < arr.length; i++) {
arr[i] = i;
}
int num = 20011112;
long startTime = System.currentTimeMillis();
int index = search(arr, num);
System.out.println(num + " 在arr数组的第 : " + index + " 位上,执行了 " + count_1 + " 次");
long endTime = System.currentTimeMillis();
System.out.println("传统查找使用 : " + (endTime - startTime) + " 毫秒");
startTime = System.currentTimeMillis();
index = binarySearch(arr, num);
System.out.println(num + " 在arr数组的第 : " + index + " 位上,执行了 " + count_2 + " 次");
endTime = System.currentTimeMillis();
System.out.println("二分法查找使用 : " + (endTime - startTime) + " 毫秒");
}
// 传统查询次数
static int count_1 = 0;
// 二分法查询次数
static int count_2 = 0;
/**
* 传统写法
*
* @param arr
* @param num
* @return
*/
public static int search(int[] arr, int num) {
for (int i = 0; i < arr.length; i++) {
count_1++;
if (arr[i] == num) {
return i;
}
}
// 能到这里说明没有找到,返回 -1
return -1;
}
/**
* 二分法查询
*
* @param arr
* @param num
* @return
*/
public static int binarySearch(int[] arr, int num) {
if (arr == null || arr.length == 0) {
return -1;
}
// 1 确定数据的开始位置和结束位置
int startPos = 0;
int endPos = arr.length - 1;
// 2 确定数据的中间位置,判断中间位置元素是否是目标数据,如果是,就直接返回中间数据对应的下标
int m = (startPos + endPos) / 2;
// 终止条件 : 当起始值大于结束值的时候,说明没有这个目标数据
while (startPos <= endPos) {
count_2++;
if (num == arr[m]) {
return m;
}
// 3 如果不是,分为两种
// 1 目标数据大于中间数据
// 起始值 = 中间值 + 1 , 结束值不变
if (num > arr[m]) {
startPos = m + 1;
}
// 2 目标数据小于中间数据
// 结束值 = 中间值 - 1 , 起始值不变
if (num < arr[m]) {
endPos = m - 1;
}
m = (startPos + endPos) / 2;
}
// 能到这里 说明没有找到,直接返回-1
return -1;
}
}