一. 算法

什么是算法?

        解决某个实际问题的过程和方法

学习算法的技巧?

        先搞清楚算法的流程,再直接去推敲如何写算法

1.1 排序算法

1.1.1 冒泡排序

        每次从数组中找出最大值放在数组的后面去

public class demo {

public static void main(String[] args) {

int[] arr = {5,2,3,1};

//升序排序【1,2,3,5】

//外循环控制排序轮数,内循环控制每一轮的遍历

//n个数需要排序n-1轮

for (int i = 0; i < arr.length - 1; i++) {

//每一轮的目标是找到最大值,并放在最后一个位置

//n个数 第一轮需要比较n-1次,第二轮需要比较n-2次 …… 第n-1轮需要比较1次

for (int j = 0; j < arr.length - i - 1; j++) {

//如果前一个数大于后一个数,则进行交换

if(arr[j] > arr[j+1]){

int temp;

temp = arr[j];

arr[j] = arr[j+1];

arr[j+1] = temp;

}

}

}

System.out.println(Arrays.toString(arr));

}

}

1.1.2 选择排序

        每次选择当前位置,开始找出后面的较小值与该位置交换

public class demo {

public static void main(String[] args) {

int[] arr = {5,1,3,2};

//升序排序【1,2,3,5】

selectionSort(arr);

selectionSort1(arr);

}

//普通选择排序

private static void selectionSort(int[] arr) {

//外循环控制排序轮数,内循环控制每一轮的遍历

//n个数需要排序n-1轮

for (int i = 0; i < arr.length - 1; i++) {

//每一轮的目标是确定当前位置的值(确定arr[i]的值)

//j依次记录当前位置后面位置的值(要记录到最后一个位置)

//如第一轮确定arr[0]的值,j应该从位置1到位置n-1(一共n个数)

for (int j = i + 1 ; j < arr.length; j++) {

//如果当前位置的值大于后面的值,就进行交换

if(arr[i] > arr[j]){

int temp;

temp = arr[i];

arr[i] = arr[j];

arr[j] = temp;

}

}

}

System.out.println(Arrays.toString(arr));

}

//改进选择排序

//减少交换次数,每一轮确定后面位置的最小值,再进行排序,这样每轮最多只需要交换一次

private static void selectionSort1(int[] arr) {

//n个数需要排序n-1轮

for (int i = 0; i < arr.length - 1; i++) {

//每一轮的目标是确定当前位置的值(确定arr[i]的值)

//j依次记录当前位置后面位置的值(要记录到最后一个位置)

//每轮确定后面位置的最小值再进行交换,用一个变量记录最小值位置的索引

int minIndex = i;

for (int j = i + 1 ; j < arr.length; j++) {

//用minIndex记录这一轮的最小值

if(arr[minIndex] > arr[j]){

minIndex = j;

}

}

//该轮最小值不是arr[i],则和最小值交换位置

if(minIndex != i){

int temp;

temp = arr[minIndex];

arr[minIndex] = arr[i];

arr[i] = temp;

}

}

System.out.println(Arrays.toString(arr));

}

}

1.2 查找算法

1.2.1 顺序查找(基本查找)

注意:再数据量特别大的时候,基本查找这种从前往后挨个找的形式,性能是很差的

1.2.2 二分查找(折半查找)

        前提条件:数组中的数据必须是有序的

        核心思想:每次排除一半的数据,查询数据的性能明显提高很多

        折半条件:二分查找正常的折半条件应该是开始位置left<=结束位置right

public class demo {

public static void main(String[] args) {

int[] arr = {7,23,79,81,103,127,131,147};

int index = binarySearch(arr,81);

if(index != arr.length){

System.out.println("您要找的数据在数组的索引值是"+index);

}

//Java中Arrays类提供了二分查找的方法

System.out.println(Arrays.binarySearch(arr, 131));

}

public static int binarySearch(int[] arr,int data){

//定义两个变量记录左右两端的位置

int left = 0;

int right = arr.length - 1;

//定义一个循环

while(left <= right){

int mid = (left + right) / 2;

if(arr[mid] == data){

return mid;

}else if(arr[mid] > data){

right = mid - 1;

}else{

left = mid + 1;

}

}

//循环结束,还没有找到,才会执行到这里

System.out.println("未查找到"+data);

return -1;

}

}

