java-数据结构与算法-02-数据结构-05-栈

news2024/11/16 21:24:56

文章目录

    • 1. 栈
      • 1. 概述
      • 2. 链表实现
      • 3. 数组实现
      • 4. 应用
    • 2. 习题
      • E01. 有效的括号-Leetcode 20
      • E02. 后缀表达式求值-Leetcode 120
      • E03. 中缀表达式转后缀
      • E04. 双栈模拟队列-Leetcode 232
      • E05. 单队列模拟栈-Leetcode 225

1. 栈

1. 概述

计算机科学中,stack 是一种线性的数据结构,只能在其一端添加数据和移除数据。习惯来说,这一端称之为栈顶,另一端不能操作数据的称之为栈底,就如同生活中的一摞书

栈是一种特殊的线性表,只能在一端进行操作

  • 往栈中添加元素的操作,一般叫做 push,入栈
  • 从栈中移除元素的操作,一般叫做 pop,出栈(只能移除栈顶元素,也叫做:弹出栈顶元素)
  • 后进先出的原则,Last In First Out,LIFO
    在这里插入图片描述

先提供一个栈接口

public interface Stack<E> {
    /**
     * 向栈顶压入元素
     * @param value 待压入值
     * @return 压入成功返回 true, 否则返回 false
     */
    boolean push(E value);

    /**
     * 从栈顶弹出元素
     * @return 栈非空返回栈顶元素, 栈为空返回 null
     */
    E pop();

    /**
     * 返回栈顶元素, 不弹出
     * @return 栈非空返回栈顶元素, 栈为空返回 null
     */
    E peek();

    /**
     * 判断栈是否为空
     * @return 空返回 true, 否则返回 false
     */
    boolean isEmpty();

    /**
     * 判断栈是否已满
     * @return 满返回 true, 否则返回 false
     */
    boolean isFull();
}

栈的应用
浏览器的前进和后退

在这里插入图片描述

2. 链表实现

package com.itheima.datastructure.stack;

import java.util.Iterator;
import java.util.StringJoiner;

/**
 * 链表实现的栈。
 * 该类实现了Stack接口和Iterable接口,允许对栈中的元素进行迭代。
 *
 * @param <E> 栈中元素的类型。
 */
public class LinkedListStack<E> implements Stack<E>, Iterable<E> {

    /**
     * 栈的容量,默认为Integer.MAX_VALUE,表示不限制容量。
     */
    private int capacity = Integer.MAX_VALUE;
    
    /**
     * 栈中元素的数量。
     */
    private int size;
    
    /**
     * 链表的头节点,用于简化插入和删除操作。
     */
    private final Node<E> head = new Node<>(null, null);

    /**
     * 默认构造函数。
     */
    public LinkedListStack() {
    }

    /**
     * 带容量限制的构造函数。
     *
     * @param capacity 栈的容量限制。
     */
    public LinkedListStack(int capacity) {
        this.capacity = capacity;
    }

    /**
     * 将元素压入栈顶。
     *
     * @param value 要压入栈的元素。
     * @return 如果栈未满,则返回true;否则返回false。
     */
    /*
        head -> 2 -> 1 -> null
     */
    @Override
    public boolean push(E value) {
        if (isFull()) {
            return false;
        }
        head.next = new Node<>(value, head.next);
        size++;
        return true;
    }

    /**
     * 从栈顶弹出一个元素。
     *
     * @return 如果栈不为空,则返回栈顶元素;否则返回null。
     */
    /*
        head -> 2 -> 1 -> null
     */
    @Override
    public E pop() {
        if (isEmpty()) {
            return null;
        }
        Node<E> first = head.next;
        head.next = first.next;
        size--;
        return first.value;
    }

