主頁 > 後端開發 > 動態規劃篇——背包問題

動態規劃篇——背包問題

2022-11-24 06:49:05 後端開發

動態規劃篇——背包問題

本次我們介紹動態規劃篇的背包問題,我們會從下面幾個角度來介紹:

  • 背包問題概述
  • 零一背包問題
  • 完全背包問題
  • 多重背包問題
  • 分組背包問題

背包問題概述

背包問題算是很經典的動態規劃問題,我們在面試中也經常出現

首先我們給出動態規劃的思想:

然后我們簡單介紹一下背包問題:

/*背包問題*/

有 N 件物品和一個容量是 V 的背包,

第 i 件物品的體積是 vi,價值是 wi,

求解將哪些物品裝入背包,可使這些物品的總體積不超過背包容量,且總價值最大,輸出最大價值,

/*輸入格式*/
    
第一行兩個整數,N,V,用空格隔開,分別表示物品數量和背包容積,

接下來有 N 行,每行兩個整數 vi,wi,用空格隔開,分別表示第 i 件物品的體積和價值,

/*輸出格式*/
    
輸出一個整數,表示最大價值,

最后我們介紹我們下列將要講述了背包問題的前提:

/*01背包問題*/

每件物品只能使用一次
    
/*完全背包問題*/
    
每件物品無次數限制使用
    
/*多重背包問題*/
    
每件物品有不同的使用次數
    
/*分組背包問題*/
    
每組物品有若干個,同一組內的物品最多只能選一個

零一背包問題

我們首先介紹一下01背包規則:

/*背包問題*/

有 N 件物品和一個容量是 V 的背包,

第 i 件物品的體積是 vi,價值是 wi,

求解將哪些物品裝入背包,可使這些物品的總體積不超過背包容量,且總價值最大,輸出最大價值,

/*輸入格式*/
    
第一行兩個整數,N,V,用空格隔開,分別表示物品數量和背包容積,

接下來有 N 行,每行兩個整數 vi,wi,用空格隔開,分別表示第 i 件物品的體積和價值,

/*輸出格式*/
    
輸出一個整數,表示最大價值,
    
/*限制條件*/
    
每件物品只能使用一次

然后我們對其進行分析:

/*內容分析*/

首先我們有 N 件物品,總容量為 V
    
如果我們想要求得最大 W 的情況,我們就需要計算所有的 N 和 V 情況
    
/*暴力求解方法分析*/
    
我們這里首先采用最暴力的方法(二維):
    
我們采用f[i][j]來表示前i件物品中進行選擇,其體積不超過j,儲存值為W最優解
    
我們會發現,f[i][j]無非就兩種情況:
    在i比前一位增加一位后,如果我們當前的i沒有包含最后一位,那么一切都和上一位i的結果相同(f[i][j] = f[i-1][j])
    那么我們就只需要判斷是否需要加上第i位,且前提是j >= v[i](f[i][j] = max(f[i][j],f[i-1][j-v[i]]+w[i]))
    	
/*優化方法分析*/
 
下面我們介紹的優化方法來自于滾動陣列:
    滾動陣列是指當我們只需要兩行資料時,我們可以拋出二維的概念,采用層級差來覆寫掉之前的資料資訊,從而轉換為一維
    
我們對上述暴力求解進行分析:
    我們會發現其實我們所采用的無非只有兩行:f[i]和f[i-1]
    那么我們只需要將f[i]所使用的f[i-1]的資訊在使用前保留下來,我們就可以將其簡化為一行,也就是一維

我們給出實際代碼以及代碼中的決議:

/*暴力求解方法*/

import java.util.Scanner;

public class Packsack01 {

    final static int N = 1010;

    static int n,m;

    // 存放f[][],v[],w[]
    static int[][] f = new int[N][N];
    static int[] v = new int[N];
    static int[] w = new int[N];

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        
        n = scanner.nextInt();
        m = scanner.nextInt();
        
        // 首先我們應該初始化f[][],但是由于需要初始化為0,陣列默認為0,所以我們不需要書寫
        
