算法之回溯

news2024/11/24 9:24:34

在这里插入图片描述

  • 我最近开了几个专栏,诚信互三!
    ====> |||《算法专栏》::刷题教程来自网站《代码随想录》。|||
    ====> |||《C++专栏》::记录我学习C++的经历,看完你一定会有收获。|||
    ====> |||《Linux专栏》::记录我学习Linux的经历,看完你一定会有收获。|||
    ====> |||《C#专栏》::记录我复习C#的经历,深度理解查漏补缺,不定期更新。|||

回溯算法

  • 什么是回溯
  • 回溯算法能解决什么问题
  • 回溯算法经典OJ

什么是回溯

回溯是一种暴力搜索的算法,回溯算法通过循环控制树的宽度,递归调用控制树的深度,来收集满足条件的集合。

回溯算法能解决什么问题

1.排列组合
2.组合总和
3.分割字串
4.子集

回溯算法经典OJ

1.排列组合问题

组合问题的分析组合及每层选的值以及该值的左边所有值下一层则不能在被选择,为了控制选值,则需要startIndex来索引下标,并根据条件收集和返回结果。
排列问题的分析排列问题每层都可以取除了上一层选择的值之外的所有值,所以一般不需要startIndex控制索引,而需要hash表记住上一层所选择的值。
剪枝:剪枝操作要根据题目的收集结果条件进行剪枝,一般都在for循环的判断部分进行剪枝。

组合
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

问题分析:该题要求返回组合,则需要startIndex控制索引防止重复选取,同时返回条件是当收集到2个结果返回。

int* result;// - 结果数组
int arrTop;// - 控制返回数组的下标
int top;// - 控制结果数组的下标
int** arr;// - 结果数组

void BackTracking(int n, int k, int** arr, int index)
{
    if(top == k)// - 满足条件返回
    {
        int* tmp = (int*)malloc(sizeof(int)*k);
        for(int i = 0; i < k; i++)
        {
            tmp[i] = result[i];
        }
        arr[arrTop++] = tmp;
        return;

    }
    for(int i = index; i <= n; i++)
    {
        result[top++] = i;
        BackTracking(n,k,arr,i+1);
        // - 回溯
        top--;
    }

}



int** combine(int n, int k, int* returnSize, int** returnColumnSizes) 
{
        arr = (int**)malloc(sizeof(int*)*10000);
        result = (int*)malloc(sizeof(int)*k);

        arrTop = top = 0;
        BackTracking(n,k,arr,1);
        *returnSize = arrTop;// - 返回arr数组有多少行

        *returnColumnSizes = (int*)malloc(sizeof(int)*(*returnSize));// - 返回arr数组每列有多少个元素。
        for(int i = 0; i < *returnSize; i++)
        {
            (*returnColumnSizes)[i] = k;

        }
        return arr;
}

剪枝:本题要求收集到k个值就返回,若接下来收集的元素最大值都收集不到k个,则就不用遍历了。
result数组中有Top个元素,所需需要的元素个数为: k - Top;
列表中剩余元素(n-i) >= 所需需要的元素个数(k - Top)
在集合n中至多要从该起始位置 : i <= n - (k - Top) + 1,开始遍历

 for(int i = index; i <= n - (k-Top)+1; i++)

全排列

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

问题分析:不含重复数子,则代表不存在两个结果相同,但是所对应的下标不同,则不需要在每层去重,要返回全排列,返回条件就是rTop的值是numsSize,并且该问题为排列问题,可以重选。

int* path;
int pathTop;
int** ans;
int ansTop;

//将used中元素都设置为0
void initialize(int* used, int usedLength) {
    int i;
    for(i = 0; i < usedLength; i++) {
        used[i] = 0;
    }
}

//将path中元素拷贝到ans中
void copy() {
    int* tempPath = (int*)malloc(sizeof(int) * pathTop);
    int i;
    for(i = 0; i < pathTop; i++) {
        tempPath[i] = path[i];
    }
    ans[ansTop++] = tempPath;
}

void backTracking(int* nums, int numsSize, int* used) 
{
    //若path中元素个数等于nums元素个数,将nums放入ans中
    if(pathTop == numsSize) {
        copy();
        return;
    }
    int i;
    for(i = 0; i < numsSize; i++) {
        //若当前下标中元素已使用过,则跳过当前元素
        if(used[i])
            continue;
        used[i] = 1;
        path[pathTop++] = nums[i];
        backTracking(nums, numsSize, used);
        //回溯
        pathTop--;
        used[i] = 0;
    }
}

