【算法系列篇】前缀和

2023-10-27

在这里插入图片描述

前言

前缀和算法是一种常用的优化技术,用于加速某些涉及连续子数组或子序列求和的问题。它基于一个简单但强大的思想,通过提前计算并存储数组的前缀和,以便在后续查询中可以快速获取任意区间的和。

在许多算法问题中,我们需要频繁地查询子数组的和,例如最大子数组和、连续子数组的平均值等。传统的方法是在每次查询时遍历数组,并计算所需区间的和,这样会导致时间复杂度较高。

而前缀和算法通过预处理数组,计算出每个位置的前缀和,并将其保存在一个额外的数组中。这样,在查询时,我们只需要简单地减去两个前缀和即可得到所需子数组的和,从而将查询时间降低为O(1)的常数复杂度。

什么是前缀和算法

前缀和算法(Prefix Sum Algorithm)是一种用于高效计算数组前缀和的算法。前缀和是指数组中某个位置之前(包括该位置)所有元素的和。

前缀和算法的基本思想是通过一次遍历数组,计算每个位置的前缀和,并将其存储在一个新的数组中。然后,可以通过查询新数组中的元素,快速计算出任意子数组的和。

具体步骤如下:

  1. 创建一个新的数组prefixSum,长度与原数组相同。
  2. 初始化prefixSum[0]为原数组的第一个元素。
  3. 从原数组的第二个元素开始,依次计算prefixSum[i] = prefixSum[i-1] + nums[i],其中nums为原数组。
  4. 完成后,prefixSum数组中的每个元素即为对应位置之前所有元素的和。

通过前缀和算法,可以在O(1)的时间复杂度内计算出任意子数组的和。例如,要计算原数组中从位置i到位置j的子数组和,只需计算prefixSum[j] - prefixSum[i-1]即可。如果i为0,则直接返回prefixSum[j]。

前缀和算法在解决一些与子数组和相关的问题时非常有用,例如求解子数组和等于目标值的个数、求解最大子数组和、求解最长连续子数组和等。

1.【模板】前缀和

https://www.nowcoder.com/practice/acead2f4c28c401889915da98ecdc6bf?tpId=230&tqId=2021480&ru=/exam/oj&qru=/ta/dynamic-programming/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D196

1.1 题目要求

在这里插入图片描述

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int a = in.nextInt();
            int b = in.nextInt();
            System.out.println(a + b);
        }
    }
}

1.2 做题思路

按照暴力解法的思路,每次查询 l 到 r 之间的和的时候,就需要遍历一次数组,那么这样的时间复杂度就是 O(q*n) 了,因为进行了较多的重复计算,导致时间效率较低,那么是否有一种方法可以减少重复计算呢?答案是有的,这就是前缀和的思路,其实有点类似于前面我为大家分享的滑动窗口中进窗口的操作,每次进窗口更新数据的时候只需要用前面已经计算了的数字的和加上进窗口的那个数据,就得到了当前位置之前所有元素的和。通过这样的思路就大大减少了重复计算。

然后这个求 l 到 r 之间元素的和的时候,就只需要用 r 和 r 之前所有元素的和减去 l 之前所有元素的和就可以了。

在这里插入图片描述
并且仔细的人可能会发现:为什么 l 和 r 都是从1开始而不是0呢?因为从下标为0开始的话,就需要求0 ~ -1 之间元素的和,但是这个区间是不合法的,所以数组从 1 开始就可以防止出现这种的情况。

在开始求 l 到 r 之间元素的和的时候,可以先对数组进行一个预处理,求出数组中每个位置之前的前缀和。
在这里插入图片描述

1.3 Java代码实现

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int n = in.nextInt(),q = in.nextInt();
            int[] arr = new int[n + 1];
            for(int i = 1; i <= n; i++) arr[i] = in.nextInt();
            //创建一个同样大小的前缀和数组,并且因为是多个元素的和,
            //可能会超出int所能表示的最大范围,这里用long来表示
            long[] dp = new long[n + 1]; 
            for(int i = 1; i <= n; i++) {
                dp[i] = dp[i-1] + arr[i];
            }
            for(int i = 0; i < q; i++) {
                int l = in.nextInt(),r = in.nextInt();
                System.out.println(dp[r] - dp[l-1]);
            }
        } 
    }
}