二. 正则表达式

2.1 认识正则表达式 

        就是由一些特定的字符组成,代表的是一个规则

        正则表达式作用一:用来校验数据格式是否合法

        正则表达式作用二:在一段文本中查找满足要求的内容

public class demo {

public static void main(String[] args) {

//校验QQ号码是否正确,要求全部都是数字,长度在(6-20)之间,不能用0开头

System.out.println(checkQQ(null)); //为空返回false

System.out.println(checkQQ("12345")); //长度不在6-20之间返回false

System.out.println(checkQQ("012345")); //0开头返回false

System.out.println(checkQQ("12345678abc")); //不都是数字返回false

System.out.println(checkQQ("12345678")); //true

System.out.println("===============================");

//正则表达式校验

System.out.println(checkQQ1(null)); //为空返回false

System.out.println(checkQQ1("12345")); //长度不在6-20之间返回false

System.out.println(checkQQ1("012345")); //0开头返回false

System.out.println(checkQQ1("12345678abc")); //不都是数字返回false

System.out.println(checkQQ1("12345678")); //true

}

//运用正则表达式

//String提供了一个匹配正则表达式的方法

//public boolean matches(String regex) 判断字符串是否匹配正则表达式,匹配返回true,不匹配返回false

private static boolean checkQQ1(String s) {

return s!=null && s.matches("[1-9]\\d{5,19}");

}

//不运用正则表达式

private static boolean checkQQ(String s) {

if(s==null || s.startsWith("0") || s.length()<6 || s.length()>20){

return false;

}

//执行到这里,说明不为空且开头不为0,长度在6-20之间

//接下来要判断都是数字

for (int i = 0; i < s.length(); i++) {

//根据索引i提取当前位置的字符

char c = s.charAt(i);

if(c < '0' || c > '9'){

return false;

}

}

//执行到这里,说明都是数字

return true;

}

}

2.2 书写规则

public class demo {

public static void main(String[] args) {

// 1、字符类(只能匹配单个字符)

System.out.println("a".matches("[abc]")); // [abc]只能匹配a、b、c

System.out.println("e".matches("[abcd]")); // false

System.out.println("d".matches("[^abc]")); // [^abc] 不能是abc

System.out.println("a".matches("[^abc]")); // false

System.out.println("b".matches("[a-zA-Z]")); // [a-zA-Z] 只能是a-z A-Z的字符

System.out.println("2".matches("[a-zA-Z]")); // false

System.out.println("k".matches("[a-z&&[^bc]]")); // : a到z,除了b和c

System.out.println("b".matches("[a-z&&[^bc]]")); // false

System.out.println("ab".matches("[a-zA-Z0-9]")); // false 注意:以上带 [内容] 的规则都只能用于匹配单个字符

// 2、预定义字符(只能匹配单个字符) . \d \D \s \S \w \W

System.out.println("徐".matches(".")); // .可以匹配任意字符(只能匹配单个)

System.out.println("徐徐".matches(".")); // false

//在Java中\是有特殊用途的,例如特殊字符 \n \t,因此希望是\的时候需要用\\

// \转义

System.out.println("\""); //输出"

// \n \t

System.out.println("3".matches("\\d")); // \d: 代表0-9

System.out.println("a".matches("\\d")); //false

System.out.println(" ".matches("\\s")); // \s: 代表一个空白字符

System.out.println("a".matches("\\s")); // false

System.out.println("a".matches("\\S")); // \S: 代表一个非空白字符

System.out.println(" ".matches("\\S")); // false

System.out.println("a".matches("\\w")); // \w: [a-zA-Z_0-9]

System.out.println("_".matches("\\w")); // true

System.out.println("1".matches("\\w")); //true

System.out.println("徐".matches("\\w")); // false

System.out.println("徐".matches("\\W")); // [^\w]不能是a-zA-Z_0-9

System.out.println("a".matches("\\W")); // false

System.out.println("23232".matches("\\d")); // false 注意:以上预定义字符都只能匹配单个字符。

// 3、数量词: ? * + {n} {n, } {n, m}

System.out.println("a".matches("\\w?")); // ? 代表0次或1次

System.out.println("".matches("\\w?")); // true

System.out.println("abc".matches("\\w?")); // false

System.out.println("abc12".matches("\\w*")); // * 代表0次或多次

System.out.println("".matches("\\w*")); // true

System.out.println("abc12张".matches("\\w*")); // false(\w不能匹配中文)

System.out.println("abc12".matches("\\w+")); // + 代表1次或多次

System.out.println("".matches("\\w+")); // false(+ 代表1次或多次,不能是0次)

System.out.println("abc12张".matches("\\w+")); // false(\w不能匹配中文)

System.out.println("a3c".matches("\\w{3}")); // {3} 代表要正好是n次

System.out.println("abcd".matches("\\w{3}")); // false(大于3次)

System.out.println("abcd".matches("\\w{3,}")); // {3,} 代表是>=3次

System.out.println("ab".matches("\\w{3,}")); // false(小于3次)

System.out.println("abcde徐".matches("\\w{3,}")); // false(\w不能匹配中文)

System.out.println("abc232d".matches("\\w{3,9}")); // {3, 9} 代表是 大于等于3次,小于等于9次

// 4、其他几个常用的符号:(?i)忽略大小写 、 或:| 、 分组:()

System.out.println("abc".matches("(?i)abc")); // true

System.out.println("ABC".matches("(?i)abc")); // true

System.out.println("aBc".matches("a((?i)b)c")); // true

System.out.println("ABc".matches("a((?i)b)c")); // false

// 需求1:要求要么是3个小写字母,要么是3个数字。

System.out.println("abc".matches("[a-z]{3}|\\d{3}")); // true

System.out.println("ABC".matches("[a-z]{3}|\\d{3}")); // false

System.out.println("123".matches("[a-z]{3}|\\d{3}")); // true

System.out.println("A12".matches("[a-z]{3}|\\d{3}")); // false

// 需求2:必须是”我爱“开头,中间可以是至少一个”编程“,最后至少是1个”666“

System.out.println("我爱编程编程666666".matches("我爱(编程)+(666)+")); //true

System.out.println("我爱编程编程66666".matches("我爱(编程)+(666)+")); //false

}

}

 2.3 应用案例