    /**
     * 查看栈顶元素。
     *
     * @return 如果栈不为空,则返回栈顶元素;否则返回null。
     */
    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        return head.next.value;
    }

    /**
     * 检查栈是否为空。
     *
     * @return 如果栈为空,则返回true;否则返回false。
     */
    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 检查栈是否已满。
     *
     * @return 如果栈已满,则返回true;否则返回false。
     */
    @Override
    public boolean isFull() {
        return size == capacity;
    }

    /**
     * 创建一个迭代器,用于遍历栈中的元素。
     *
     * @return栈的元素迭代器。
     */
    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            Node<E> p = head.next;

            @Override
            public boolean hasNext() {
                return p != null;
            }

            @Override
            public E next() {
                E value = p.value;
                p = p.next;
                return value;
            }
        };
    }

    /**
     * 链表节点类,用于存储栈中的元素。
     *
     * @param <E> 节点中存储的元素类型。
     */
    static class Node<E> {
        E value;
        Node<E> next;

        public Node(E value, Node<E> next) {
            this.value = value;
            this.next = next;
        }
    }

    /**
     * 将栈中的元素转换为字符串表示。
     *
     * @return 栈的字符串表示,元素之间用逗号分隔。
     */
    @Override
    public String toString() {
        StringJoiner sj = new StringJoiner(",");
        for (E e : this) {
            sj.add(e.toString());
        }
        return sj.toString();
    }
}


3. 数组实现

/**
 * 数组实现的栈类,支持泛型元素。
 * @param <E> 栈中元素的类型。
 */
package com.itheima.datastructure.stack;

import java.util.Iterator;

public class ArrayStack<E> implements Stack<E>, Iterable<E> {

    /**
     * 存储栈元素的数组。
     */
    private final E[] array;
    
    /**
     * 栈顶指针,指示当前栈的顶部元素的位置。
     */
    private int top; // 栈顶指针

    /**
     * 构造一个指定容量的栈。
     * @param capacity 栈的初始容量。
     */
    @SuppressWarnings("all")
    public ArrayStack(int capacity) {
        this.array = (E[]) new Object[capacity];
    }

    /**
     * 将元素压入栈顶。
     * @param value 要压入栈的元素。
     * @return 如果栈未满,则返回true;否则返回false。
     */
    @Override
    public boolean push(E value) {
        if (isFull()) {
            return false;
        }
        array[top++] = value;
        return true;
    }

    /**
     * 弹出栈顶元素。
     * @return 栈顶元素,如果栈为空,则返回null。
     */
    @Override
    public E pop() {
        if (isEmpty()) {
            return null;
        }
        E e = array[--top];
        array[top] = null; // help GC
        return e;
    }

    /**
     * 查看栈顶元素。
     * @return 栈顶元素,如果栈为空,则返回null。
     */
    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        return array[top - 1];
    }

    /**
     * 检查栈是否为空。
     * @return 如果栈为空,则返回true;否则返回false。
     */
    @Override
    public boolean isEmpty() {
        return top == 0;
    }

    /**
     * 检查栈是否已满。
     * @return 如果栈已满,则返回true;否则返回false。
     */
    @Override
    public boolean isFull() {
        return top == array.length;
    }

    /**
     * 返回栈元素的迭代器,用于遍历栈。
     * @return栈元素的迭代器。
     */
    /*
        底          顶
        0   1   2   3
        a   b   c   d
                        p
     */
    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            int p = top;

            @Override
            public boolean hasNext() {
                return p > 0;
            }

            @Override
            public E next() {
                return array[--p];
            }
        };
    }
}

4. 应用

模拟如下方法调用

public static void main(String[] args) {
    System.out.println("main1");
    System.out.println("main2");
    method1();
    method2();
    System.out.println("main3");
}

public static void method1() {
    System.out.println("method1");
    method3();
}

public static void method2() {
    System.out.println("method2");
}

public static void method3() {
    System.out.println("method3");
}

模拟代码

package com.itheima.datastructure.stack;

/**
 * CPU模拟类,使用栈来模拟方法的调用与返回。
 */
public class CPU {
    /**
     * 方法帧类,用于存储方法的退出点。
     */
    static class Frame {
        int exit;