在这里插入图片描述

2. 【模板】二维前缀和

https://www.nowcoder.com/practice/99eb8040d116414ea3296467ce81cbbc?tpId=230&tqId=2023819&ru=/exam/oj&qru=/ta/dynamic-programming/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D196

2.1 题目要求

在这里插入图片描述

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int a = in.nextInt();
            int b = in.nextInt();
            System.out.println(a + b);
        }
    }
}

2.2 做题思路

二维前缀和和一维前缀和的思路基本上相同的,只是一个是一维数组,一个是二维数组,一些处理细节不同。

在这里插入图片描述

当求 dp[i][j] 的时候,可以将 dp 数组分成 A、B、C、D 四个部分,A 部分是从 0,0 位置开始到 i - 1,j - 1 位置之间的矩阵元素的和。dp[i][j] = A + B + C + D 之间的元素的和,但是这里 B 和 C 区间之间的元素不是很容易求和,所以我们可以用
(A + B) + (A + C) + D - A 来求 dp[i][j] 的值。

然后(x1,y1) 到 (x2,y2)之间的矩阵的和,我们可以使用 dp[x2][y2] - (A + B) - (A + C) + A,也就是 dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1]。

在这里插入图片描述

2.3 Java代码实现

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int n = in.nextInt(),m = in.nextInt(),q = in.nextInt();
            int[][] arr = new int[n + 1][m + 1];
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= m; j++) {
                    arr[i][j] = in.nextInt();
                }
            }
            //构造二维前缀和数组
            long[][] dp = new long[n + 1][m + 1];
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= m; j++) {
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + arr[i][j] - dp[i - 1][j - 1];
                }
            }
            for(int i = 0; i < q; i++) {
                int x1 = in.nextInt(),y1 = in.nextInt(),x2 = in.nextInt(),y2 = in.nextInt();
                System.out.println(dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1 - 1][y1 - 1]);
            }
        }
    }
}

在这里插入图片描述

3. 寻找数组的中心下标

https://leetcode.cn/problems/find-pivot-index/description/

3.1 题目要求

给你一个整数数组 nums ,请计算数组的 中心下标 。

数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。

如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。

如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。

示例 1:

输入:nums = [1, 7, 3, 6, 5, 6]
输出:3
解释:
中心下标是 3 。
左侧数之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 ,
右侧数之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等。

示例 2:

输入:nums = [1, 2, 3]
输出:-1
解释:
数组中不存在满足此条件的中心下标。

示例 3:

输入:nums = [2, 1, -1]
输出:0
解释:
中心下标是 0 。
左侧数之和 sum = 0 ,(下标 0 左侧不存在元素),
右侧数之和 sum = nums[1] + nums[2] = 1 + -1 = 0 。

提示:

  • 1 <= nums.length <= 104
  • -1000 <= nums[i] <= 1000
class Solution {
    public int pivotIndex(int[] nums) {

    }
}

3.2 做题思路

这个题目要求我们找到一个元素,这个元素的左边所有元素的和等于该元素右边所有元素的和,通过前面的两个题目我们做这道题目应该是会有一点思路的。

因为要求的是某一元素左边部分和前面部分的元素的和,所以我们可以使用两个数组,分别记录数组中每一个元素的前缀和以及后缀和,前缀和数组从前往后插入数据,后缀和数组从后往前插入数据,并且前缀和的第一个数据为0,后缀和的最后一个数据为0。最后再遍历一次数组,判断数组某一位置的前缀和是否等于后缀和。

3.3 Java代码实现

class Solution {
    public int pivotIndex(int[] nums) {
        int n = nums.length;
        int[] f = new int[n];  //前缀和数组
        int[] g = new int[n];  //后缀和数组
        for(int i = 1; i < n; i++) {
            f[i] = f[i-1] + nums[i - 1];
        }
        for(int i = n - 2; i >= 0; i--) {
            g[i] = g[i + 1] + nums[i + 1];
        }
        for(int i = 0; i < n; i++) {
            if(f[i] == g[i]) return i;
        }

        return -1;
    }
}

在这里插入图片描述

4. 除自身以外的数组的乘积

https://leetcode.cn/problems/product-of-array-except-self/

4.1 题目要求

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。