public class demo {

public static void main(String[] args) {

//checkPhone();

//checkEmail();

checkTime();

}

private static void checkPhone() {

while (true) {

System.out.println("请输入您的电话号码(手机|座机):");

Scanner sc = new Scanner(System.in);

String phone = sc.nextLine(); //nextLine()用来接收一行数据

//校验手机号码的正则表达式

if(phone.matches("(1[3-9]\\d{9})|(0\\d{2,3}-?[1-9]\\d{6,7})")){

System.out.println("您输入的电话号码格式正确");

break;

}else{

System.out.println("您输入的电话号码格式不正确");

}

}

}

private static void checkEmail() {

while (true) {

System.out.println("请输入您的邮箱:");

Scanner sc = new Scanner(System.in);

String phone = sc.nextLine(); //nextLine()用来接收一行数据

//校验邮箱的正则表达式

if(phone.matches("\\w{2,}@\\w{2,10}(\\.\\w{2,10}){1,2}")){

System.out.println("您输入的邮箱格式正确");

break;

}else{

System.out.println("您输入的邮箱格式不正确");

}

}

}

private static void checkTime() {

while (true) {

System.out.println("请输入需要校验的时间(xx:xx:xx):");

Scanner sc = new Scanner(System.in);

String phone = sc.nextLine(); //nextLine()用来接收一行数据

//校验邮箱的正则表达式

if(phone.matches("(([0-9])|(1[0-9])|(2[0-3]))\\:[0-5][0-9]\\:[0-5][0-9]")){

System.out.println("您输入的时间格式正确");

break;

}else{

System.out.println("您输入的时间格式不正确");

}

}

}

}

2.4 用于查找信息

