算法:穷举,暴搜,深搜,回溯,剪枝

news2024/11/27 13:46:40

文章目录

  • 算法基本思路
  • 例题
    • 全排列
    • 子集
    • 全排列II
    • 电话号码和字母组合
    • 括号生成
    • 组合
    • 目标和
    • 组合总和
    • 优美的排列
    • N皇后
    • 有效的数独
    • 解数独
    • 单词搜索
    • 黄金矿工
    • 不同路径III
  • 总结

算法基本思路

穷举–枚举

  1. 画出决策树
  2. 设计代码

在设计代码的过程中,重点要关心到全局变量,dfs函数,和细节问题,例如有回溯,剪枝,递归出口等问题

例题

全排列

在这里插入图片描述
画出该全排列的决策树:

在这里插入图片描述
因此筛选思路也就有了,从给定的vector开始选,每选择了一个就将选的元素的下标标记为true,代表选过了,递归到下一次进行选择的时候,如果要选的元素的下标是false,代表还没有选过,就可以被选,回溯后要回复现场

class Solution 
{
public:
    // 设计全局变量
    vector<vector<int>> ret; // 返回的二维数组
    vector<int> path; // 二维数组中的元素
    bool check[7]; // 判断元素是否被统计过了
    
    void dfs(vector<int>& nums)
    {
        // 递归出口
        if(path.size() == nums.size())
        {
            ret.push_back(path);
            return;
        }

        for(int i=0;i<nums.size();i++)
        {
            // 如果该字符没有被统计过就进行统计
            if(check[i] == false)
            {
                path.push_back(nums[i]);
                check[i] = true;
                // 进入递归
                dfs(nums);
                // 回溯和恢复现场
                path.pop_back();
                check[i] = false;
            }
        }
    }

    vector<vector<int>> permute(vector<int>& nums) 
    {
        dfs(nums);
        return ret;
    }
};

子集

在这里插入图片描述
对于这个题有两种决策方案:
第一种决策方案是,对于nums数组中的每一个元素,都看它是否需要被选,可以选择要被选,也可以选择不被选
第二种决策方案是,对于path数组中的元素个数,可以为一个,也可以为两个,也可以为三个,直到和nums数组中元素的个数一样

决策1:
在这里插入图片描述

class Solution 
{
public:
    vector<vector<int>> ret; // 返回值
    vector<int> path; // 数组中的元素

    void dfs(vector<int>& nums, int pos)
    {
        for(int i=pos;i<nums.size();i++)
        {
            // 选
            path.push_back(nums[i]);
            dfs(nums,i+1);

            // 不选
            path.pop_back();
        }
        ret.push_back(path);
    }

    vector<vector<int>> subsets(vector<int>& nums) 
    {
        dfs(nums,0);
        return ret;
    }
};

决策2:

在这里插入图片描述

class Solution 
{
public:
    vector<vector<int>> ret; // 返回值
    vector<int> path; // 数组中的元素

    void dfs(vector<int>& nums, int pos)
    {
        ret.push_back(path);
        for(int i=pos;i<nums.size();i++)
        {
            // 数组中元素的个数
            path.push_back(nums[i]);
            dfs(nums,i+1);
            // 回溯+恢复现场
            path.pop_back();
        }
    }

    vector<vector<int>> subsets(vector<int>& nums) 
    {
        dfs(nums,0);
        return ret;
    }
};

全排列II

在这里插入图片描述
前面有做过一道全排列,这个题和前面题的不同点就是多了相同元素,因此对于剪枝的策略有不同,下面首先画出它的决策树

在这里插入图片描述
从决策树中可以看出这个题的剪枝方案

  1. 在同一个节点,相同的数不能被选两次 — 比较这个数有没有被选过
  2. 在不同的节点,已经被选过的数就不能被选了 — check数组
class Solution 
{
public:
    // 设计全局变量
    vector<vector<int>> ret;
    vector<int> path;
    bool check[9];