        /**
         * 构造方法,初始化方法帧的退出点。
         * 
         * @param exit 方法的退出点值。
         */
        public Frame(int exit) {
            this.exit = exit;
        }
    }

    /**
     * 程序计数器,用于指示当前执行的指令位置。
     */
    static int pc = 1;
    /**
     * 方法调用栈,用于模拟方法的调用与返回过程。
     */
    static ArrayStack<Frame> stack = new ArrayStack<>(100);

    /**
     * 程序入口点。
     * 
     * @param args 命令行参数。
     */
    public static void main(String[] args) {
        // 初始化方法调用栈,压入一个表示main方法开始的帧
        stack.push(new Frame(-1));
        // 当栈不为空时,循环执行指令
        while (!stack.isEmpty()) {
            // 根据程序计数器的值执行相应的操作
            switch (pc) {
                case 1:
                    // 执行main方法的第一段代码
                    System.out.println("main1");
                    pc++;
                    break;
                case 2:
                    // 执行main方法的第二段代码
                    System.out.println("main2");
                    pc++;
                    break;
                case 3:
                    // 调用method1方法
                    stack.push(new Frame(pc + 1));
                    pc = 100;
                    break;
                case 4:
                    // 调用method2方法
                    stack.push(new Frame(pc + 1));
                    pc = 200;
                    break;
                case 5:
                    // 方法返回,从栈中弹出方法帧,并跳转到退出点
                    System.out.println("main3");
                    pc = stack.pop().exit;
                    break;
                case 100:
                    // method1方法的代码段
                    System.out.println("method1");
                    stack.push(new Frame(pc + 1));
                    pc = 300;
                    break;
                case 101:
                    // method1方法返回
                    pc = stack.pop().exit;
                    break;
                case 200:
                    // method2方法的代码段
                    System.out.println("method2");
                    pc = stack.pop().exit;
                    break;
                case 300:
                    // method3方法的代码段
                    System.out.println("method3");
                    pc = stack.pop().exit;
                    break;
            }
        }
    }
}

2. 习题

E01. 有效的括号-Leetcode 20

一个字符串中可能出现 [] () 和 {} 三种括号,判断该括号是否有效
有效的例子

()[]{}

([{}])

()

无效的例子

[)

([)]

([]

思路

  • 遇到左括号, 把要配对的右括号放入栈顶
  • 遇到右括号, 若此时栈为空, 返回 false,否则把它与栈顶元素对比
    • 若相等, 栈顶元素弹出, 继续对比下一组
    • 若不等, 无效括号直接返回 false
  • 循环结束
    • 若栈为空, 表示所有括号都配上对, 返回 true
    • 若栈不为空, 表示右没配对的括号, 应返回 false

答案(用到了课堂案例中的 ArrayStack 类)

public boolean isValid(String s) {
    ArrayStack<Character> stack = new ArrayStack<>(s.length() / 2 + 1);
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        if (c == '(') {
            stack.push(')');
        } else if (c == '[') {
            stack.push(']');
        } else if (c == '{') {
            stack.push('}');
        } else {
            if (!stack.isEmpty() && stack.peek() == c) {
                stack.pop();
            } else {
                return false;
            }
        }
    }
    return stack.isEmpty();
}

E02. 后缀表达式求值-Leetcode 120

后缀表达式也称为逆波兰表达式,即运算符写在后面

  • 从左向右进行计算
  • 不必考虑运算符优先级,即不用包含括号

示例

输入:tokens = ["2","1","+","3","*"]
输出:9
即:(2 + 1) * 3

输入:tokens = ["4","13","5","/","+"]
输出:6
即:4 + (13 / 5)

题目假设

  • 数字都视为整数
  • 数字和运算符个数给定正确,不会有除零发生

代码