public class demo {

public static void main(String[] args) {

//需求:从以下内容中爬取出,手机,邮箱,座机、400电话等信息。

String data = " 来学习Java,\n" +

" 电话:1866668888,18699997777\n" +

" 或者联系邮箱:boniu@qq.com,\n" +

" 座机电话:01036517895,010-98951256\n" +

" 邮箱:bozai@wosun.cn,\n" +

" 邮箱:0_009@163.com,\n" +

" 热线电话:400-618-9090 ,400-618-4000,4006184000,4006189090";

//定义爬取规则

//手机号:1开头,第二位是3-9,剩下9位是0-9

//座机号:

// 区号是0开头,可能是3位或4位。

// -可有可无

// 座机号是7或8位,不能是0开头

//邮箱:必须有@,@前要有两个及以上的字符,@后要有至少2个最多10个字符,最后至少接上一组.和两个以上的字符(如123@123.com)

//热线电话:400开头,后接一组3位数和一组4位数,中间的-可有可无

//正则表达式中不能随意写空格,会导致结果不对

String regex = "(1[3-9]\\d{9})|(0\\d{2,3}-?[1-9]\\d{6,7})|(\\w{2,}@\\w{2,10}(\\.\\w{2,10}){1,2})|(400-?\\d{3}-?\\d{4})";

//把正则表达式封装成一个Pattern对象

Pattern pattern = Pattern.compile(regex);

//通过pattern对象去获取查找内容的匹配器对象

Matcher matcher = pattern.matcher(data);

//定义一个循环开始爬取信息

while(matcher.find()){

String rs = matcher.group(); //获取找到的内容

System.out.println(rs);

}

}

}

 2.5 用于搜索替换、分割内容

        正则表达式用于搜索替换、分割内容,需要结合String提供的如下方法完成

方法名说明public String replaceAll(String regex,String newStr)按照正则表达式匹配的内容进行替换public String[] split(String regex);按照正则表达式匹配的内容进行分割字符串,返回一个字符串数组

public class demo {

public static void main(String[] args) {

//public String replaceAll(String regex,String newStr) 按照正则表达式匹配的内容进行替换

// 需求:请把 古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴,中间的非中文字符替换成 “-”

String s = "古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴";

System.out.println(s.replaceAll("\\w+", "-"));

// 需求:某语音系统,收到一个口吃的人说的“我我我喜欢编编编编编编编编编编编编程程程!”,需要优化成“我喜欢编程!”。

String s2 = "我我我喜欢编编编编编编编编编编编编程程程!";

/**

* (.) :代表一组 .用来匹配任意字符

* \\1 :为这个组声明一个组号:1号 分组引用

* + :声明必须是重复的字

* $1 :可以去取到第1组代表的那个重复的字

*/

System.out.println(s2.replaceAll("(.)\\1+", "$1")); //未接触过的知识

//public String[] split(String regex); 按照正则表达式匹配的内容进行分割字符串,返回一个字符串数组

//需求:请把 古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴,中的人名获取出来。

String s3 = "古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴";

String[] arr = s3.split("\\w+");

System.out.println(Arrays.toString(arr));

}

}

三. 异常

        异常就是代表程序出现的问题

异常的体系

        分为 运行时异常 和 编译时异常

代码层面上的异常处理

        · 抛出异常(throws)

                在方法上使用throws关键字,可以将方法内部出现的异常跑出去给调用者处理

方法 throws 异常1,异常2,异常3…{

        ……

}

        · 捕获异常(try…catch)

                直接捕获程序出现的异常

try{

        //监视可能出现异常的代码

}catch(异常类型1 变量){

        //处理异常

}catch(异常类型2 变量){

        //处理异常

}

public class demo {

public static void main(String[] args) throws ParseException{

//运行时异常(编译阶段不会出现错误提醒)

//Integer.valueOf("abc"); //NumberFormatException

// int[] arr = {1,2,3};

// System.out.println(arr[3]); //ArrayIndexOutOfBoundsException

//编译时异常

//快捷键 ctrl+Alt+T 可以添加try-catch

// try {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

//parse()把字符串时间解析成日期对象

Date d = sdf.parse("2020-11-11 10:24"); //ParseException

System.out.println(d);

// } catch (ParseException e) {

// e.printStackTrace();

// }

}

}

3.1 自定义异常

        Java无法为这个世界上全部的问题都提供异常类来代表,如果企业自己的某种问题,想通过异常来表示,以便用异常来管理该问题,那就需要自己来定义异常类

异常的作用

        · 异常时用来查寻系统bug的关键参考信息

        · 异常可以作为方法内部的一种特殊返回值,以便通知上层调用者底层的执行情况