    void dfs(vector<int>& nums)
    {
        // 递归终止条件
        if(path.size() == nums.size())
        {
            ret.push_back(path);
            return;
        }

        for(int i = 0; i < nums.size(); i++)
        {
            // 剪枝的条件:当前节点没用过并且前面没出现过
            if(check[i] == false && (i == 0 || nums[i] != nums[i-1] || check[i-1]))
            {
                path.push_back(nums[i]);
                check[i] = true;
                dfs(nums);
                // 回溯
                check[i] = false;
                path.pop_back();
            }
        }
    }

    vector<vector<int>> permuteUnique(vector<int>& nums) 
    {
        sort(nums.begin(),nums.end());
        dfs(nums);
        return ret;
    }
};

电话号码和字母组合

在这里插入图片描述

class Solution 
{
public:
    // 全局变量
    string arr[10] = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    vector<string> ret;
    string path;

    // 决策:取digits中每一个数字对应的字符串中的元素,直接取即可
    void dfs(string& digits, int pos)
    {
        // 递归终止条件
        if(path.size() == digits.size())
        {
            ret.push_back(path);
            return;
        }

        for(auto e : arr[digits[pos] - '0'])
        {
            path += e;
            dfs(digits, pos+1);
            // 回溯+恢复现场
            path.pop_back();
        }
    }

    vector<string> letterCombinations(string digits) 
    {
        if(digits.size() == 0)
            return ret;
        dfs(digits, 0);
        return ret;
    }
};

括号生成

在这里插入图片描述

首先画出这个题的决策树,观察决策树的剪枝情况

在这里插入图片描述
从中可以看出,这个题的剪枝条件是,右括号的数量不能大于左括号的数量,并且左括号的数量不能大于n

全局变量如何设计?答案存储在一个数组中,每一个path也要有一个字符串用以描述

递归函数头如何设计?首先必须要知道n是多少,其次要知道左括号现在有多少,右括号现在有多少

递归函数的实现细节:递归终止条件是path的长度等于n的2倍,回溯要将最后插入的部分删除掉

因此函数就很好实现了:

class Solution
{
public:
    vector<string> res;
    string path;

    void dfs(int n, int left, int right)
    {
        // 递归终止条件
        if (path.size() == n * 2)
        {
            res.push_back(path);
            return;
        }

        // 添加左括号的剪枝条件
        if (left < n)
        {
            path += '(';
            left++;
            dfs(n, left, right);
            // 回溯+恢复现场
            path.pop_back();
            left--;
        }
        // 添加右括号的剪枝条件
        if (left > right)
        {
            path += ')';
            right++;
            dfs(n, left, right);
            // 回溯+恢复现场
            path.pop_back();
            right--;
        }
    }

    vector<string> generateParenthesis(int n)
    {
        dfs(n, 0, 0);
        return res;
    }
};

组合

在这里插入图片描述

画出决策树

在这里插入图片描述

这里要注意这两个条件,其实在代码中是不需要专门体现的,首先,选过的不能再选,也就是说子集的元素都是升序排列的,那么只需要在递归的时候直接从当前位置的下一个位置开始找数即可

check数组的存在意义?

通过这个题,对于check数组有了更多的理解,check数组存在的意义是,选完一个数后,在选第二个数的过程中,需要从头再次开始选的时候,为了避免会重复选用,因此会有check数组来用以标记,但是在这个题中,选了一个数以后,选第二个数直接从这个数的下一个数开始选就可以了,因此实际上是不需要check数组来帮忙的

class Solution
{
public:
	// 定义全局变量
	vector<vector<int>> ret;
	vector<int> path;
	bool check[25];

	void dfs(int n, int k, int pos)
	{
		// 递归终止条件
		if (path.size() == k)
		{
			ret.push_back(path);
			return;
		}

		for (int i = pos; i <= n; i++)
		{
			path.push_back(i);
			dfs(n, k, i + 1);
			// 回溯+恢复现场
			path.pop_back();
		}
	}

	vector<vector<int>> combine(int n, int k)
	{
		dfs(n, k, 1);
		return ret;
	}
};

目标和

在这里插入图片描述