题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。

请不要使用除法,且在 O(n) 时间复杂度内完成此题。

示例 1:

输入: nums = [1,2,3,4]
输出: [24,12,8,6]

示例 2:

输入: nums = [-1,1,0,-3,3]
输出: [0,0,9,0,0]

提示:

  • 2 <= nums.length <= 105
  • -30 <= nums[i] <= 30
  • 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内
class Solution {
    public int[] productExceptSelf(int[] nums) {

    }
}

4.2 做题思路

这个题目跟上面的 寻找数组的中心下标 思路基本上差不多,只是判断前缀和和后缀和相等的操作换成了前缀积和后缀积的乘积,这里我就不过多介绍了,大家可以直接看代码。

4.3 Java代码实现

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] f = new int[n];
        int[] g = new int[n];
        //这里需要注意前缀积的第一个元素和后缀积的最后一个元素要初始化为1,因为是乘法
        f[0] = 1;
        g[n-1] = 1;
        for(int i = 1; i < n; i++) {
            f[i] = f[i - 1] * nums[i - 1];
        }
        for(int i = n-2; i >= 0; i--) {
            g[i] = g[i + 1] * nums[i + 1];
        }
        int[] ret = new int[n];
        for(int i = 0; i < n; i++) {
            ret[i] = f[i] * g[i];
        }

        return ret;
    }
}

在这里插入图片描述

5. 和为 k 的子数组

https://leetcode.cn/problems/subarray-sum-equals-k/description/

5.1 题目要求

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数 。

示例 1:

输入:nums = [1,1,1], k = 2
输出:2

示例 2:

输入:nums = [1,2,3], k = 3
输出:2

提示:

  • 1 <= nums.length <= 2 * 104
  • -1000 <= nums[i] <= 1000
  • -107 <= k <= 107
class Solution {
    public int subarraySum(int[] nums, int k) {

    }
}

5.2 做题思路

还是先来看看暴力解法是怎样解决的?遍历数组,以数组的每一元素为起始位置,然后看以该元素为起始位置的子数组是否和为 k ,暴力解法的时间复杂度为 O(N*2)。

很多人看到这个题目首先想到的可能是 滑动窗口 ,但是我们需要仔细看题目,使用滑动窗口,需要保证窗口具有单调性,这里题目没有说数组全为非负数或者非整数,所以不能保证窗口的单调性,不能使用滑动窗口。

换个思路,它既然求的是和为 k 的子数组,我们仍然可以使用前缀和的思想,在数组的某个位置之前找到 该位置的前缀和 - k = 该位置之前的某一位置的前缀和,并且这个题目求的是 子数组的个数,我们可以配合着哈希表来进行计数。哈希表中存储的是某一位置的前缀和以及该前缀和出现的次数。

与暴力解法的思路有些许的区别,在构建前缀和数组的时候,我们不以数组中每个元素作为起始位置,而是将每个元素作为结束位置,这样更贴合我们的前缀和思想。

在这里插入图片描述

5.3 Java代码实现

class Solution {
    public int subarraySum(int[] nums, int k) {
        Map<Integer,Integer> map = new HashMap<>();
        //为了防止从0开始到某一位置的子数组的和为k,所以提前放入一个前缀和为0的键值对
        map.put(0,1);  
        int n = nums.length;
        int ret = 0,sum = 0;
        for(int i = 0; i < n; i++) {
            sum += nums[i];
            ret += map.getOrDefault(sum-k,0);
            map.put(sum,map.getOrDefault(sum,0) + 1);
        }

        return ret;
    }
}

在这里插入图片描述

6.和可被 k 整除的子数组

https://leetcode.cn/problems/subarray-sums-divisible-by-k/description/

6.1 题目要求

给定一个整数数组 nums 和一个整数 k ,返回其中元素之和可被 k 整除的(连续、非空) 子数组 的数目。

子数组 是数组的 连续 部分。

示例 1:

输入:nums = [4,5,0,-2,-3,1], k = 5
输出:7
解释:
有 7 个子数组满足其元素之和可被 k = 5 整除:
[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]

示例 2:

输入: nums = [5], k = 9
输出: 0

提示:

  • 1 <= nums.length <= 3 * 104
  • -104 <= nums[i] <= 104
  • 2 <= k <= 104
