其它非java扩展链接类型的知识点放这
其中比较重要的几条
刚需import
import java.util.*;
import java.util.Scanner;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Collections;
import java.util.Random;
import java.lang.Math;
import java.lang.System;
import java.io.*;
input场景
场景一:第一行单个整型数字a,代表第二行有a个数字,第二行的数字以空格(或其它字符)分开,把第二行的数字放进数组里
import java.util.Scanner;
import java.util.Arrays;
import java.lang.System;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);//输入
int a = in.nextInt();
in.nextLine(); // 消除nextInt()留下的换行符
String b=null;
while (in.hasNextLine()) {// 第二行扫描为String b
b = in.nextLine();
}
String[] c=b.trim().split(" ");//.trim()可以去掉,以空格切割b为String[] c
int[] d=new int[a];//用a,在某些场合换成c.length更万能
for(int i=0;i<a;i++){
d[i]=Integer.parseInt(c[i]);//String[] c强制转为int[] d
}
for(int i=0;i<a;i++){
System.out.println(d[i]);//换行输出d
}
}
}
场景二:直接一行以空格(或其它字符)分隔的数字
只需要用c.length换成a,直接看场景一的注释来改
场景三:第一行a代表接下去要扫多少行的数字(或字符串等),后面的a行字符
用while循环,每行先存为一个数组,然后统计里面出现c这个字母出现的频率
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
for (int t = 0; t < a; t++) {
String b = scanner.next(); // 读取每一行内容
char[] charArray = b.toCharArray();//字符串变字符数组
int count = 0;
for (char c : charArray) {
if (c == 'c') {
count++;
}
}
System.out.println(count);
}
}
}
【场景三】注意:(数组改为ArrayList)的“第一行a代表接下去要扫多少行的数字”,说明如果后面跟着的不止a行,也可以输入
只是输入了a+n行,也只循环前a行内容。如果想要行多了或少了直接报错,而不输出任何循环行的答案,就应该使用ArrayList而不是数组,方便无限增加内容,在读取每一行时记录每行的字符计数,并在结束时检查总行数是否等于预期行数,如果不等于则输出错误信息。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int count_line = 0;
List<Integer> row = new ArrayList<>();
while (scanner.hasNext()) {
String b = scanner.next(); // 读取每一行内容
char[] charArray = b.toCharArray(); // 字符串变字符数组
int count = 0;
for (char c : charArray) {
if (c == 'c') {
count++;
}
}
row.add(count);
count_line++;
}
if (count_line == a) {// 如果行数正确,输出List内容
for (int value : row) {
System.out.println(value);
}
} else {
System.out.println("行数不对");
}
}
}
场景四:两行未知且长度不同的、以空格(或其它字符)分隔的数字,扫描进两个数组
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String b = null;//第一行
while (in.hasNextLine()) {
b = in.nextLine();
break;//一行一行地while并break
}
String[] c = b.trim().split(" ");
int a = c.length; // 根据元素的数量确定数组的大小
int[] array1 = new int[a];
for (int i = 0; i < a; i++) {
array1[i] = Integer.parseInt(c[i]);
}
b = null;// 第二行
while (in.hasNextLine()) {
b = in.nextLine();
break;
}
String[] d = b.trim().split(" ");
int[] array2 = new int[d.length];
for (int i = 0; i < d.length; i++) {
array2[i] = Integer.parseInt(d[i]);
}
System.out.println("Array 1:");//换行输出第一个数组
for (int i = 0; i < array1.length; i++) {
System.out.println(array1[i]);
}
System.out.println("Array 2:");//换行输出第二个数组
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i]);
}
}
}
场景五:若干行未知且长度不同的、以空格(或其它字符)分隔的数字
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
List<List<Integer>> numberList = new ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] numbersAsString = line.split("\\s+"); // 分隔数字,这里使用空格分隔
List<Integer> numbers = new ArrayList<>();
for (String num : numbersAsString) {
numbers.add(Integer.parseInt(num));
}
numberList.add(numbers);
}
// 输出ArrayList内容
for (List<Integer> numbers : numberList) {
for (int i = 0; i < numbers.size(); i++) {
System.out.print(numbers.get(i));
if (i < numbers.size() - 1) {
System.out.print(" ");//防止每一行最后多输入一个空格
}
}
System.out.println();
}
}
}
相关Scanner参考
(补充上述的)【Java】输入—Scanner用法(全)
其它场景注意:
从字符串中提取数字
public static void main(String[] args) {
Scanner in = new Scanner(System.in);//输入{1,2.3,4,5,6,7,8},k=3,只想要数字
String input=in.nextLine().replaceAll("[{}\\s|k=]","");
//从标准输入读取一行字符串,并使用replaceAll方法将字符串中的{}、空格、以及"k="替换为空字符串""
//[]:去掉括号内的任意一个字符,[^]是除括号内字符之外的任意一个字符
//这样可以去除输入中的大括号、空格以及"k="
//正则表达式,其中\\s 表示匹配任何空白字符(空格、制表符、换行符等)
//而 | 表示逻辑或的意思,用于在正则表达式中连接两个条件,表示其中之一成立即可
//有时候会有别的,如 \\[ 和 \\]:替换掉方括号 []
//别的正则表达式:\d:任何数字,等价于 [0-9],相反\D:任何非数字;\w:任何字母、数字或下划线字符,等价于 [a-zA-Z0-9_],相反\W;.:匹配除换行符 \n 之外的任意字符
String[] numbers=input.split(",");
int b[]=new int[8];
for(int i=0;i<8;i++){
b[i]=Integer.parseInt(numbers[i]);
}
int a = Integer.parseInt(numbers[8]);
System.out.println(b[7]);
System.out.println(a);
}
防止input出问题try/catch/finally
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
} catch (Exception e) {
System.out.println("Error reading input. Please provide valid input.");
} finally {
scanner.close();
}
}
}
打印数组
public static void printArray(int[] array) {
for (int value : array) {
System.out.print(value + " ");
}
System.out.println();
}
数组、ArrayList(Collection)、HashMap(Map)的声明、访问、添加
更多的方法介绍:Java容器合集
它仨的关系
// 声明和初始化一个整数数组Array
int[] intArray = new int[]{1, 2, 3, 4, 5};
// 访问数组元素
System.out.println("Array element at index 2: " + intArray[2]);
更多Array相关函数看下面的函数七
// 声明和初始化一个整数ArrayList
ArrayList<Integer> intArrayList = new ArrayList<>();
//ArrayList是一个可以存储任意类型的泛型类,通过尖括号<>指定存储的元素类型
// 添加元素到ArrayList
intArrayList.add(1);
intArrayList.add(2);
intArrayList.add(3);
intArrayList.add(4);
intArrayList.add(5);
// 访问ArrayList元素
System.out.println("ArrayList element at index 2: " + intArrayList.get(2));
//关于List的创建,用到ArrayList
List<List<Integer>> ans = new ArrayList<List<Integer>>();
更多Collection相关函数看下面的函数八
// 声明和初始化一个键为String类型、值为Integer类型的HashMap
HashMap<String, Integer> hashMap = new HashMap<>();
// 添加键值对到HashMap
hashMap.put("One", 1);
hashMap.put("Two", 2);
hashMap.put("Three", 3);
// 获取HashMap中的值
int value = hashMap.get("Two");
System.out.println("Value for key 'Two': " + value);
//一个字符串s,统计每个字母出现次数
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
hashMap.put(c, charMap.getOrDefault(c, 0) + 1);
}
还有HashSet,在练习题里
好用的函数
函数一:按几遍大小写切换才输出该字符Character.isUpperCase(c)
private static int calculateKeyPresses(String s) {
int keyPresses = 0;
boolean capsLock = false;
for (char c : s.toCharArray()) {
if (Character.isUpperCase(c) != capsLock) { // 需要按下CapsLock键
//Character.isUpperCase(c)用来判断是否为大写字母
keyPresses++;
capsLock = !capsLock;
}
keyPresses++;// 按下字母键
}
return keyPresses;
}
函数二:Map统计字符串<字符,该字符出现的次数>
import java.util.HashMap;
import java.util.Map;
public class CharacterCount {
public static Map<Character, Integer> countCharacters(String str) {
Map<Character, Integer> targetMap = new HashMap<>();
for (char ch : str.toCharArray()) {
// 如果该字符还没有在 targetMap 中出现过,返回默认值 0;
// 如果该字符已经在 targetMap 中存在,则返回其出现的次数,然后将这个次数加1
targetMap.put(ch, targetMap.getOrDefault(ch, 0) + 1);
}
return targetMap;
}
public static void main(String[] args) {
String str = "hello";
Map<Character, Integer> countMap = countCharacters(str);
System.out.println("字符出现次数:");
for (char ch : countMap.keySet()) {
System.out.println(ch + ": " + countMap.get(ch));
}
}
}
函数三:string int char ArrayList互转
在Java中,你可以使用以下方法进行String、int和char之间的相互转换:
1. String 转 int:
String str = "123";
int intValue = Integer.parseInt(str);
2. int 转 String:
int intValue = 123;
String str1 = Integer.toString(intValue);
String str2 = String.valueOf(intValue);//int转string,两种方法
3. String 转 char/char[]:
String str = "ABC";
char charValue = str.charAt(0);//charValue为A
char[] charArray = str.toCharArray();//charArray为['A','B','C']
4. char/char[] 转 String:
char charValue = 'A';//或为['A','B','C']
String str1 = Character.toString(charValue);
String str2 = String.valueOf(charValue);//char转string,两种方法,同int转string
char[] array = ['A','B','C'];
String strlong = new String(array);//char[]转string,直接转
5. int 转 char:
int intValue = 65; // ASCII码对应的值
char charValue = (char) intValue;
6. char 转 int:
char charValue = 'A';
int intValue = (int) charValue;
7. int[] 转 ArrayList<Integer>
int[] intArray = {1, 2, 3, 4, 5}; // 假设这是你的整数数组
ArrayList<Integer> arrayList = new ArrayList<>();
for (int value : intArray) {
arrayList.add(value); // 将整数数组的每个元素添加到 ArrayList 中
}
8. ArrayList<Integer> 转 int[]
ArrayList<Integer> arrayList = new ArrayList<>();
// 假设这是你的 ArrayList
int[] intArray = new int[arrayList.size()];
for (int i = 0; i < arrayList.size(); i++) {
intArray[i] = arrayList.get(i); // 将 ArrayList 中的每个元素取出并存入 int 数组
}
9. String 转 ArrayList<Character>
String str = "Hello";
ArrayList<Character> charList = new ArrayList<>();
for (char c : str.toCharArray()) {
charList.add(c);
}
10. ArrayList<Character> 转 String
ArrayList<Character> charList = new ArrayList<>();
charList.add('H');
charList.add('e');
charList.add('l');
charList.add('l');
charList.add('o');
StringBuilder sb = new StringBuilder(charList.size());
for (Character c : charList) {
sb.append(c);
}
String str = sb.toString();
需要注意的是,在进行类型转换时,要确保数据的合法性,否则可能会引发异常。例如,对于Integer.parseInt,如果字符串不是有效的整数格式,会抛出 NumberFormatException。在实际应用中,通常需要加入一些逻辑来处理异常情况。
函数四:输入几行时间判断是否在指定范围内
// 输入时间范围
System.out.print("输入开始时间(yyyy-MM-dd HH:mm:ss):");
String startTimeStr = scanner.nextLine();
System.out.print("输入结束时间(yyyy-MM-dd HH:mm:ss):");
String endTimeStr = scanner.nextLine();
// 将输入的时间字符串转换为LocalDateTime对象
LocalDateTime startTime = LocalDateTime.parse(startTimeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime endTime = LocalDateTime.parse(endTimeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// 读取多行文本
System.out.println("输入文本(每行包括年月日时间分钟秒数):");
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
// 提取文本中的时间字符串
String timeStr = line.split(" ")[0]; // 假设时间位于每行的开头
// 将时间字符串转换为LocalDateTime对象
LocalDateTime lineTime = LocalDateTime.parse(timeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// 判断时间是否在指定范围内
if (lineTime.isAfter(startTime) && lineTime.isBefore(endTime)) {
System.out.println("在指定时间范围内的行:" + line);
}
}
函数五:Math类的作用
基本数学运算:
Math.abs(double a): 返回参数的绝对值。
Math.ceil(double a): 返回不小于参数的最小整数。
Math.floor(double a): 返回不大于参数的最大整数。
Math.round(float a): 返回最接近参数的整数,四舍五入。
指数和对数:
Math.exp(double a): 返回e的a次方。
Math.log(double a): 返回参数的自然对数。
Math.pow(double a, double b): 返回a的b次方。
三角函数:
Math.sin(double a): 返回角度a的正弦值。
Math.cos(double a): 返回角度a的余弦值。
Math.tan(double a): 返回角度a的正切值。
取整和舍入:
Math.max(double a, double b): 返回两个参数中较大的一个。
Math.min(double a, double b): 返回两个参数中较小的一个。
Math.random(): 返回[0,1)范围内的随机数。
平方根和次方根:
Math.sqrt(double a): 返回参数的平方根。
Math.cbrt(double a): 返回参数的立方根。
函数六:拼接字符串StringBuffer
用StringBuffer:
StringBuffer a = new StringBuffer("Hello"); // 创建
a.append("World");// 追加
a.insert(6, "Good "); // 在索引6的位置插入字符串
a.delete(6, 11); // 删除索引6到索引10的字符
a.replace(0, 5, "Hola"); // 用"Hola"替换索引0到索引4的字符
a.reverse();// 反转字符
int length = a.length(); // 获取字符串长度
int capacity = a.capacity(); // 获取字符串容量
System.out.println(a.toString()); // 输出
函数七:数组Arrays.函数
Arrays.sort
对数字数组排序
int[] nums=[1,3,2];
Arrays.sort(nums);
对字符数组排序
str="1435";
char[] arrayStr = str.toCharArray();
Arrays.sort(arrayStr);
根据二维数组第一个元素排序
int[][] intervals=[[1,3],[2,6],[8,10],[15,18]];
Arrays.sort(intervals, new Comparator<int[]>() {
public int compare(int[] interval1, int[] interval2) {
return interval1[0] - interval2[0];
}
});
上述第三种情况:在 Arrays.sort() 方法中,通过传入一个 Comparator 对象来定义排序规则。Comparator 接口是一个函数式接口,其中的 compare() 方法用于比较两个对象的顺序。在这里,我们创建了一个匿名内部类实现 Comparator 接口,重写了 compare() 方法,定义了按照区间起始点升序排序的规则。
具体来说,compare() 方法中的返回值表示比较结果:
如果返回值小于 0,则表示第一个元素比第二个元素小,将第一个元素排在第二个元素之前;
如果返回值等于 0,则表示两个元素相等,位置不变;
如果返回值大于 0,则表示第一个元素比第二个元素大,将第一个元素排在第二个元素之后。
因此,interval1[0] - interval2[0] 的结果为负值时,表示 interval1 的起始点小于 interval2 的起始点,interval1 应该排在 interval2 之前。
Arrays.copyOfRange
Arrays.copyOf()
:将一个数组复制到一个新数组中,也可以指定新数组的长度。
例如,int[] newArray = Arrays.copyOf(oldArray, length)
。
//好用的Arrays.copyOfRange()
Integer[] original = {1, 2, 3, 4, 5};
Integer[] copy = Arrays.copyOfRange(original, 1, 4); // 复制索引 1 到 3(不包括 4)的元素
//运行后copy数组的内容是{2, 3, 4}
Arrays.fill
Arrays.fill()
:用指定的值填充数组的所有元素。例如,Arrays.fill(array, value)
。
Arrays.equals()
:比较两个数组是否相等,即数组中的元素是否相同,顺序也相同。例如,Arrays.equals(array1, array2)
。
Arrays.asList()
:将数组转换为列表。例如,List<Integer> list = Arrays.asList(array)
。
拼接数组System.arraycopy
这里比函数七中的Arrays.copyOfRange灵活
public static int[] concatenateArrays(int[] arr1, int[] arr2) {
int[] result = new int[arr1.length + arr2.length];//将第一个数组arr1的元素复制到result
System.arraycopy(arr1, 0, result, 0, arr1.length);//将第二个数组arr2的元素复制到result
System.arraycopy(arr2, 0, result, arr1.length, arr2.length);
return result;
}
去重数组
public static int[] newArrFn(int[] arr) {
//该方法去重int[]和char[]都有用
HashSet<Integer> set = new HashSet<>();
for (int num : arr) {
set.add(num);
}
int[] newArr = new int[set.size()];
int index = 0;
for (int num : set) {
newArr[index++] = num;
}
return newArr;
}
函数八:容器Collection.函数
Collections.sort
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SortingExample {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();//注意这里
numbers.add(5);
numbers.add(2);
numbers.add(8);
numbers.add(1);
numbers.add(3);
System.out.println("Before sorting: " + numbers);
// 使用Collections类的sort方法对List进行排序
Collections.sort(numbers);
System.out.println("After sorting: " + numbers);
}
}
Collections.reverse
List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
System.out.println("Before reverse: " + names);
Collections.reverse(names);//反转集合中元素的顺序
System.out.println("After reverse: " + names);
Collections.shuffle随机打乱
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
numbers.add(5);
System.out.println("Before shuffle: " + numbers);
Collections.shuffle(numbers);//随机打乱集合中元素的顺序
System.out.println("After shuffle: " + numbers);
Collections.rotate元素右旋指定距离
List<Character> letters = new ArrayList<>();
letters.add('A');
letters.add('B');
letters.add('C');
letters.add('D');
letters.add('E');
System.out.println("Before rotate: " + letters);
Collections.rotate(letters, 2);//将集合中的元素向右旋转指定的距离
System.out.println("After rotate: " + letters);
函数九:Random随机数
import java.util.Random;
public class RandomExample {
public static void main(String[] args) {
Random random = new Random();
// 生成一个随机整数
int randomNumber = random.nextInt(100); // 生成0到99之间的随机整数
System.out.println("Random number: " + randomNumber);
// 生成一个随机双精度浮点数
double randomDouble = random.nextDouble(); // 生成0.0到1.0之间的随机双精度浮点数
System.out.println("Random double: " + randomDouble);
}
}
矩阵转换
import java.io.*;
import java.util.*;
class Solution {
public void myFunc(ArrayList<ArrayList<Integer>> arr) {
int numRows = arr.size();
int numCols = arr.get(0).size();
for (int j = 0; j < numCols; j++) {
for (int i = 0; i < numRows; i++) {
System.out.print(arr.get(i).get(j));
if (i < numRows - 1) {
System.out.print(" ");
}
}
System.out.println();
}
}
}
public class Main {
public static void main(String args[]) {
Scanner cin = new Scanner(System.in);
ArrayList<ArrayList<Integer>> arr = new ArrayList<ArrayList<Integer>>();
while (cin.hasNextLine()) {
ArrayList<Integer> row = new ArrayList<Integer>();
String line = cin.nextLine();
if (line.length() > 0) {
String[] arrLine = line.split(" ");
for (int i = 0; i < arrLine.length; i++) {
row.add(Integer.parseInt(arrLine[i]));
}
arr.add(row);
}
}
new Solution().myFunc(arr);
}
}
由前序中序求后序
前序遍历:1247356A(第一行输入)
中序遍历:472153A6(第二行输入)
后序遍历:7425A631
import java.util.Scanner;
class Node {
int data;
Node left, right;
public Node(int data) {
this.data = data;
this.left = this.right = null;
}
}
// 注意类为 Main,
public class Main {
private Node root;
public Main(){
root=null;
}
public void postOrder(){
this.postOrder(this.root);
}
public void postOrder(Node localRoot){
if(localRoot!=null){
postOrder(localRoot.left);
postOrder(localRoot.right);
System.out.print((char)localRoot.data);
}
}
public void initTree(char[] preOrder,char[] midOrder){
this.root=this.initTree(preOrder,0,preOrder.length-1,midOrder,0,midOrder.length-1);
}
private Node initTree(char[] preOrder,int start1,int end1,char[] midOrder,int start2,int end2){
if(start1>end1||start2>end2){
return null;
}
char rootData=preOrder[start1];
Node head=new Node(rootData);
int rootIndex=findIndexArray(midOrder,rootData,start2,end2);
int offSet=rootIndex-start2-1;
Node left=initTree(preOrder,start1+1,start1+1+offSet,midOrder,start2,start2+offSet);
Node right=initTree(preOrder,start1+offSet+2,end1,midOrder,rootIndex+1,end2);
head.left=left;
head.right=right;
return head;
}
private int findIndexArray(char[] a,char x,int begin,int end){
for(int i=begin;i<=end;i++){
if(a[i]==x){
return i;
}
}
return -1;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String scann=null;//第一行前序ABDCF
while(in.hasNextLine()){
scann=in.nextLine();
break;
}
char[] pre_q=scann.toCharArray();
scann=null;//第二行中序DBAFC
while(in.hasNextLine()){
scann=in.nextLine();
break;
}
char[] mid_q=scann.toCharArray();
Main binaryTree=new Main();
binaryTree.initTree(pre_q,mid_q);
binaryTree.postOrder();
}
}
搜索
深度优先搜索(DFS)
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public class DepthFirstSearch {
public void dfs(TreeNode root) {
if (root == null) {
return;
}
System.out.print(root.val + " "); // 访问当前节点
dfs(root.left); // 递归遍历左子树
dfs(root.right); // 递归遍历右子树
}
public static void main(String[] args) {
DepthFirstSearch dfs = new DepthFirstSearch();
// 构建二叉树
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
// 深度优先搜索
dfs.dfs(root);
}
}
广度优先搜索(BFS)
import java.util.LinkedList;
import java.util.Queue;
public class BreadthFirstSearch {
public void bfs(TreeNode root) {
if (root == null) {
return;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode current = queue.poll();
System.out.print(current.val + " "); // 访问当前节点
if (current.left != null) {
queue.offer(current.left); // 将左子节点加入队列
}
if (current.right != null) {
queue.offer(current.right); // 将右子节点加入队列
}
}
}
public static void main(String[] args) {
BreadthFirstSearch bfs = new BreadthFirstSearch();
// 构建二叉树
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
// 广度优先搜索
bfs.bfs(root);
}
}