首先画出它的决策树,从中可以看出它和子集的那道题有异曲同工之处,在此基础上,对这个决策树进行实现

在这里插入图片描述

class Solution
{
public:
	// 定义全局变量
	int count;
	void dfs(vector<int>& nums, int target, int pos, int path)
	{
		if (pos == nums.size())
		{
			if (path == target)
				count++;
			return;
		}
		dfs(nums, target, pos + 1, path + nums[pos]);
		dfs(nums, target, pos + 1, path - nums[pos]);
	}
	int findTargetSumWays(vector<int>& nums, int target)
	{
		dfs(nums, target, 0, 0);
		return count;
	}
};

组合总和

在这里插入图片描述

决策树

在这里插入图片描述
如果在不考虑去重的情况下,这样的决策树是可以的,但是这里题目要求有要去重的阶段,因此就需要考虑剪枝的问题

如何剪枝?

对于数据的选择,如果先选了2,再选3,那么在选3的时候就不应该再选2,因此剪枝的策略就是选的时候不选前面的,因为如果前面的能选,那么在前面选的时候一定选了后面的,所以只需要向前进行寻找即可,不用管后面的部分

在这里插入图片描述
这样的决策树才理应是正确的决策树

class Solution 
{
public:
    // 定义全局变量
    vector<vector<int>> ret;
    vector<int> path;

    void dfs(vector<int>& candidates, int target, int pos, int sum)
    {
        // 递归终止条件
        if(sum == target)
        {
            ret.push_back(path);
            return;
        }
        if(sum > target)
            return;

        for(int i = pos; i < candidates.size(); i++)
        {
            path.push_back(candidates[i]);
            dfs(candidates, target, i, sum + candidates[i]);
            // 回溯+恢复现场
            path.pop_back();
        }
    }

    vector<vector<int>> combinationSum(vector<int>& candidates, int target) 
    {
        dfs(candidates, target, 0, 0);
        return ret;
    }
};

这是其中一种决策方案,下面提供决策的第二种思路

在数据选择方面,假设现在有2,3,5三个数字,可以对其中的每个数字选不同的次数,例如选0次,1次,2次…

优美的排列

在这里插入图片描述

一开始第一反应是,先把数组搞出来,再进行判断,但这样会超时,意味着有些地方需要被优化

// 超时
class Solution 
{
    // 思路:全排列出来数据,然后判断是否优美
public:
    // 全局变量
    bool check[20];
    vector<int> path;
    int count;

    bool check_perm(const vector<int>& nums)
    {
        for(int i = 0; i < nums.size(); i++)
        {
            if(max(nums[i],i+1) % min(nums[i],i+1) != 0)
                return false;
        }
        return true;
    }

    void dfs(int n)
    {
        // 递归终止条件
        if(path.size() == n)
        {
            if(check_perm(path)) count++;
            return;
        }
        for(int i = 0; i < n; i++)
        {
            if(check[i] == false)
            {
                path.push_back(i + 1);
                check[i] = true;
                dfs(n);
                // 回溯现场
                path.pop_back();
                check[i] = false;
            }
        }
    }

    int countArrangement(int n) 
    {
        dfs(n);
        return count;
    }
};

N皇后

在这里插入图片描述

关于check判断,还可以使用类似于哈希表的解法,在下一道题中进行使用

class Solution
{
public:
    // 全局变量
    int _n;
    vector<vector<string>> ret;
    vector<string> path;

    // 构建皇后摆放情况
    string con_string(int pos, int n)
    {
        string tmp;
        for (int i = 0; i < pos; i++)
            tmp += '.';
        tmp += 'Q';
        while (tmp.size() != n)
            tmp += '.';
        return tmp;
    }

    // 判断能不能在第i行的pos位置放置皇后
    bool check(int i, int pos)
    {
        // 判断列
        for (int j = 0; j < i; j++)
        {
            if (path[j][pos] == 'Q')
                return false;
        }
        // 判断主对角线
        for (int j = 1; i - j >= 0 && pos + j < _n; j++)
        {
            if (path[i - j][pos + j] == 'Q')
                return false;
        }
        // 判断次对角线
        for (int j = 1; i - j >= 0 && pos - j >= 0; j++)
        {
            if (path[i - j][pos - j] == 'Q')
                return false;
        }
        return true;
    }