int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    //初始化辅助变量
    path = (int*)malloc(sizeof(int) * numsSize);
    ans = (int**)malloc(sizeof(int*) * 1000);
    int* used = (int*)malloc(sizeof(int) * numsSize);
    //将used数组中元素都置0
    initialize(used, numsSize);
    ansTop = pathTop = 0;

    backTracking(nums, numsSize, used);

    //设置path和ans数组的长度
    *returnSize = ansTop;
    *returnColumnSizes = (int*)malloc(sizeof(int) * ansTop);
    int i;
    for(i = 0; i < ansTop; i++) {
        (*returnColumnSizes)[i] = numsSize;
    }
    return ans;
}

2.组合总和问题

组合总和问题的分析组合及每层选的值以及该值的左边所有值下一层则不能在被选择,为了控制选值,则需要startIndex来索引下标,并根据条件收集和返回结果。
剪枝:剪枝操作要根据题目的收集结果条件进行剪枝,组合总和问题一般通过排序+和下一层的元素相加来剪枝,一般都在for循环的判断部分进行剪枝。

组合总和 III
找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:

  • 只使用数字1到9
  • 每个数字 最多使用一次

返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

问题分析:该问题为组合问题,数字为1-9,则代表数字有序,要收集相加和为n的k个整数集合,则不满足这个条件直接返回。

int* result;
int rTop;
int aTop;


void BackTracking(int k, int n, int startIndex, int sum, int** arr)
{
    // - 剪枝
    if(rTop == k) 
    {
        if(sum == n) {
            int* tempPath = (int*)malloc(sizeof(int) * k);
            int j;
            for(j = 0; j < k; j++)
                tempPath[j] = result[j];
            arr[aTop++] = tempPath;
        }
        return;
    }
    // - 剪枝
    else if(rTop != k && sum >= n)
    {
        return;
    }
    for(int j = startIndex; j <=9; j++)
    {
        sum+=j;
        result[rTop++] = j;
        BackTracking(k,n,j+1,sum,arr);
        rTop--;
        // - 组合总和问题要注意每层回溯要-=结果数组内容。
        sum-=j;

    }


}

int** combinationSum3(int k, int n, int* returnSize, int** returnColumnSizes) 
{
    int** arr = (int**)malloc(sizeof(int*)*1000);
        //初始化辅助变量
    result = (int*)malloc(sizeof(int) * k);
    rTop = aTop = 0;

    BackTracking(k, n, 1, 0,arr);

    //设置返回的二维数组中元素个数为ansTop
    *returnSize = aTop;
    //设置二维数组中每个元素个数的大小为k
    *returnColumnSizes = (int*)malloc(sizeof(int) * aTop);
    int i;
    for(i = 0; i < aTop; i++) {
        (*returnColumnSizes)[i] = k;
    }
    return arr;

}

剪枝:该题依旧对数量有限制,则可以用组合问题的剪纸方法进行剪枝

 for(int i = index; i <= 9 - (k-Top)+1; i++)

组合总和
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

问题分析:该问题为组合问题,同一个数子课重复使用,找出和为target的值。

int** arr;
int* result;
int rTop;
int aTop;
int* length;

void BackTracking(int sum, int target, int* candidates, int n, int startIndex)
{
    // - sum > target返回
    if(sum > target)
        return;
    // - 等于target收集数据
    if(sum == target)
    {
        int* tmp = (int*)malloc(sizeof(int)*rTop);
        for(int i = 0; i < rTop; i++)
        {
            tmp[i] = result[i];
        }
        arr[aTop] = tmp;
        length[aTop++] = rTop;
        return;
    }
    // - 改题目需要的是组合,所以不用遍历遍历过的
    for(int j = startIndex; j < n; j++)
    {
        
        sum+=candidates[j];
        result[rTop++] = candidates[j];
        BackTracking(sum,target,candidates,n,j);
        rTop--;
        // - sum 要-;
        sum-=candidates[j];

    }

}