        // 然后我們放入v,w
        for (int i = 1; i <= n; i++) {
            v[i] = scanner.nextInt();
            w[i] = scanner.nextInt();
        }
        
        // 然后我們就可以逐層更新(第0層為前0個物品,肯定都是0,不用更新)
        for (int i = 1; i <= n; i++) {
            // 我們對前i個物品的體積v也進行遞增
            for (int j = 0; j <= m; j++) {
                
                // 如果我們不加入最后一個數,那么當前i層的值和i-1層的值相同
                f[i][j] = f[i-1][j];
                
                // 注意:由于加入第i個數不一定是最優解,所以我們需要進行w權重比較
                // 我們比較的資料分別是上一層的不加i的w
                // 注意這里由于上面f[i][j] = f[i-1][j],所以下面的f[i][j]實際上是上一層的f[i-1][j]
                // 以及我們該層加上i之后的w,我們加上i之后v就需要去掉v[i]
                // 同時我們選取前i-1個數的v為j-[v[i]]的w最優解加上w[i]來進行比較
                if (j >= v[i]) f[i][j] = Math.max(f[i][j],f[i-1][j-v[i]]+w[i]);
            }
        }

        // 最后輸出即可
        System.out.println(f[n][m]);
    }

}

/*優化求解方法*/

import java.util.Scanner;

public class Packsack01 {

    final static int N = 1010;

    static int n,m;

    // 存放f[],v[],w[]
    static int[] f = new int[N];
    static int[] v = new int[N];
    static int[] w = new int[N];


    // 建議和暴力求解對比觀看
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        
        n = scanner.nextInt();
        m = scanner.nextInt();
        
        // 首先我們應該初始化f[],但f[0]最開始都是0,就不需要初始化了

        // 然后我們放入v,w
        for (int i = 1; i <= n; i++) {
            v[i] = scanner.nextInt();
            w[i] = scanner.nextInt();
        }
        
        // 然后我們就可以逐層更新
        for (int i = 1; i <= n; i++) {
            // 我們對前i個物品的體積v也進行遞增
            // 注意:由于下面判斷條件需要保證j>=v[i],所以我們這里可以直接從v[i]開始,畢竟前面的條件都不滿足
            // 注意:我們這里需要倒敘書寫, 因為我們下面要使用f[i-1][j-v[i]]這里的i-1就是上一層,我們需要注意我們不能覆寫掉這一層!!!
            for (int j = m; j >= v[i]; j--) {

                // 這里簡化i之后,為f[j] = f[j],恒等式,我們就直接省略了

                // 注意:由于加入第i個數不一定是最優解,所以我們需要進行w權重比較
                // 我們比較的資料分別是上一個不加i的w
                // 以及我們該層加上i之后的w,我們加上i之后v就需要去掉v[i]
                // 同時我們選取前i-1個數的v為j-[v[i]]的最優解來進行比較,記得加上w[i]
                
                // 這里我們需要注意,我們后面比較的值是上一層的f
                // 所以我們前面的for回圈的方向需要轉換一下,防止上一層的資料被覆寫掉
                f[j] = Math.max(f[j],f[j-v[i]]+w[i]);
            }
        }

        // 最后輸出即可
        System.out.println(f[m]);
    }

}

完全背包問題

我們首先介紹一下完全背包規則:

/*背包問題*/

有 N 件物品和一個容量是 V 的背包,

第 i 件物品的體積是 vi,價值是 wi,

求解將哪些物品裝入背包,可使這些物品的總體積不超過背包容量,且總價值最大,輸出最大價值,

/*輸入格式*/
    
第一行兩個整數,N,V,用空格隔開,分別表示物品數量和背包容積,

接下來有 N 行,每行兩個整數 vi,wi,用空格隔開,分別表示第 i 件物品的體積和價值,

/*輸出格式*/
    
輸出一個整數,表示最大價值,
    
/*限制條件*/
    
每件物品沒有使用次數限制

然后我們對其進行分析:

/*內容分析*/

首先我們有 N 件物品,總容量為 V
    
如果我們想要求得最大 W 的情況,我們就需要計算所有的 N 和 V 情況
    
/*暴力求解方法分析*/
    