    void dfs(int n, int pos)
    {
        // 终止条件
        if (pos == n)
        {
            ret.push_back(path);
            return;
        }

        for (int i = 0; i < n; i++)
        {
            // 剪枝判断pos行的i位置是否可以放皇后,如果成功就放到棋盘中
            if (check(pos,i))
            {
                // 构建出当前皇后摆放情况
                string tmp = con_string(i, n);
                path.push_back(tmp);
                // 递归到下一层去判断
                dfs(n, pos + 1);
                // 回溯 恢复现场
                path.pop_back();
            }
        }
    }

    vector<vector<string>> solveNQueens(int n)
    {
        _n = n;
        dfs(n, 0);
        return ret;
    }
};

有效的数独

在这里插入图片描述
此题就是利用了类似哈希表的方法

class Solution 
{
public:
    // 利用哈希表的原理来解题
    // 全局变量:col/row[i][j]表示第i行/列中j元素是否出现过,grid是把每个九宫格当成一个元素
    bool col[9][10];
    bool row[9][10];
    bool grid[3][3][10];
    bool isValidSudoku(vector<vector<char>>& board) 
    {
        for(int i = 0; i < board.size(); i++)
        {
            for(int j = 0; j < board[i].size(); j++)
            {
                if(board[i][j] == '.') continue;
                
                if(col[i][board[i][j] - '0'] == false)
                {
                    col[i][board[i][j] - '0'] = true;
                }
                else
                {
                    return false;
                }

                if(row[j][board[i][j] - '0'] == false)
                {
                    row[j][board[i][j] - '0'] = true;
                }
                else
                {
                    return false;
                }

                if(grid[i / 3][j / 3][board[i][j] - '0'] == false)
                {
                    grid[i / 3][j / 3][board[i][j] - '0'] = true;
                }
                else
                {
                    return false;
                }
            }
        }
        return true;
    }
};

解数独

在这里插入图片描述

解决本题需要依赖前面的思想


class Solution 
{
public:
    // 全局变量
    bool col[9][10];
    bool row[9][10];
    bool grid[3][3][10];

    void solveSudoku(vector<vector<char>>& board) 
    {
        for(int i = 0; i < 9; i++)
        {
            for(int j = 0; j < 9; j++)
            {
                if(board[i][j] != '.')
                {
                    col[j][board[i][j] - '0'] = true;
                    row[i][board[i][j] - '0'] = true;
                    grid[i / 3][j / 3][board[i][j] - '0'] = true;
                }
            }
        }
        dfs(board);
    }