class Solution {
    public int subarraysDivByK(int[] nums, int k) {

    }
}

6.2 做题思路

在做这个题目之前,我们需要知道两个额外的知识点:

  1. 同余定理
  • 如果 (a - b) % n == 0 ,那么我们可以得到⼀个结论: a % n == b % n 。⽤⽂字叙述就是,如果两个数相减的差能被n整除,那么这两个数对n取模的结果相同。
    在这里插入图片描述
  1. 在c++和Java中对负数取模的话,结果会是一个负数,所以需要修正负数取模的结果 (a % n + n) % n(a为负数)

当知道这两个定理之后,那么这个题目的思路就跟上面的 和为 k 的子数组 思路是类似的。
在这里插入图片描述

6.3 Java代码实现

class Solution {
    public int subarraysDivByK(int[] nums, int k) {
        Map<Integer,Integer> map = new HashMap<>();
        //同样为了防止从0开始到某一位置的子数组的乘积都能被k整除
        map.put(0 % k,1);
        int n = nums.length;
        int sum = 0,ret = 0;
        for(int i = 0; i < n; i++) {
            sum += nums[i];
            int r = (sum % k + k) % k;
            ret += map.getOrDefault(r,0);
            map.put(r,map.getOrDefault(r,0) + 1);
        }

        return ret;
    }
}

在这里插入图片描述

7.连续数组

https://leetcode.cn/problems/contiguous-array/description/

7.1 题目要求

给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。

示例 1:

输入: nums = [0,1]
输出: 2
说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。

示例 2:

输入: nums = [0,1,0]
输出: 2
说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。

提示:

  • 1 <= nums.length <= 105
  • nums[i] 不是 0 就是 1
class Solution {
    public int findMaxLength(int[] nums) {

    }
}

7.2 做题思路

因为数组中只有二进制数,也就是0和1,我们可以将0当成是-1,当子数组中0和1的数量相同的时候,子数组的和为0。所以这个题目也就相当于求长度最长的和为0的子数组。所以我们哈希表中存储的就是前缀和以及数组的下标。

7.3 Java代码实现

class Solution {
    public int findMaxLength(int[] nums) {
        Map<Integer,Integer> map = new HashMap<>();
        map.put(0,-1);
        int n = nums.length;
        int ret = 0,sum = 0;
        for(int i = 0; i < n; i++) {
            sum += (nums[i] == 0 ? -1 : 1);
            if(map.containsKey(sum)) ret = Math.max(ret,i-map.getOrDefault(sum,0));
            else map.put(sum,i);
        }

        return ret;
    }
}

在这里插入图片描述

8.矩阵区域和

https://leetcode.cn/problems/matrix-block-sum/description/

8.1 题目要求

给你一个 m x n 的矩阵 mat 和一个整数 k ,请你返回一个矩阵 answer ,其中每个 answer[i][j] 是所有满足下述条件的元素 mat[r][c] 的和:

  • i - k <= r <= i + k,
  • j - k <= c <= j + k 且
  • (r, c) 在矩阵内。

示例 1:

输入:mat = [[1,2,3],[4,5,6],[7,8,9]], k = 1
输出:[[12,21,16],[27,45,33],[24,39,28]]

示例 2:

输入:mat = [[1,2,3],[4,5,6],[7,8,9]], k = 2
输出:[[45,45,45],[45,45,45],[45,45,45]]

提示:

  • m == mat.length
  • n == mat[i].length
  • 1 <= m, n, k <= 100
  • 1 <= mat[i][j] <= 100
class Solution {
    public int[][] matrixBlockSum(int[][] mat, int k) {

    }
}

8.3 做题思路

这个题目跟上面的【模板】二维前缀和是类似的,只是这个题目需要我们找到对应的矩阵。
在这里插入图片描述
需要注意的是,题目中的 r 和 c 都是从0开始的,也就是说,可能会出现数组越界的情况,这道题题目的重点就是需要处理下标越界的情况。那么如何处理下标越界的情况呢?很简单,前面的不是有从下标1开始的吗?当我们构建前缀和数组的时候,我们也可以将数组下标以1开始,然后在最终结果的数组中填入数据的时候注意下标的映射关系就行了。

8.3 Java代码实现

class Solution {
    public int[][] matrixBlockSum(int[][] mat, int k) {
        int n = mat.length;
        int m = mat[0].length;
        int[][] dp = new int[n + 1][m + 1];
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + mat[i - 1][j - 1] - dp[i - 1][j - 1];
            }
        }
        
        int[][] ret = new int[n][m];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
            //处理下标越界问题,并且解决了下标的映射关系
                int x1 = Math.max(0,i-k) + 1,y1 = Math.max(0,j - k) + 1;
                int x2 = Math.min(n - 1,i + k) + 1,y2 = Math.min(m - 1,j  + k) + 1;
                ret[i][j] = dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1];
            }
        }

        return ret;
    }
}

在这里插入图片描述

总结

通过前缀和算法,我们可以在O(1)的时间复杂度内计算出任意区间的元素和。这在处理大规模数据时非常有用,可以大大提高计算效率。

总结起来,前缀和算法是一种高效计算数组区间和的方法。它通过计算数组的前缀和,可以在O(1)的时间复杂度内得到任意区间的元素和。在实际应用中,前缀和算法经常用于解决数组区间和相关的问题,例如子数组的最大和、子数组的平均值等。通过掌握前缀和算法,我们可以更加高效地解决这类问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【算法系列篇】前缀和 的相关文章

  • 若依系统注册功能

    加油 三步实现注册 前端 后端 分配角色 总结 前端 login vue中打开注册开关 后端 打开数据库sys config表 开启注册功能 分配角色 在SysUserMapper中添加方法 实现方法 在SysUserServiceImpl
  • dialog中二维码显示问题

    由于dialog加载过程会耗费一定时间 因此在dialog中直接调用会导致在一次打开的dialog无法加载二维码 在dialog标签中加入 opened ShowQRCode 属性 opened是dialog动画打开完毕之后的回调 当页面加
  • 计算机网络层提供的面向连接服务还是无连接服务讨论与思考

    概要 在计算机网络领域 网络层应该向运输层提供怎样的服务 面向连接 还是 无连接 曾引起了长期的争论 争论焦点的实质就是 在计算机通信中 可靠交付应当由谁来负责 是网络还是端系统 介绍 有些人认为应当借助于电信网的成功经验 让网络负责可靠交