我們首先介紹暴力求解方法:

我們其實所有步驟和01背包的步驟相似,但不同的是對于第i個物品的數量的大小的決定
    
我們在不能承載第i個物品前:f[i][j] = f[i-1][j]
 
在我們能承載第i個物品后:f[i][j] = Math.max(f[i-1][j],f[i-1][j - k*v[i]] + k * w[i])
    
所以我們只需要在01背包基礎上加上一個fork回圈來控制第i個物品的數量保證最優解即可
    	
/*優化方法1分析*/
    
我們在上述暴力求解中直接采用了fork回圈,這時我們的時間復雜度在 O(n^3),所以我們想要減少時間復雜度
    
我們可以發現,我們上述承載第i個物品后:f[i][j] = Math.max(f[i-1][j],f[i-1][j - k*v[i]] + k * w[i])
    
那么相當于:f[i][j] = Math.max(f[i-1][j],f[i-1][j-v[i]]+w[i],f[i-1][j-2*v[i]]+2*w[i],...)
    
相當于我們直接在上一個f[i][j]的基礎上判斷是否能夠添加i物品,也就是:f[i][j] = Math.max(f[i][j],f[i][j-v[i]]+w[i])

/*優化方法2分析*/
    
最后一重優化其實就是01背包的優化,我們轉化為滾動陣列即可    
    
下面我們介紹的優化方法來自于滾動陣列:
    滾動陣列是指當我們只需要兩行資料時,我們可以拋出二維的概念,采用層級差來覆寫掉之前的資料資訊,從而轉換為一維
    
我們對上述暴力求解進行分析:
    我們會發現其實我們所采用的無非只有兩行:f[i]和f[i-1]
    那么我們只需要將f[i]所使用的f[i-1]的資訊在使用前保留下來,我們就可以將其簡化為一行,也就是一維

我們給出實際代碼以及代碼中的決議:

/*暴力求解演算法*/

import java.util.Scanner;

public class PacksackFull {

    final static int N = 1010;

    static int n,m;

    static int[][] f = new int[N][N];
    static int[] v = new int[N];
    static int[] w = new int[N];

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        n = scanner.nextInt();
        m = scanner.nextInt();

        for (int i = 1; i <= n; i++) {
            v[i] = scanner.nextInt();
            w[i] = scanner.nextInt();
        }


        for (int i = 1; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                // 重點在這里!!!
                // 我們之前的f[i][j] = f[i-1][j]也融入到下面的max判斷里去了
                // 我們由于需要判斷第i個物品的數量,我們需要從0開始,判斷應該增加幾個i物品
                for (int k = 0; k * v[i] <= j; k++) {
                    f[i][j] = Math.max(f[i][j],f[i-1][j-v[i]*k]+w[i]*k);
                }
            }
        }

        System.out.println(f[n][m]);
    }

}

/*優化演算法1*/

import java.util.Scanner;

public class PacksackFull {

    final static int N = 1010;

    static int n,m;

    static int[][] f = new int[N][N];
    static int[] v = new int[N];
    static int[] w = new int[N];

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        n = scanner.nextInt();
        m = scanner.nextInt();

        for (int i = 1; i <= n; i++) {
            v[i] = scanner.nextInt();
            w[i] = scanner.nextInt();
        }


        for (int i = 1; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                // 我們為了減少一層回圈,我們直接將f[i][j]與前面的f[i][j]比較即可

                // 注意:記得先給當前f[i][j]賦值
                f[i][j] = f[i-1][j];

                // 然后我們才能進行比較,我們將f[i-1][j]與f[i]層的比較(記得判斷是否可以加v[i]!)
                if(j >= v[i]) f[i][j] = Math.max(f[i][j],f[i][j-v[i]]+w[i]);
            }
        }

        System.out.println(f[n][m]);
    }

}

/*優化演算法2*/

import java.util.Scanner;

public class PacksackFull {

    final static int N = 1010;

    static int n,m;

    static int[] f = new int[N];
    static int[] v = new int[N];
    static int[] w = new int[N];

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        n = scanner.nextInt();
        m = scanner.nextInt();

        for (int i = 1; i <= n; i++) {
            v[i] = scanner.nextInt();
            w[i] = scanner.nextInt();
        }


        for (int i = 1; i <= n; i++) {
            // 注意:由于這次我們使用的是第i層的資料,所以我們需要從前往后遍歷提前更新第i層資料,防止使用第i-1層資料
            for (int j = v[i]; j <= m; j++) {
                if(j >= v[i]) f[j] = Math.max(f[j],f[j-v[i]]+w[i]);
            }
        }

        System.out.println(f[m]);
    }

}

多重背包問題

我們首先介紹一下多重背包規則:

/*背包問題*/

有 N 件物品和一個容量是 V 的背包,

第 i 種物品最多有 si 件,每件體積是 vi,價值是 wi,

求解將哪些物品裝入背包,可使這些物品的總體積不超過背包容量,且總價值最大,輸出最大價值,

/*輸入格式*/
    
第一行兩個整數,N,V,用空格隔開,分別表示物品數量和背包容積,

接下來有 N 行,每行三個整數 vi,wi,si,用空格隔開,分別表示第 i 種物品的體積、價值和數量,

/*輸出格式*/
    
輸出一個整數,表示最大價值,
    
/*限制條件*/
    
每個物品有一定的使用次數限制

然后我們對其進行分析:

/*內容分析*/

首先我們有 N 件物品,總容量為 V
    
如果我們想要求得最大 W 的情況,我們就需要計算所有的 N 和 V 情況
    
/*暴力求解方法分析*/
    
其實暴力求解方法和完全背包問題暴力求解方法完全相同
    
只不過是在k的限制條件上多加了一個k < s[i]的限制而已
    	
/*優化方法分析*/
    
我們需要注意多重背包優化由于有數量限制的原因,無法使用完全背包優化!
    
我們因為多重背包有數量限制,當數量較少時,我們采用暴力求解是沒有問題的,但是當s數量過多,高達一兩千就會導致問題
    
我們的優化思路是
    通過將該物品打包分類為多個新的物品,重新定義這些物品的v和w,s固定為1
    我們選擇2的n次冪來打包物品,因為2的n次冪相加可以組成2的n+1次冪內的所有數!

我們給出實際代碼以及代碼中的決議:

/*暴力求解演算法*/

import java.util.Scanner;

public class PacksackNumber {

    final static int N = 1010;

    static int n,m;

    // 多添加一個s陣列存放個數
    static int[][] f = new int[N][N];
    static int[] v = new int[N];
    static int[] w = new int[N];
    static int[] s = new int[N];

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        n = scanner.nextInt();
        m = scanner.nextInt();

        for (int i = 1; i <= n; i++) {
            v[i] = scanner.nextInt();
            w[i] = scanner.nextInt();
            s[i] = scanner.nextInt();
        }


        for (int i = 1; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                // 重點在這里!!!
                // 我們只需要多一個條件 k <= s[i]即可
                for (int k = 0; k <= s[i] && k * v[i] <= j; k++) {
                    f[i][j] = Math.max(f[i][j],f[i-1][j-v[i]*k]+w[i]*k);
                }
            }
        }

        System.out.println(f[n][m]);
    }

}

/*優化演算法*/

import java.util.Scanner;

public class PacksackNumber {

    // 因為是二進制,一個數最多就是2的12次方就會超過題目給的2000,所以給個將限制范圍1000*12
    final static int N = 12000;

    static int n,m;

    // 這里的f采用一維即可,因為最后我們會轉變為01問題,可以采用滾動陣列優化
    static int[] f = new int[N];
    
    // 我們這里只需要記錄v,w即可,因為我們會根據輸入的資料重新更新v,w,不再存在s的概念
    static int[] v = new int[N];
    static int[] w = new int[N];

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        n = scanner.nextInt();
        m = scanner.nextInt();

        // 表示定義到第幾個資料
        int cnt = 0;
        