//demo

public class demo {

public static void main(String[] args){

//需求:保存一个合法的年龄、

//运行时异常

// try {

// //saveAge(23);

// saveAge(160);

// System.out.println("底层执行成功");

// } catch (Exception e) {

// e.printStackTrace();

// System.out.println("底层出现了bug");

// }

//编译时异常

// try {

// saveAge1(256);

// System.out.println("saveAge1底层执行成功");

// } catch (AgeIllegalException e) {

// e.printStackTrace();

// System.out.println("saveAge1底层出现了bug");

// }

}

public static void saveAge1(int age) throws AgeIllegalException{

if(age>0 && age<150){

System.out.println("您输入的年龄"+age+"被成功保存");

}else{

//用一个异常对象来封装这个问题

//throw 抛出去这个异常对象

//throws 用在方法上,抛出方法内部的异常(因为这里是编译时异常,如果方法上不加throws AgeIllegalException底下的一行会标红)

throw new AgeIllegalException("/age is illegal, your age is " + age);

}

}

public static void saveAge(int age){

if(age>0 && age<150){

System.out.println("您输入的年龄"+age+"被成功保存");

}else{

//用一个异常对象来封装这个问题

//throw 抛出去这个异常对象

throw new AgeIllegalRuntimeException("/age is illegal, your age is " + age);

}

}

}

//AgeIllegalException

//要继承Exception,才能成为一个编译时异常类

public class AgeIllegalException extends Exception {

//重写构造器

public AgeIllegalException() {

}

public AgeIllegalException(String message) {

super(message);

}

}

//AgeIllegalRuntimeException

//要继承RuntimeException,才能成为一个运行时异常类

public class AgeIllegalRuntimeException extends RuntimeException {

//重写构造器

public AgeIllegalRuntimeException() {

}

public AgeIllegalRuntimeException(String message) {

super(message);

}

}

3.2 异常的处理

开发中对于异常的常见处理方式一:捕获异常,记录异常并相应合适的信息给用户

//demo

public class demo {

public static void main(String[] args){

try {

test1();

} catch (ParseException e) {

System.out.println("您要解析的时间有问题");

e.printStackTrace(); //打印出异常对象的信息

} catch (FileNotFoundException e) {

System.out.println("您要找的文件不存在");

e.printStackTrace(); //打印出异常对象的信息

}

}

public static void test1() throws ParseException, FileNotFoundException {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

//Date d = sdf.parse("2020-11-11 13:14");

Date d = sdf.parse("2020-11-11 13:14:15");

System.out.println(d);

test2();

}

public static void test2() throws FileNotFoundException {

//读取文件

InputStream is = new FileInputStream("D:/1.jpg");

}

}

//demo1 对demo中的代码进行一些改进

//因为自己写的时候往往不知道抛出异常的名字,因此可以统一抛出Exception

public class demo1 {

public static void main(String[] args){

try {

test1();

} catch (Exception e) {

System.out.println("您当前的操作有问题");

e.printStackTrace(); //打印出异常对象的信息

}

}

public static void test1() throws Exception {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

//Date d = sdf.parse("2020-11-11 13:14");

Date d = sdf.parse("2020-11-11 13:14:15");

System.out.println(d);

test2();

}

public static void test2() throws Exception {

//读取文件

InputStream is = new FileInputStream("D:/1.jpg");

}

}

开发中对于异常的常见处理方式二:捕获异常,尝试重新修复 

//目标:掌握异常的处理方式,捕获异常,尝试修复

public class demo {

public static void main(String[] args){

//需求:调用一个方法,让用户输入一个合适的价格返回为止

//尝试修复

while (true) {

try {

System.out.println(getMoney());

break;

} catch (Exception e) {

System.out.println("请您输入合法的数字!!!");

}

}

}

public static double getMoney(){

Scanner sc = new Scanner(System.in);

while (true) {

System.out.println("请您输入一个合适的价格:");

//这里可能会出现异常,因为用户输入的可能不是数字

double money = sc.nextDouble();

if(money<=0){

System.out.println("您输入的价格有问题,请重新输入");

}else{

return money;

}

}

}

}

好文推荐

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: