java算法题常用工具模板

7 篇文章 0 订阅

输入与输出

一般我常用的数据输入方法有两种,Scanner和BufferedReader。BufferedReader可以读一行,速度比Scanner快,所以数据较多的时候使用。注意BufferedReader用完记得关。

1.Scanner

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(); // String: next(), double: nextDouble()
        int[] nums = new int[n];
        for (int i = 0; i < n; i++)
            nums[i] = sc.nextInt();
    }
}

2.BufferReader

import java.util.*;
import java.io.*;

public class Main{
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        //读入的是字符串形式,需要转化为整型
        int n = Integer.parseInt(reader.readLine());
        int[] nums = new int[n];
        String[] strs = reader.readLine().split(" ");
        for (int i = 0; i < n; i++)
            nums[i] = Integer.parseInt(strs[i]);
        reader.close(); // 记得关闭
    }
}

数组初始化

初始化一维数组

int[] arr = new int[110];
Arrays.fill(arr,-1);
  • 注意Arrays.fill只能用来初始化一维数组,不能用来直接初始化多位数组。

初始化二维数组

\\使用循环初始化所有行
int[] arr = new int[110][110];
for(int[] row : arr)
    Arrays.fill(row, -1);

字符型的0-9数字转为int型数字:

直接将字符值减去48,因为数字0对应的ASCII码值为48:

 char a = 1; int i = a-48;
 //或者直接减去字符'0'
 char a = 1; int i = a-'0';

字符数组转字符串:

//构造String时传参
char data[] = {'s', 'g', 'k'};
String str = new String(data);
//String.valueOf(char[] chr)
char[] cha = {'s','g','h'};
String n = String.valueOf(cha);

数组拷贝

  • 拷贝所有元素,使用Object类的clone方法
int[] a = {1,2,3}
int[] b = a.clone();
  • 拷贝指定位置元素
//函数原型:copyOfRange(oringinal,int from, int to)
//该方法是从original数组的下标from开始复制,到下标to结束
int[] a = {1,2,3,4};
int[] b = Arrays.copyOfRange(a,2,3);

数组与List互相转换

数组转List

Integer[] arr = new Integer[] { 1, 2, 3 };
List<Integer> list = Arrays.asList(arr);
for(Integer i:list)
                    System.out.println(i);

List转数组

List<Integer> stockList = new ArrayList<>();
stockList.add(1);stockList.add(2);

Integer[] stockArr = new Integer[stockList.size()];
stockArr = stockList.toArray(stockArr);

for(Integer s : stockArr)
    System.out.println(s+" ");

排序

对List排序

  • Collections.sort()方法:
	List<Integer> list = new ArrayList<>();
	list.add();list.add();list.add();
//升序排序	
	Collections.sort(list);
//逆序排序
    Collections.sort(list, Collections.reverseOrder());
  • List.sort()方法:
List<Integer> list= new ArrayList<>();
list.add(-3);list.add(5);list.add(1);list.add(3);
//升序排序,也可写作 stockList.sort(Integer::compareTo);
        list.sort((Integer o1,Integer o2)->o1-o2);
//降序只需改变Comparator的结果符号即可
        list.sort((Integer o1,Integer o2)->o2-o1);
  • 对字符串类型或者char类型
 List<String> stringList = new ArrayList<>();
        stringList.add("a");
        stringList.add("hard");
        stringList.add("good");
//        stringList.sort((String::compareTo));//字典序
//        stringList.sort(Comparator.naturalOrder());//字典序
//        stringList.sort((String s1, String s2)->s1.compareTo(s2));//字典序
//        stringList.sort((String s1, String s2)->s2.compareTo(s1));//逆字典序
//        stringList.sort(Comparator.reverseOrder());//逆字典序
          stringList.sort((String::lastIndexOf));//按最后一位字母的字典序
  • 对基本类型数组排序
    Arrays.sort(arr)可以对数组按升序排序,此时arr可以是基本类型的数组(如int[], double[], char[]等),也可以是包装类型(Integer[], Double[]等)。
    Arrays.sort(arr, Collections.reverseOrder()) 可以对数组按降序排序,但此时arr只能是包装类型。

常用容器操作(对比C++ STL)

1.vector 和 ArrayList

vector<int> a; - ArrayList<Integer> a = new ArrayList<>();
size()  - size()  // 返回元素个数
empty() - isEmpty()  // 返回是否为空
clear() - clear  // 清空
front()/back() - get(0)/get(a.size() - 1)
push_back()/pop_back() - add()/remove(a.size() - 1)
begin()/end() - iterator()
[] - get()
支持比较运算 - 不支持比较运算

ArrayList 的遍历:
for (int i = 0; i < a.size(); i++) a.get(i);

Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) iterator.next()

for (int num : a) num;

2.pair 和 Pair

(Java 需要 import javafx.util.Pair ,目前 acwing 不支持)

pair<int, int> p = make_pair(1, 2); - Pair<Integer, Integer> p = new Pair<>(1, 2); 
first - getKey() // 第一个元素
second - getValue() // 第二个元素
支持比较运算 - 不支持比较运算

///java中自定义pair类
class Pair implements Comparable<Pair>{
	public int x,y;
	public Pair(int x,int y){
		this.x = x;
		this.y = y;
	}
	//若需要pair排序,则加上下面代码
	@Override
	public int compareTo(Pair o){
		return Integer.compare(x,o.x);
	}
}

3.string 和 String

string a = "yxc"; - String b = "hqh";
size()/length() - length()  // 返回字符串长度
empty()
clear()
substr(起始下标,(子串长度)) - substring(起始下标,(终止下标 + 1)) // 返回子串
c_str()  // 返回字符串所在字符数组的起始地址
支持加法运算 - 支持加法运算