        // 我們根據輸入的資料重新定義v,w
        for (int i = 1; i <= n; i++) {
            // a是v,b是w,s是數量
            int a = scanner.nextInt();
            int b = scanner.nextInt();
            int s = scanner.nextInt();
            
            // 我們根據2的k次冪來劃分s,重新分成物品
            int k = 1;// 相當于2的0次冪
            
            // 一直更新到無法存放k
            while ( k <= s){
                // 更新資料位置
                cnt++;
                // 將資料存入
                v[cnt] = a * k;
                w[cnt] = b * k;
                // 數量減去已存放的k,并且k翻倍(2次冪)
                s -= k;
                k *= 2;
            }
            
            // 判斷是否有剩余元素
            if (s > 0){
                // 若存放剩余元素,我們還需要存放
                cnt ++;
                v[cnt] = a * s;
                w[cnt] = b * s;
            }
        }
        
        // 我們目前擁有cnt個新物品(被我們分解的)
        n = cnt;
        
        // 我們對新物品進行裝載即可(01背包)
        for (int i = 1; i <= n; i++) {
            for (int j = m; j >= v[i] ; j--) {
                f[j] = Math.max(f[j],f[j - v[i]] + w[i]);
            }
        }

        System.out.println(f[m]);
    }
}

分組背包問題

我們首先介紹一下分組背包規則:

/*背包問題*/
    
有 N 組物品和一個容量是 V 的背包,
    
每件物品的體積是 vij,價值是 wij,其中 i 是組號,j 是組內編號,

求解將哪些物品裝入背包,可使物品總體積不超過背包容量,且總價值最大,輸出最大價值,

/*輸入格式*/
    
第一行有兩個整數 N,V,用空格隔開,分別表示物品組數和背包容量,

接下來有 N 組資料:

每組資料第一行有一個整數 Si,表示第 i 個物品組的物品數量;
    
每組資料接下來有 Si 行,每行有兩個整數 vij,wij,用空格隔開,分別表示第 i 個物品組的第 j 個物品的體積和價值;

/*輸出格式*/
    
輸出一個整數,表示最大價值,
    
/*限制條件*/
    
每組物品有若干個,同一組內的物品最多只能選一個,

然后我們對其進行分析:

/*內容分析*/

首先我們有 N 組物品,總容量為 V
    
如果我們想要求得最大 W 的情況,我們就需要計算所有的 N組物品中每種物品使用 和 V 情況

/*求解方法分析*/
    
我們同樣采用一層迭代一層的原則,但由于每組商品只能選擇一次,所以我們在f[i][j]的情況下,需要與第i組的所有物品互動判斷一次
    
同樣我們由于f[i]只利用f[i-1]層原理,我們可以采用滾動陣列的原理來將二維陣列變為一維陣列

我們給出實際代碼以及代碼中的決議:

/*已優化演算法*/

import java.util.Scanner;

public class Packsack01 {
    final static int N = 110;

    static int n,m;

    // 這里的f采用一維即可
    static int[] f = new int[N];

    // 我們這里使用了分組概念,需要二維陣列記錄資訊
    static int[][] v = new int[N][N];
    static int[][] w = new int[N][N];

    // s這里記錄該組的個數
    static int[] s = new int[N];

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        n = scanner.nextInt();
        m = scanner.nextInt();

        // 對分組輸入資料
        for (int i = 1; i <= n; i++) {
            // 記錄該組數量
            s[i] = scanner.nextInt();
            for (int j = 1; j <= s[i]; j++) {
                // 記錄v,w
                v[i][j] = scanner.nextInt();
                w[i][j] = scanner.nextInt();
            }
        }

        // 開始遍歷即可
        for (int i = 1; i <= n; i++) {
            for (int j = m; j >= 0; j--) {
                for (int k = 0;k <= s[i]; k++) {
                    if (v[i][k] <= j){
                        f[j] = Math.max(f[j],f[j - v[i][k]] + w[i][k]);
                    }
                }
            }
        }

        System.out.println(f[m]);
    }
}

結束語

好的,關于動態規劃篇的背包問題就介紹到這里,希望能為你帶來幫助~

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/538123.html

標籤:Java

上一篇:IDEA專案下out與target目錄的區別詳解

下一篇:JVM運行資料區深度決議

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more