public int evalRPN(String[] tokens) {
    LinkedList<Integer> numbers = new LinkedList<>();
    for (String t : tokens) {
        switch (t) {
            case "+" -> {
                Integer b = numbers.pop();
                Integer a = numbers.pop();
                numbers.push(a + b);
            }
            case "-" -> {
                Integer b = numbers.pop();
                Integer a = numbers.pop();
                numbers.push(a - b);
            }
            case "*" -> {
                Integer b = numbers.pop();
                Integer a = numbers.pop();
                numbers.push(a * b);
            }
            case "/" -> {
                Integer b = numbers.pop();
                Integer a = numbers.pop();
                numbers.push(a / b);
            }
            default -> numbers.push(Integer.parseInt(t));
        }
    }
    return numbers.pop();
}

E03. 中缀表达式转后缀

public class E03InfixToSuffix {
    /*
        思路
        1. 遇到数字, 拼串
        2. 遇到 + - * /
            - 优先级高于栈顶运算符 入栈
            - 否则将栈中高级或平级运算符出栈拼串, 本运算符入栈
        3. 遍历完成, 栈中剩余运算符出栈拼串
            - 先出栈,意味着优先运算
        4. 带 ()
            - 左括号直接入栈
            - 右括号要将栈中直至左括号为止的运算符出栈拼串

        |   |
        |   |
        |   |
        _____

        a+b
        a+b-c
        a+b*c
        a*b+c
        (a+b)*c

     */
    public static void main(String[] args) {
        System.out.println(infixToSuffix("a+b"));
        System.out.println(infixToSuffix("a+b-c"));
        System.out.println(infixToSuffix("a+b*c"));
        System.out.println(infixToSuffix("a*b-c"));
        System.out.println(infixToSuffix("(a+b)*c"));
        System.out.println(infixToSuffix("a+b*c+(d*e+f)*g"));
    }

       /**
     * 将中缀表达式转换为后缀表达式。
     * 后缀表达式也称为逆波兰表达式,它使用栈的操作来实现运算符的优先级处理,有效地简化了计算过程。
     * 
     * @param exp 中缀表达式字符串,包含数字、运算符和括号。
     * @return 后缀表达式字符串。
     */
    static String infixToSuffix(String exp) {
        // 使用链表作为栈来存储运算符
        LinkedList<Character> stack = new LinkedList<>();
        // 使用StringBuilder来构建后缀表达式
        StringBuilder sb = new StringBuilder(exp.length());
        
        // 遍历中缀表达式的每个字符
        for (int i = 0; i < exp.length(); i++) {
            char c = exp.charAt(i);
            
            // 根据字符的不同类型进行处理
            switch (c) {
                case '*', '/', '+', '-' -> {
                    // 处理运算符
                    if (stack.isEmpty()) {
                        stack.push(c);
                    } else {
                        if (priority(c) > priority(stack.peek())) {
                            stack.push(c);
                        } else {
                            // 当当前运算符的优先级不高于栈顶运算符时,将栈顶运算符弹出到后缀表达式中
                            while (!stack.isEmpty() && priority(stack.peek()) >= priority(c)) {
                                sb.append(stack.pop());
                            }
                            stack.push(c);
                        }
                    }
                }
                case '(' -> {
                    // 遇到左括号直接入栈
                    stack.push(c);
                }
                case ')' -> {
                    // 遇到右括号,将栈中的运算符依次弹出到后缀表达式中,直到遇到左括号
                    while (!stack.isEmpty() && stack.peek() != '(') {
                        sb.append(stack.pop());
                    }
                    // 弹出左括号,不加入到后缀表达式中
                    stack.pop();
                }
                default -> {
                    // 遇到数字直接加入到后缀表达式中
                    sb.append(c);
                }
            }
        }
        // 将栈中剩余的运算符依次弹出到后缀表达式中
        while (!stack.isEmpty()) {
            sb.append(stack.pop());
        }
        // 返回构建好的后缀表达式
        return sb.toString();
    }

/**
 * 计算运算符的优先级。
 * 
 * @param c 运算符
 * @return 运算符的优先级
 * @throws IllegalArgumentException 如果运算符不合法,则抛出此异常
 */
static int priority(char c) {
    // 使用switch表达式来根据运算符的类型返回对应的优先级
    return switch (c) {
        case '*' -> 2; // 乘法和除法具有相同的优先级
        case '/' -> 2;
        case '+' -> 1; // 加法和减法具有相同的优先级
        case '-' -> 1;
        case '(' -> 0; // 左括号具有最低优先级
        default -> throw new IllegalArgumentException("不合法的运算符:" + c);
    };
}

}