随机推荐

  • 计算机主机名与用户名区别

    一 主机名概念 主机名就是计算机的名字 计算机名 网上邻居就是根据主机名来识别的 这个名字可以随时更改 从我的电脑属性的计算机名就可更改 用户登陆时候用的是操作系统的个人用户帐号 这个也可以更改 从控制面板的用户界面里改就可以了 这个用户名
  • 1. Inna and Pink Pony

    1 Inna and Pink Pony 首先找出四个边界点 但要注意当横纵坐标等于边界横纵坐标时 需考虑是否会出界 满足以上条件时 考虑横纵坐标移动次数其和为偶数时便可以完成移动 因为正负抵消原则 话不多说 直接上Python代码 n m
  • 解决 CommandNotFoundError: Your shell has not been properly configured to use ‘conda activate’问题

    针对使用conda进入虚拟环境时遇到的问题 CommandNotFoundError Your shell has not been properly configured to use conda activate 解决方法 win r
  • 解决Android中使用RecyclerView滑动时底部item显示不全的问题

    感觉这个bug是不是因人而异啊 找了很多文章都没能解决我的问题 包括在RecyclerView上在嵌套上一层RelativeLayout 添加属性android descendantFocusability blocksDescendant
  • 解决“L6200E Symbol xx defined (by xx.o and xx.o)”重复定义问题

    今天来分享一个关于自己之前遇到的一个问题 就是关于重复定义会造成的一个错误 错误提示为 OBJ LCD axf Error L6200E Symbol ascii 1206 multiply defined by lcd user o an
  • C语言每日一题:7.寻找数组中心下标。

    思路一 暴力求解 1 定义一个ps作为中间下标去记录下标值 2 循环下标ps从头到位 定义四个变量分别是left sum left right sum right 3 初始化left ps 1和right ps 1 当ps0 gt 就让su
  • etcd学习和实战:4、Java使用etcd实现服务发现和管理

    etcd学习和实战 4 Java使用etcd实现服务发现和管理 文章目录 etcd学习和实战 4 Java使用etcd实现服务发现和管理 1 前言 2 代码 2 1 服务注册 2 2 服务发现 2 3 运行结果 2 4 问题 3 最后 1
  • 关于SVM的一点笔记

    关于SVM的一点笔记 一 简单了解 1 感知机 perceptron 感知机是一种类似于生物中神经细胞功能的人工神经元 它可以把一个或者多个输入 x 1 x 1 x1 x
  • flask最基础的增删改查实现步骤及代码

    分类序列化器 写入要序列化的字段 user info id fields Integer name fields String 商品序列化器 写入要序列化的字段 goods info id fields Integer name field
  • Spring系列面试题(Spring、SpringMvc、SpringBoot)

    一 springboot自动配置原理 自动装配 简单来说就是自动把第三方组件的Bean装载到Spring IOC器里面 不需要开发人员再去写Bean的配置 在Spring Boot应用里面 只需要在启动类加上 SpringBootAppli
  • 五张图带你理解 RocketMQ 顺序消息实现机制

    大家好 我是君哥 今天聊一聊 RocketMQ 的顺序消息实现机制 在有些场景下 使用 MQ 需要保证消息的顺序性 比如在电商系统中 用户提交订单 支付订单 订单出库这 3 个消息应该保证顺序性 如下图 对于 RocketMQ 来说 主要是
  • Electron桌面开发入门

    1 初始化工作 midir electron demo cd electron demo npm init 到package json 文件下将入口文件修改为main js main main js 并且创建main js文件 electr
  • Java猫和狗(继承,多态,抽象,接口版)上

    Java的继承 抽象 多态 接口的简单应用 我们利用 猫和狗都是动物类 然后猫会抓鱼 狗会看门的这些方法来简单应用一下继承 抽象 多态 接口 简单思路就是 1 定义动物类 2 定义猫 狗类 让他们成为动物的子类 3 编写测试类 继承 使子类
  • PTA L1-016:查验身份证 (python)

    一 题目要求 二 参考代码 sheet 0 1 1 0 2 X 3 9 4 8 5 7 6 6 7 5 8 4 9 3 10 2 w 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 n int input c 0 f
  • ARM单片机FATFS文件系统的移植

    ARM单片机FATFS文件系统的移植 测试效果 前提条件 下载所需源码 FATFS 文件系统 SFUD万能驱动 加入工程 接口驱动 测试代码 FreeRTOS10 0 1 FATFS FF14A SFUD V1 1 0 STM32F103Z
  • 超过2t硬盘分区_大于2T的磁盘怎么分区呢?

    由于购买了磁盘柜专门用作存储 后来考虑到磁盘容量的动态管理 准备采用LVM进行动态扩容管理了 首先让前端挂载机器能够识别到磁盘柜的逻辑卷组 比如 dev sdb 先介绍2种分区表 MBR分区表 MBR含义 主引导记录 所支持的最大卷 2T
  • 6.8过程纹理

    过程纹理也称为自定义纹理 根据计算得出 这个例子使用了位置和原点的距离作为输入参数 并加入了动画 但是和目前的纹理没任何关系 纯手工计算 因为位置是三维的 所以在涉及到纹理的几个地方都要改为三维的 struct RENDEROBJECT D
  • Java中的&、&&、

    关于这几个的运算符我一代码的实例来介绍 如下 1 首先它们都是逻辑运算符 但是 和 是短路运算符 也就是只判断运算符左边的即可 就可以确定整个表达式的结果了 所以它的执行效率高于 和 因为这两个运算符需要将表达式中所有的boolean值都判
  • JAVA开发(行业现状与未来)

    JAVA开发行业经过了这么多年的发展 曾经从一个机顶盒程序起家 到超过3亿台以上设备都在运行JAVA程序 JAVA语言见证了整个互联网化的工业化过程 许许多多的东西从从传统模式搬到了线上 特别是电子商务和网络社交的发展 大量的资金投入的这个
  • 【算法系列篇】前缀和

    文章目录 前言 什么是前缀和算法 1 模板 前缀和 1 1 题目要求 1 2 做题思路 1 3 Java代码实现 2 模板 二维前缀和 2 1 题目要求 2 2 做题思路 2 3 Java代码实现 3 寻找数组的中心下标 3 1 题目要求