int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes) 
{
    length = (int*)malloc(sizeof(int)*200);
    arr = (int**)malloc(sizeof(int*)*1000);
    result = (int*)malloc(sizeof(int)*100);
    rTop = aTop = 0;
    int sum = 0;
    BackTracking(sum, target,candidates,candidatesSize,0);
    *returnSize = aTop;
    *returnColumnSizes = (int*)malloc(sizeof(int)*aTop);
      int i;
    for(i = 0; i < aTop; i++) {
        (*returnColumnSizes)[i] = length[i];
    }
    return arr;
}

剪枝:只要某一层的和+下一层将要遍历的数大于target就不再进入循环。

for (int i = startIndex; i < n && sum + candidates[i] <= target; i++)

3.分割字串问题

分割字串问题的分析:**分割字串问题的本质在于选择分割位置,我们通过startIndex控制分割的起始位置,循环变量控制分割位置,分割过的位置不能在分割,会出现重复

分割回文串
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

回文串 是正着读和反着读都一样的字符串。

问题分析:该问题为分割字串问题,同时收集结果的条件为全部回文,[startIndex,i]是一个分割区间,只要整个串被分割完,则代表可以收集结果了。

char*** arr;
char** result;
int aTop;
int rTop;
int* arrSize;

// - 判断回文
int checkStr(char* s, int start, int end)
{
    while(start <= end)
    {
        if(s[start] == s[end])
        {
            start++;
            end--;
        }
        else
        {
            return 0;
        }
    }
    return 1;


}

char* curStr(char* s, int start, int end)
{
    char* tmp = (char*)malloc(sizeof(char)*(end-start+2));
    int index = 0;
    for(int i = start; i <= end; i++)
    {
        tmp[index++] = s[i];
    }
    tmp[index] = '\0';

    return tmp;

}


void copy()
{
    char** tmp = (char**)malloc(sizeof(char*)*rTop);
    for(int i = 0; i < rTop; i++)
    {
        tmp[i] = result[i];
    }

    arrSize[aTop] = rTop;
    arr[aTop++] = tmp;


}
void BackTracking(char* s, int len, int startIndex)
{
    // startIndex >= strlen的时候收集结果
    if(startIndex >= len)
    { 
        copy();
        return ;
    }



    for(int j = startIndex; j < len; j++)
    {
        if(checkStr(s,startIndex,j))
        {
            result[rTop++] = curStr(s,startIndex,j);
        }
        // - 某层不回文,则++接着判断。
        else
            continue;
        BackTracking(s,len,j+1);

        rTop--;

    }

}

char*** partition(char* s, int* returnSize, int** returnColumnSizes)
{
    arrSize = (int*)malloc(sizeof(int)*40000);
    arr = (char***)malloc(sizeof(char**)*40000);
    int len = strlen(s);
    // - result数组存储的是满足条件的组合,该组合不会超过len个
    result = (char**)malloc(sizeof(char*)*len);
    rTop = aTop = 0;
    BackTracking(s,len,0);
    *returnSize = aTop;
    *returnColumnSizes = (int*)malloc(sizeof(int)*aTop);

    for(int i = 0; i < aTop; i++)
    {
        (*returnColumnSizes)[i] = arrSize[i];

    }
    return arr;
}

复原IP地址
有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。

例如:“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址,但是 “0.011.255.245”、“192.168.1.312” 和 “192.168@1.1” 是 无效 IP 地址。
给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 ‘.’ 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。

问题分析:本题目为分割字串问题,分割条件为加每个ip地址都是有效,且要加入点号。

char* result;
char** arr;
int rTop;
int aTop;

int isIPAdders(char* s, int start, int end)
{
    if(start > end)
        return 0;
    if (s[start] == '0' && start != end) { // 0开头的数字不合法
                return 0;
    }
    int num = 0;
    for (int i = start; i <= end; i++) {
        if (s[i] > '9' || s[i] < '0') { // 遇到非数字字符不合法
            return 0;
        }
        num = num * 10 + (s[i] - '0');
        if (num > 255) { // 如果大于255了不合法
            return 0;
        }
    }
    return 1;
}


void CurStr(char* s, int start, int end)
{
    for(int i = start; i <= end; i++)
    {
        result[rTop++] = s[i];
    }
}

void BackTracking(char* s, int len, int startIndex, int pointSize)
{
    if(pointSize == 3)
    {
        if(isIPAdders(s, startIndex, len-1))
        {
            char* tmp = (char*)malloc(sizeof(char)*(len+4));
            CurStr(s, startIndex, len-1);
            for(int i = 0; i <= rTop; i++)
            {
                tmp[i] = result[i];
            }
            tmp[rTop] = '\0';
            arr[aTop++] = tmp;
            // - 最后一次回退不能由循环完成,必须在这里完成,并且最后一个回退不用回退.号
            rTop-=((len-1)-startIndex+1);
            return;
        }
        return;
    }

                            // - 每个合法地址从startIndex开始最多3个字符,剪枝。
    for(int j = startIndex; j < 3+startIndex; j++)
    {
        if(isIPAdders(s,startIndex, j))
        {
            CurStr(s,startIndex,j);
            result[rTop++] = '.';
            pointSize++;

            BackTracking(s,len,j+1,pointSize);
            rTop-=(j-startIndex+2);
            pointSize--;
        }
        // - 只要起始位置不是合法地址,则该串就无法分割出合法地址。
        else
            break;

    }

}

// - 分割子串
char** restoreIpAddresses(char* s, int* returnSize) 
{
    int len = strlen(s);
    if(len < 4 && len > 12)
        return NULL;    
    arr = (char**)malloc(sizeof(char*)*10000);
    result = (char*)malloc(sizeof(char)*(len+4));
    rTop = aTop = 0;
    BackTracking(s,len,0,0);
    *returnSize = aTop;
    return arr;


}

剪枝:每个分割项的数字个数是[1-3],所以可以在for循环判断部分剪枝。

for(int j = startIndex; j < 3+startIndex; j++)

4.子集问题

子集问题的分析子集问题的本质依旧是组合问题,不过收集条件为无,及收集所有结点,同时每次收集完不用返回

子集
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

问题分析:本题为子集问题,则要收集所有结点。

int** arr;
int* result;
int* length;
int rTop;
int aTop;

void copy()
{
    int* tmp = (int*)malloc(sizeof(int)*10);
    for(int i = 0; i < rTop; i++)
    {
        tmp[i] = result[i];
    }
    length[aTop] = rTop;
    arr[aTop++] = tmp;

}

// - 子集问题--收集所有回溯树的结点
void BackTracking(int* nums, int numsSize, int startIndex)
{
    copy();
	
	// - 没有元素可取,就返回。
    if(startIndex >= numsSize)
        return;

    for(int i = startIndex; i < numsSize; i++)
    {
        result[rTop++] = nums[i];
        BackTracking(nums,numsSize, i+1);
        rTop--;
    }

}

int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) 
{
    arr = (int**)malloc(sizeof(int*)*2000);
    result = (int*)malloc(sizeof(int)*numsSize);
    length = (int*)malloc(sizeof(int)*2000);
    rTop = aTop = 0;
    BackTracking(nums,numsSize,0);
    *returnSize = aTop;
    *returnColumnSizes = (int*)malloc(sizeof(int)*aTop);
    for(int i = 0; i < aTop; i++)
    {
        (*returnColumnSizes)[i] = length[i];
    }
    return arr;
}

递增子序列
给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。

数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。

问题分析:存在重复元素,并且要求返回不同递增子序列,则不能通过排序去重,可以使用hash表,记录每次选择的元素,完成去重操作,去重的原因在于重复的元素存在重复收集结果的情况,同时改题目也需要我们遍历所有结点,收集结果的条件是result数字的元素大于1。

int** arr;
int* result;
int* length;
int rTop;
int aTop;

void copy()
{
    int* tmp = (int*)malloc(sizeof(int)*rTop);
    // for(int i = 0; i < rTop; i++)
    // {
    //     tmp[i] = result[i];
    // }
    memcpy(tmp, result, rTop*sizeof(int));
    length[aTop] = rTop;
    arr[aTop++] = tmp;

}


find(int* hash, int size, int element)
{
    int i;
    for(i = 0; i < size; i++) {
        if(hash[i] == element)
            return 1;
    }
    return 0;
}

// - 去重 - 不能用排序进行去重,因为要求原数组的递增子序列 -- 哈希表
void BackTracking(int* nums, int numsSize, int startIndex)
{
    if(rTop > 1)
        copy();
    
    // - 每层都生成一个哈希表,去重。
    int* hash = (int*)malloc(numsSize*sizeof(int));
    int hashTop = 0;
    for(int i = startIndex; i < numsSize; i++)
    {
    	// - 满足以下条件++,不收集结果。
        if((rTop > 0 && nums[i] < result[rTop-1]) || find(hash, numsSize,nums[i]))
            continue;
        result[rTop++] = nums[i];
        hash[hashTop++] = nums[i];
        BackTracking(nums,numsSize, i+1);
        rTop--;
    }

}