4.queue, stack, deque 和 Deque

queue, 队列
   size()  - size()
   empty() - isEmpty()
   push()  - offer()  // 向队尾插入一个元素
   front() - peek()  // 返回队头元素
   back()  // 返回队尾元素
   pop()   - poll()  // 弹出队头元素


stack,size()  - size()
   empty() - isEmpty()
   push()  - push()  // 向栈顶插入一个元素
   top()   - peek()  // 返回栈顶元素
   pop()   - pop()  // 弹出栈顶元素

deque, 双端队列
   size()  - size()
   empty() - isEmpty()
   clear() - clear()
   front()/back() - getFirst()/getLast()
   push_back()/pop_back()   - offerLast()/pollLast()
   push_front()/pop_front() - offerFirst()/pollFirst()
   begin()/end() - iterator()
   []

5.priority_queue 和 PriorityQueue

默认是大根堆 - 默认是小根堆
push() - offer()  // 插入一个元素
top() - peek()  // 返回堆顶元素
pop() - poll() // 弹出堆顶元素

PriorityQueue 定义成大根堆的方式:
PriorityQueue<Integer> pq = new PriorityQueue<>((o1, o2) -> o2 - o1);

6.unordered_set 和 HashSet

size() - size()
empty() - isEmpty()
clear() - clear()
insert() - add()  // 插入一个数
find() - contains()  // 查找一个数
erase() - remove() // 删除元素

7.unordered_map 和 HashMap

size()   - size()
empty()  - isEmpty()
clear()  - clear()
insert() - put() // 插入的数是一个 pair
find()   - get(key) // 查找一个 pair
erase()  - remove() // 删除元素
    	 - containsKey(key)/containsValue(value) // 判断元素是否在集合中
   		 - entrySet() // 返回一个包含所有节点的集合
   		 - keySet() // 返回一个包含所有键的集合
   		 - values() // 返回一个包含所有值的集合
    	 - getOrDefault(key, default value) // 返回指定 key 的 value,若 key 不存在 则返回 default value
   		 - putIfAbsent(key, value) // 如果集合中没有该 key 对应的节点,则插入

图的存储

n个点,m条边,m约等于n2n2叫做稠密图,用邻接矩阵存储;n个点,m条边,m远小于n2n2叫做稀疏图,用邻接表存储。

邻接矩阵

public class Main{
    public static final int INF = 0x3f3f3f3f;
    public static int n;
    public static int[][] g;
    public static int[] dist;
    public static boolean[] visit;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        int m = sc.nextInt();
        g = new int[n + 1][n + 1];
        dist = new int[n + 1];
        visit = new boolean[n + 1];
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                if (i == j)
                    g[i][j] = 0;
                else
                    g[i][j] = INF;
        for (int i = 0; i < m; i++) {
            int x = sc.nextInt(), y = sc.nextInt(), z = sc.nextInt();
            g[a][b] = Math.min(g[a][b], c);
        }
        //int res = dijkstra();
        System.out.println(res);
    }
}

邻接表

import java.util.*;

public class Main{
    public static int INF = 0x3f3f3f3f;
    public static int n;
    public static Map<Integer, List<Node>> map = new HashMap<>();
    public static int[] dist;
    public static boolean[] visit;

    public static class Node {
        public int node;
        public int length;

        public Node(int node, int length) {
            this.node = node;
            this.length = length;
        }
    }

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        n = sc.nextInt();
        dist = new int[n + 1];
        visit = new boolean[n + 1];
        int m = sc.nextInt();
        for (int i = 1; i <= n; i++)
            map.put(i, new ArrayList<>());
        for (int i = 0; i < m; i++) {
            int x = sc.nextInt(), y = sc.nextInt(), z = sc.nextInt();
            map.get(x).add(new Node(y, z));
        }
        //int res = dijkstra();
        System.out.println(res);
    }
}
/* * (有向)图的深度优先遍历算法模板 */ package dsa; public abstract class DFS extends GraphTraverse { //变量 protected static int clock = 0;//遍历过程中使用的计时钟 //构造方法 public DFS(Graph g) { super(g); } //深度优先遍历算法 protected Object traverse(Vertex v, Object info) {//从顶点v出发,深度优先查找 if (UNDISCOVERED != v.getStatus()) return null;//跳过已访问过的顶点(针对非连通图) v.setDStamp(clock++); v.setStatus(DISCOVERED); visit(v, info);//访问当前顶点 for (Iterator it = v.outEdges(); it.hasNext();) {//检查与顶点v Edge e = (Edge)it.getNext();//通过边e = (v, u) Vertex u = (Vertex)e.getVPosInV(1).getElem();//相联的每一顶点u switch (u.getStatus()) {//根据u当前的不同状态,分别相应处理 case UNDISCOVERED ://若u尚未被发现,则 e.setType(TREE);//e被归类为“树边” traverse(u, info);//从u出发,继续深度优先查找 break; case DISCOVERED ://若u已经被发现,但对其访问尚未结束,则 e.setType(BACKWARD);//将e归类为“后向跨边” break; default ://VISITED,即对u的访问已经结束 if (u.getDStamp() < v.getDStamp())//若相对于v,u被发现得更早,则 e.setType(CROSS);//将e归类为“横跨边” else//否则 e.setType(FORWARD);//将e归类为“前向跨边” break; } }//至此,v的所有邻居都已访问结束,故 v.setFStamp(clock++); v.setStatus(VISITED);//将v标记为VISITED return null;//然后回溯 } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sklit88

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值