返回结果

ab+c*
abc*+d-e*
abc+*

E04. 双栈模拟队列-Leetcode 232

给力扣题目用的自实现栈,可以定义为静态内部类

class ArrayStack<E> {

    private E[] array;
    private int top; // 栈顶指针

    @SuppressWarnings("all")
    public ArrayStack(int capacity) {
        this.array = (E[]) new Object[capacity];
    }

    public boolean push(E value) {
        if (isFull()) {
            return false;
        }
        array[top++] = value;
        return true;
    }

    public E pop() {
        if (isEmpty()) {
            return null;
        }
        return array[--top];
    }

    public E peek() {
        if (isEmpty()) {
            return null;
        }
        return array[top - 1];
    }

    public boolean isEmpty() {
        return top == 0;
    }

    public boolean isFull() {
        return top == array.length;
    }
}

参考解答,注意:题目已说明

  • 调用 push、pop 等方法的次数最多 100
package com.itheima.datastructure.stack;

/**
 * 双栈模拟队列
 *
 * <ul>
 *     <li>调用 push、pop 等方法的次数最多 100</li>
 * </ul>
 */
public class E04Leetcode232 {

    /*
        队列头        队列尾
        b
        顶   底     底   顶
        s1              s2

        队列尾添加
            s2.push(a)
            s2.push(b)

        队列头移除
            先把 s2 的所有元素移动到 s1
            s1.pop()

     */
    ArrayStack<Integer> s1 = new ArrayStack<>(100);
    ArrayStack<Integer> s2 = new ArrayStack<>(100);

    public void push(int x) { //向队列尾添加
        s2.push(x);
    }

    public int pop() { // 从对列头移除
        if (s1.isEmpty()) {
            while (!s2.isEmpty()) {
                s1.push(s2.pop());
            }
        }
        return s1.pop();
    }

    public int peek() { // 从对列头获取
        if (s1.isEmpty()) {
            while (!s2.isEmpty()) {
                s1.push(s2.pop());
            }
        }
        return s1.peek();
    }

    public boolean empty() {
        return s1.isEmpty() && s2.isEmpty();
    }

}

E05. 单队列模拟栈-Leetcode 225

给力扣题目用的自实现队列,可以定义为静态内部类

public class ArrayQueue3<E> {

    private final E[] array;
    int head = 0;
    int tail = 0;

    @SuppressWarnings("all")
    public ArrayQueue3(int c) {
        c -= 1;
        c |= c >> 1;
        c |= c >> 2;
        c |= c >> 4;
        c |= c >> 8;
        c |= c >> 16;
        c += 1;
        array = (E[]) new Object[c];
    }
    
    public boolean offer(E value) {
        if (isFull()) {
            return false;
        }        
        array[tail & (array.length - 1)] = value;
        tail++;
        return true;
    }

    public E poll() {
        if (isEmpty()) {
            return null;
        }
        E value = array[head & (array.length - 1)];
        head++;
        return value;
    }

    public E peek() {
        if (isEmpty()) {
            return null;
        }
        return array[head & (array.length - 1)];
    }

    public boolean isEmpty() {
        return head == tail;
    }

    public boolean isFull() {
        return tail - head == array.length;
    }
}

参考解答,注意:题目已说明

  • 调用 push、pop 等方法的次数最多 100
  • 每次调用 pop 和 top 都能保证栈不为空
public class E05Leetcode225 {
    /*
        队列头     队列尾
        cba
        顶           底

        queue.offer(a)
        queue.offer(b)
        queue.offer(c)
     */
    ArrayQueue3<Integer> queue = new ArrayQueue3<>(100);
    int size = 0;
    public void push(int x) {
        queue.offer(x);
        for (int i = 0; i < size; i++) {
            queue.offer(queue.poll());
        }
        size++;
    }