int** findSubsequences(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) 
{
    arr = (int**)malloc(sizeof(int*)*33000);
    result = (int*)malloc(sizeof(int)*numsSize);
    length = (int*)malloc(sizeof(int)*33000);
    rTop = aTop = 0;
    BackTracking(nums,numsSize,0);
    *returnSize = aTop;
    *returnColumnSizes = (int*)malloc(sizeof(int)*aTop);
    for(int i = 0; i < aTop; i++)
    {
        (*returnColumnSizes)[i] = length[i];
    }
    return arr;
}

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

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

相关文章

Java SE——*API API帮助文档

1. API概述 Java中的API可以理解为一本编程字典或者工具包&#xff0c;它包含了许多预定义的类、接口和方法&#xff0c;可以帮助我们更方便地开发Java程序 想象一下&#xff0c;当你要做一个饭菜的时候&#xff0c;你需要食谱和厨具。食谱告诉你需要哪些食材和步骤&#xff…

腾讯云助力港华能源上线“碳汭星云2.0”,推动能源行业绿色低碳转型

11月17日&#xff0c;港华能源与腾讯云联合打造的港华智慧能源生态平台“碳汭星云2.0”升级上线。依托双方的连接、大数据能力和行业深耕经验&#xff0c;该平台打破了园区“数据孤岛”&#xff0c;进一步提升了数据治理、应用集成和复制推广能力&#xff0c;未来有望以综合能源…

记录一次较为完整的Jenkins发布流程

文章目录 1. Jenkins安装1.1 Jenkins Docker安装1.2 Jenkins apt-get install安装 2. 关联github/gitee服务与webhook2.1 配置ssh2.2 Jenkins关联2.3 WebHook 3. 前后端关联发布 1. Jenkins安装 1.1 Jenkins Docker安装 Docker很好&#xff0c;但是我没有玩明白如何使用Docke…

php伪随机数

利用工具 php_mt_seed <?php // php 7.2function white_list() {return mt_rand();}echo white_list(), "\n";echo white_list(), "\n";echo white_list(), "\n"; 输入命令&#xff1a; ./php_mt_seed 1035656029 <?phpmt_srand(181095…

通过U盘重装Win10教程图解

如果我们发现Win10电脑系统出现了问题&#xff0c;可以通过简单的操作来解决问题。如果还是不能解决系统问题&#xff0c;这时候用户就给电脑重新安装Win10系统&#xff0c;这样就能轻松解决问题了。接下来小编给大家详细介绍关于通过U盘重新安装系统Win10的方法步骤。 准备工作…

PC3329L DC-DC降压 10V-100V输入3A大流输出带EN功能实现零功耗只需极少元器件

1. PC3392L特性  通过使能脚关断实现零功耗  宽电压输入范围 10V 至 100V  最大输出电流 3A  集成功率 MOS 管  外围器件少  输出短路保护  温度保护  逐周期限流  输出电压灵活可靠  ESOP8 2. 描述 PC3392L 一款宽电压范围降压型 DC-DC 电源管…

Java面试题07

1.线程池都有哪些状态&#xff1f; 线程池的状态有RUNNING&#xff08;运行中&#xff09;、SHUTDOWN&#xff08;关闭中&#xff0c;不接受新任务&#xff09;、 STOP&#xff08;立即关闭&#xff0c;中断正在执行任务的线程&#xff09;和TERMINATED&#xff08;终止&#x…

Blender洪水淹没毁墙效果

本文中用到了两个Blender插件&#xff1a;FLIP Fluid(流体模拟相关插件) 和 RBDLab&#xff08;碎裂插件&#xff09;: 1.用FLIP Fluid制作流体、域、障碍&#xff0c;确定好流体的冲刷方向&#xff08;后期好摆放被摧毁的墙体&#xff09;&#xff0c;利用插件做出水流动画&a…

信息中心网络提出的背景、研究现状及研究内容

信息中心网络什么时候提出的&#xff1f;未来发展前景&#xff1f;有什么著名实验室在做&#xff1f; 1、提出背景&#xff1a; 互联网产生于上世纪60年代&#xff1a; &#xff08;1&#xff09;网络设备数量呈指数性增长 截至2022年底全球范围内预计将有超过280亿台终端设…