    bool dfs(vector<vector<char>>& board)
    {
        // 构造行和列
        for(int i = 0; i < 9; i++)
        {
            for(int j = 0; j < 9; j++)
            {
                if(board[i][j] == '.')
                {
                    for(int num = 1; num <= 9; num++)
                    {
                        // 剪枝
                        if(!row[i][num] && !col[j][num] && !grid[i / 3][j / 3][num])
                        {
                            board[i][j] = num + '0';
                            row[i][num] = col[j][num] = grid[i / 3][j / 3][num] = true;
                            if(dfs(board) == true)
                                return true;
                            // 回溯+恢复现场
                            board[i][j] = '.';
                            row[i][num] = col[j][num] = grid[i / 3][j / 3][num] = false;
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }
};

单词搜索

在这里插入图片描述
本题是使用的是矩阵中的搜索,有些类似于迷宫问题

其中需要注意的是在判断上下左右是否有内容的时候,要使用的是一个向量来标记,这样就可以避免写四层循环带来的代码冗余,在解决矩阵搜索的内容中这样的方法很方便使用

class Solution
{
public:
	// 全局变量 m为行数,n为列数
	int m;
	int n;
	string target;
	bool status;
	string path;
	bool check[7][7];
    int dx[4] = {0, 0, -1, 1};
    int dy[4] = {1, -1, 0, 0};

	// pos代表的是现在正在寻找的元素对应的下标
	void dfs(vector<vector<char>>& board, int p, int q, int pos)
	{
		if (pos == target.size())
		{
			status = true;
			return;
		}
		// 去这个格子上下左右进行寻找
        for(int i = 0; i < 4; i++)
        {
            int row = p + dx[i];
            int col = q + dy[i];
            if (row < m && row >= 0 && col < n && col >= 0 && board[row][col] == target[pos] && check[row][col] == false)
            {
                // 说明找到了,到下一层去找找
                check[row][col] = true;
                path.push_back(board[row][col]);
                dfs(board, row, col, pos + 1);
                // 回溯 恢复现场
                check[row][col] = false;
                path.pop_back();
            }
        }
	}

	bool exist(vector<vector<char>>& board, string word)
	{
		m = board.size();
		n = board[0].size();
		target = word;
		// 此时说明已经找到了target[0],于是可以继续寻找
		path.push_back(target[0]);
		for (int i = 0; i < board.size() && status == false; i++)
		{
            for(int j = 0; j< board[i].size(); j++)
            {
                if(board[i][j] == target[0])
                {
                    check[i][j] = true;
                    dfs(board, i, j, 1);
                    check[i][j] = false;
                }
            }
		}
		return status == true;
	}
};

黄金矿工

在这里插入图片描述
策略:找到有黄金的格子,从这个格子开始进行深度优先遍历,每次遍历到找不见路就停止,中间记录黄金数

class Solution
{
	// 策略:找到有黄金的格子,从这个格子开始进行深度优先遍历,每次遍历到找不见路就停止,中间记录黄金数
public:
	// 全局变量
	int res;  // 获得黄金最多的数量
	bool check[16][16];  // 判断这个格子有没有走过
	// 定义偏移量
	int dx[4] = { 0, 0, 1, -1 };
	int dy[4] = { 1, -1, 0, 0 };

	// 从第i行第j列开始开采,开采量是path
	void dfs(vector<vector<int>>& grid, int i, int j, int path)
	{
		res = max(res, path);
		for (int k = 0; k < 4; k++)
		{
			int x = dx[k] + i, y = dy[k] + j;
			// 剪枝 如果这个格子有矿并且没有被走过
			if (x >= 0 && x < grid.size() && y >= 0 && y < grid[0].size() && grid[x][y] != 0 && check[x][y] == false)
			{
				check[x][y] = true;
				dfs(grid, x, y, path + grid[x][y]);
				// 回溯和恢复现场
				check[x][y] = false;

			}
		}
	}

	int getMaximumGold(vector<vector<int>>& grid)
	{
		for (int i = 0; i < grid.size(); i++)
		{
			for (int j = 0; j < grid[i].size(); j++)
			{
				if (grid[i][j] != 0)
				{
					// 标记该处已经被开采了
					check[i][j] = true;
					// 从i j开始开采,开采量是grid[i][j]
					dfs(grid, i, j, grid[i][j]);
					// 回溯和恢复现场
					check[i][j] = false;
				}
			}
		}
		return res;
	}
};

不同路径III

在这里插入图片描述

class Solution 
{
public:
    bool check[21][21];
    int ret;
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    int step;

    void dfs(vector<vector<int>>& grid, int i, int j, int count)
    {
        if(grid[i][j] == 2)
        {
            if(count == step)
                ret++;
            return;
        }

        for(int k = 0; k < 4; k++)
        {
            int x = i + dx[k], y = j + dy[k];
            if(x >= 0 && x < grid.size() && y >= 0 && y < grid[0].size() && grid[x][y] != -1 && check[x][y] == false)
            {
                check[x][y] = true;
                dfs(grid, x, y, count + 1);
                check[x][y] = false;
            }
        }
    }

    int uniquePathsIII(vector<vector<int>>& grid) 
    {
        int x, y;
        for(int i = 0; i < grid.size(); i++)
        {
            for(int j = 0; j < grid[0].size(); j++)
            {
                if(grid[i][j] == 1)
                {
                    x = i;
                    y = j;
                }
                else if(grid[i][j] == 0)
                {
                    step++;
                }
            }
        }
        step += 2;
        check[x][y] = true;
        dfs(grid, x, y, 1);
        return ret;
    }
};

总结

其实从这些题中不难看出,画出决策树的过程并不困难,困难的是对于代码变现能力,因此在掌握代码变现的能力后再解决问题就很轻松了

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

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

相关文章

软文推广优化技巧:如何写出有创意的文案

今天媒介盒子要给大家分享的干货内容就是&#xff1a;如何写出有创意的文案。 时代背景会改变&#xff0c;大众的趣味焦点也会转移&#xff0c;同样再好的文案也会失效&#xff0c;但文案背后的触发机制不会变。下面是能够使广告文案起作用的关键因素&#xff1a; 一、 研究产…

偶数科技亮相2023中国程序员节——数据库技术高峰论坛

2023年10月24日&#xff0c;由中国软件行业协会主办的“中国程序员节”在北京、深圳、宁波多地同时召开&#xff0c;其中数据库技术高峰论坛在北京举办&#xff0c;偶数科技亮相本次论坛并分享了题为《大模型、实时需求推动湖仓平台走向开放》的主题演讲。 国际局势复杂、科技竞…

面包机上架亚马逊美国站UL1026测试报告办理

面包机&#xff08;又称烤面包机&#xff09;是一种家用电器&#xff0c;用于制作面包、烤饼等食品。在亚马逊美国站销售面包机时&#xff0c;可能需要提供 UL 报告以确保产品安全性。UL1026 是适用于面包机的美国安全标准。 面包机UL1026报告是按照美国国家电气规范NFPA 70所规…

Django生鲜蔬菜采购系统-计算机毕设 附源码 24033

Django生鲜蔬菜采购系统 目 录 摘要 1 绪论 1.1 研究背景 1.2国内外研究现状 1.3论文结构与章节安排 2 生鲜蔬菜采购系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 操作可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流…

Bean_AOP

Bean 源码 https://github.com/cmdch2017/Bean_IOC.git 获取Bean对象 BeanFactory Bean的作用域 第三方Bean需要用Bean注解 比如消息队列项目中&#xff0c;需要用到Json的消息转换器&#xff0c;这是第三方的Bean对象&#xff0c;所以不能用Component&#xff0c;而要用B…

【Mysql】查询mysql的版本

目录 cmd命令查询 mysql -- help(命令&#xff09; mysql -u root -p(命令&#xff09; 数据库管理工具查询 select version(); cmd命令查询 mysql -- help(命令&#xff09; mysql -u root -p(命令&#xff09; 执行该命令并且输入数据库密码 数据库管理工具查询 selec…

C++之旅(学习笔记)第6章 基本操作

C之旅&#xff08;学习笔记&#xff09;第6章 基本操作 6.1 基本操作 class X{ public:X(Sometype); // "普通的构造函数": 创建一个对象X(); // 默认构造函数X(const X&); // 拷贝构造函数X(X&&); // 移动构造函数X& operator(const …

广州华锐互动:VR互动实训内容编辑器助力教育创新升级

随着科技的飞速发展&#xff0c;教育领域也正在经历一场深刻的变革。其中&#xff0c;虚拟现实(VR)技术为教学活动提供了前所未有的便利和可能性。在诸多的VR应用中&#xff0c;VR互动实训内容编辑器无疑是最具潜力和创新性的一种。广州华锐互动开发的这款编辑器以其独特的功能…

HelloGitHub 社区动态,开启新的篇章!

今天这篇文章是 HelloGitHub 社区动态的第一篇文章&#xff0c;所以我想多说两句&#xff0c;聊聊为啥开启这个系列。 我是 2016 年创建的 HelloGitHub&#xff0c;它从最初的一份分享开源项目的月刊&#xff0c;现如今已经成长为 7w Star 的开源项目、1w 用户的开源社区、全网…

Xshell安装+使用教程

简介 Xshell 是一个强大的安全终端模拟软件&#xff0c;它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议。Xshell 通过互联网到远程主机的安全连接以及它创新性的设计和特色帮助用户在复杂的网络环境中享受他们的工作。 Xshell可以在Windows界面下用来访问远端不…

linux中使用arthas进行jvm内存分析

1. 安装下载 首先在官方github地址选择合适的版本&#xff0c;下载后上传到对于服务器。 使用unzip arthas-bin.zip 解压文件。进入目录中&#xff0c;执行./install-local.sh进行安装。执行完成后提示succeed&#xff0c;即可使用。 2. 启动 进入目录&#xff0c;执行java…

Python大语言模型实战-利用ChatDev框架自动开发一个游戏软件(附完整教程)

实现功能 ChatDev一个由多智能体协作框架&#xff0c;是一个虚拟软件公司&#xff0c;在人类 “用户” 指定一个具体的任务需求后&#xff0c;不同角色的智能体将进行交互式协同&#xff0c;以生产一个完整软件&#xff08;包括源代码、环境依赖说明书、用户手册等&#xff09…

智汇云舟入选IDC《中国智慧园区解决方案2023年厂商评估》报告

近日&#xff0c;全球领先的市场研究和咨询公司IDC发布报告《中国智慧园区解决方案2023年厂商评估》。报告内&#xff0c;IDC对中国市场具有代表性、且符合评估入围门槛要求的智慧园区解决方案厂商进行了综合评估。智汇云舟凭借在产品、技术等方面的综合优势&#xff0c;与大华…

从事人力资源相关工作,必须要有人力资源证书吗?

人力资源证书不是HR必备&#xff0c;但高含金量的HR证书确实是个加分项&#xff0c;有时候门槛有时候就是一证之隔。 作为人力资源从业者或者打算从事人力行业的同学&#xff0c;如果有意向考证的不妨看看&#xff0c;有哪些证书可以让你真正学以致用&#xff1f;哪些证书可以…

伦敦金冬令时开市时间怎样调整

在刚刚过去的一周&#xff0c;欧美的金融市场已经正式进入了冬令时&#xff0c;这对伦敦金市场的交易时间也产生了影响。由于美国于今年11月5日(星期日&#xff09;开始正式实施冬令时间&#xff0c;所以香港的伦敦金平台的交易时间也随之而有所调整。 从今年11月6日开始&#…

makefile的基础使用

1、建一个目录: mkdir Makefile/makefile(两个任意一个就可以) 2、用vim打开 3、在makefile里面的写法&#xff1a; 目标文件 : 依赖文件 >小例子: test:test.c [tab]依赖关系 gcc -o test test.c 4、…

win10 下 ros + Qt 工程CMakeLists.txt

win10 下 ros Qt 工程CMakeLists.txt 系统&#xff1a;win10 ros: melodic Qt: 5.12.12 源码目录: D:\workspace\catkin_qt 示例代码 https://github.com/ncnynl/ros-qt.git 由于示例代码是Qt4 &#xff0c;目前我是用QT5,所以CMakeLists.txt 修改如下 CMakeLists.txt #####…

区块链多链数字钱包开发

随着区块链技术的不断发展&#xff0c;多链数字钱包的开发逐渐成为热门领域。多链数字钱包是一种可以支持多种区块链网络的数字钱包&#xff0c;用户可以使用它来存储、管理和转移不同的数字资产。本文将探讨多链数字钱包的开发背景、市场需求、技术实现和未来趋势等方面。 一、…

AI编程工具:一站式编程解决方案,引领AI编程新时代

在人工智能的巨浪之下&#xff0c;编程领域正在经历一场深刻的转型。这场转型的核心&#xff0c;就是AI智能编程工具的出现。它们为开发者提供了一种全新的编程方式&#xff0c;极大地提高了编程效率。在这场变革中&#xff0c;DevChat无疑是引领者之一。 一、DevChat&#xf…

2011年03月31日 Go生态洞察:Godoc —— Go代码的文档化

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…