    public int pop() {
        size--;
        return queue.poll();
    }

    public int top() {
        return queue.peek();
    }

    public boolean empty() {
        return queue.isEmpty();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1948927.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习Numpy的奇思妙想

学习Numpy的奇思妙想 本文主要想记录一下&#xff0c;学习 numpy 过程中的偶然的灵感&#xff0c;并记录一下知识框架。 推荐资源&#xff1a;https://numpy.org/doc/stable/user/absolute_beginners.html &#x1f4a1;灵感 为什么 numpy 数组的 shape 和 pytorch 是 tensor 是…

WordPress 后台开发技巧:向文章发布页右侧添加自定义菜单项

案例图片 这个案例向你介绍了如何在文章发布页的右侧边栏增加一个新的自定义菜单项。具体用它实现什么功能&#xff0c;就看你的需要了。 代码 function add_custom_menu_item() { add_meta_box(custom_menu_item, 这里是菜单项名称, display_custom_menu_item, post, side, …

昇思MindSpore学习入门-高阶自动微分

mindspore.ops模块提供的grad和value_and_grad接口可以生成网络模型的梯度。grad计算网络梯度&#xff0c;value_and_grad同时计算网络的正向输出和梯度。本文主要介绍如何使用grad接口的主要功能&#xff0c;包括一阶、二阶求导&#xff0c;单独对输入或网络权重求导&#xff…

代码随想录算法训练营Day 63| 图论 part03 | 417.太平洋大西洋水流问题、827.最大人工岛、127. 单词接龙

代码随想录算法训练营Day 63| 图论 part03 | 417.太平洋大西洋水流问题、827.最大人工岛、127. 单词接龙 文章目录 代码随想录算法训练营Day 63| 图论 part03 | 417.太平洋大西洋水流问题、827.最大人工岛、127. 单词接龙17.太平洋大西洋水流问题一、DFS二、BFS三、本题总结 82…

解析capl文件生成XML Test Module对应的xml工具

之前一直用的CAPL Test Module来写代码&#xff0c;所有的控制都是在MainTest()函数来实现的&#xff0c;但是有一次&#xff0c;代码都写完了&#xff0c;突然需要用xml的这种方式来实现&#xff0c;很突然&#xff0c;之前也没研究过&#xff0c;整理这个xml整的一身汗&#…

【1】CPU飙升到200%以上问题汇总

原链接 【1】CPU飙升到200%以上问题汇总 CPU飙升到200%以上是生成中常见的问题 注意&#xff1a; 1. linux的cpu使用频率是根据cpu个数和核数决定的 2. top&#xff0c;然后你按一下键盘的1&#xff0c;这就是单个核心的负载&#xff0c;不然是所有核心的负载相加&#xff0c;…

Golang | 腾讯一面

go的调度 Golang的调度器采用M:N调度模型&#xff0c;其中M代表用户级别的线程(也就是goroutine)&#xff0c;而N代表的事内核级别的线程。Go调度器的主要任务就是N个OS线程上调度M个goroutine。这种模型允许在少量的OS线程上运行大量的goroutine。 Go调度器使用了三种队列来…

基于STM32瑞士军刀--【FreeRTOS开发】学习笔记(二)|| 堆 / 栈

堆和栈 1. 堆 堆就是空闲的一块内存&#xff0c;可以通过malloc申请一小块内存&#xff0c;用完之后使用再free释放回去。管理堆需要用到链表操作。 比如需要分配100字节&#xff0c;实际所占108字节&#xff0c;因为为了方便后期的free&#xff0c;这一小块需要有个头部记录…

2024年7月25日(Git gitlab以及分支管理 )

分布式版本控制系统 一、Git概述 Git 是一种分布式版本控制系统,用于跟踪和管理代码的变更。它是由Linus Torvalds创建的,最 初被设计用于Linux内核的开发。Git允许开发人员跟踪和管理代码的版本,并且可以在不同的开 发人员之间进行协作。 Github 用的就是Git系统来管理它们的…

JVM面试题之内存区域、类加载篇

文章目录 引言JVM是什么&#xff1f;1. JVM内存划分2. 对象如何在JVM中创建2.1 内存分配2.2 创建对象步骤 3. JVM类加载流程3.1 双亲委派 总结 引言 Java开发人员在面试中基本都会被问到关于JVM的问题。想要成为高级的开发人员&#xff0c;了解和学习Java运行的原理和JVM是必不…

webpack插件给所有的:src文件目录增加前缀

1.webpack4的版本写法 class AddPrefixPlugin {apply(compiler) {compiler.hooks.compilation.tap(AddPrefixPlugin, (compilation) > {HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(AddPrefixPlugin,(data, cb) > {// 使用正则表达式替换所有包含 /st…

阿里云服务器安装Anaconda后无法检测到

前言 问题如标题所言&#xff0c;就是conda -V验证错误&#xff0c;不过后来发现其实就是虽然安装时&#xff0c;同意了写入环境变量&#xff0c;但是其实还没有写入&#xff0c;需要手动写入。下面也会重复一遍安装流程。 安装 到[Anaconda下载处](Download Now | Anaconda)查…

基于微信小程序+SpringBoot+Vue的流浪动物救助(带1w+文档)

基于微信小程序SpringBootVue的流浪动物救助(带1w文档) 基于微信小程序SpringBootVue的流浪动物救助(带1w文档) 本系统实现的目标是使爱心人士都可以加入到流浪动物的救助工作中来。考虑到救助流浪动物的爱心人士文化水平不齐&#xff0c;所以本系统在设计时采用操作简单、界面…

通过IEC104转MQTT网关对接阿里云、华为云、亚马逊AWS、ThingsBoard、Ignition、Zabbix

随着工业互联网的快速发展&#xff0c;传统电力系统中的IEC 104协议设备正逐步向更加开放、灵活的物联网架构转型。MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;作为一种轻量级的消息传输协议&#xff0c;因其低带宽消耗、高可靠性和广泛的支持性&#xf…

【JavaSE】基础知识复习 (二)

1.面向对象 对象内存分析 举例&#xff1a; class Person { //类&#xff1a;人String name;int age;boolean isMale; } public class PersonTest { //测试类public static void main(String[] args) {Person p1 new Person();p1.name "赵同学";p1.age 20;p1.is…

CentOS搭建Apache服务器

安装对应的软件包 [roothds ~]# yum install httpd mod_ssl -y 查看防火墙的状态和selinux [roothds ~]# systemctl status firewalld [roothds ~]# cat /etc/selinux/config 若未关闭&#xff0c;则关闭防火墙和selinux [roothds ~]# systemctl stop firewalld [roothds ~]# …

使用html2canvas制作一个截图工具

0 效果 1 下载html2canvas npm install html2canvas --save 2 创建ClipScreen.js import html2canvas from html2canvas; // 样式 const cssText {box: overflow:hidden;position:fixed;left:0;top:0;right:0;bottom:0;background-color:rgba(255,255,255,0.9);z-index: 10…

【嵌入式硬件】快衰减和慢衰减

1.引语 在使用直流有刷电机驱动芯片A4950时,这款芯片采用的是PWM控制方式,我发现他的正转、反转有两种控制方式,分别是快衰减和慢衰减。 2.理解 慢衰减:相当于加在电机(感性原件)两端电压消失,将电机两端正负短接。 快衰减:相当于加在电机(感性原件)两端电压消失,将电机…

一篇文章讲清楚html css js三件套之html

目录 HTML HTML发展史 HTML概念和语法 常见的HTML标签: HTML 调试 错误信息分析 HTML文档结构 HTML5的新特性 结论 HTML HTML是网页的基础&#xff0c;它是一种标记语言&#xff0c;用于定义网页的结构和内容。HTML标签告诉浏览器如何显示网页元素&#xff0c;例如段落…