【openGauss/MogDB的TPCH测试】

TPC-H是一个决策支持基准&#xff08;Decision Support Benchmark&#xff09;&#xff0c;它由一套面向业务的特别查询和并发数据修改组成。查询和填充数据库的数据具有广泛的行业相关性。这个基准测试演示了检查大量数据、执行高度复杂的查询并回答关键业务问题的决策支持系统…

MobaXterm配置ssh端口转发(tensorboard使用)

背景&#xff1a; 我有一台本地Windows电脑&#xff0c;上面安装了MobaXterm软件。 MobaXterm通过ssh连接了一台服务器&#xff08;默认是通过22端口连&#xff0c;我这里配了一下&#xff0c;要填别的&#xff09; 现在服务器在跑模型&#xff0c;其6006端口是tensorboard端口…

沸点 | Ultipa 图数据库金融应用场景优秀案例首批入选,金融街论坛年会发布

为推进图数据库在金融行业的创新应用试点&#xff0c;近日&#xff0c;在2023金融街论坛年会“全球金融科技中心网络年会暨ZIBS北京论坛”上&#xff0c;北京前沿金融监管科技研究院发布了基于国际标准组织——国际关联数据基准委员会&#xff08;LDBC&#xff09;的《图数据库…

安全+Linux!IBM新一代大型机Z14全新发布

导读本周&#xff0c;以“架构 人机同行”为主题的IBM Systems创行者高峰论坛在北京召开&#xff0c;IBM全球及大中华区硬件系统部负责人&#xff0c;金融、医疗、制造等领域的企业、合作伙伴共与这一年度盛会&#xff0c;探讨认知时代下的基础架构技术趋势及IBM硬件系统业务的…

【MySQL】_JDBC

目录 1. JDBC原理 2. 导入JDBC驱动包 3. 编写JDBC代码实现Insert 3.1 创建并初始化一个数据源 3.2 和数据库服务器建立连接 3.3 构造SQL语句 3.4 执行SQL语句 3.5 释放必要的资源 4. JDBC代码的优化 4.1 从控制台输入 4.2 避免SQL注入的SQL语句 5. 编写JDBC代码实现…

【SpringBoot3+Vue3】四【基础篇】-前端(vue基础)

目录 一、项目前置知识 二、使用vscode创建 三、vue介绍 四、局部使用vue 1、快速入门 1.1 需求 1.2 准备工作 1.3 操作 1.3.1 创建html 1.3.2 创建初始html代码 1.3.3 参照官网import vue 1.3.4 创建vue应用实例 1.3.5 准备div 1.3.6 准备用户数据 1.3.7 通过…

Matlab论文插图绘制模板第127期—进阶气泡矩阵/热图

​在之前的文章中&#xff0c;分享了Matlab散点图矩阵的绘制模板&#xff1a; 也分享过气泡矩阵图的绘制模板&#xff1a; 考虑到规范性和便捷性&#xff0c;再来分享一下进阶版的气泡矩阵/热图。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已…

PlayCover“模拟器”作弊解决方案

当下的游戏市场&#xff0c;移动游戏已占据了主导地位&#xff0c;但移动端游戏碍于屏幕大小影响操作、性能限制导致卡顿等因素&#xff0c;开始逐步支持多端互通。但仍有一些游戏存在移动端与 PC 端不互通、不支持 PC 端或没有 Mac 版本&#xff0c;导致 Mac 设备体验游戏不方…

通信原理板块——纠错编码的基本原理和性能

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 1、分组码 将信息码分组&#xff0…

CleanMyMac X2024免费测试版好不好用?值不值得下载

如果你是一位Mac用户&#xff0c;你可能会遇到一些问题&#xff0c;比如Mac运行缓慢、磁盘空间不足、应用程序难以管理等。这些问题会影响你的Mac的性能和体验&#xff0c;让你感到沮丧和无奈。那么&#xff0c;有没有一款软件可以帮助你解决这些问题呢&#xff1f;答案是肯定的…

109.firefly-extboot的生成脚本

内核版本&#xff1a; 4.4.194 在firefly的sdk 2.5.1c及以后的版本都是extboot.img&#xff08;对应表中的extboot&#xff09; 但是之前的并不是&#xff0c;而且一个boot.img&#xff0c;&#xff08;对应表中rkboot&#xff09; rkboot的生成方法可以参考解决linux5.15编…