C++古老算法介绍

简介: C++古老算法介绍

本篇文章我们来介绍一下常用算法

1.贪心算法

贪心算法(Greedy Algorithm)是一种解决问题的策略,它在每一步都做出当前看来最优的选择,而不考虑全局最优解。(局部最优解得到整体最优解)贪心算法通常适用于满足"贪心选择性质"和"最优子结构性质"的问题。

贪心算法使用条件:

贪心算法适用的条件包括两个性质:贪心选择性质和最优子结构性质。

  1. 贪心选择性质(Greedy Choice Property):通过每一步的局部最优选择,能够得到全局最优解。也就是说,在每一步选择中,都做出当前看起来最好的选择,而不考虑对后续步骤的影响。
  2. 最优子结构性质(Optimal Substructure):问题的最优解包含了子问题的最优解。换句话说,通过求解子问题的最优解,可以推导出原问题的最优解。

当一个问题满足这两个性质时,可以考虑使用贪心算法来求解。但需要注意,并非所有问题都满足这两个性质,所以不能盲目地应用贪心算法。

代码实例:

以下是一个使用贪心算法解决找零钱问题的示例(经典):

假设有面额为1元、5元、10元、25元的硬币,现在要找零给定金额的钱数,求最少需要多少个硬币。

#include <iostream>
#include <vector>
std::vector<int> greedyCoinChange(int amount, std::vector<int>& coins) {
    std::vector<int> result;
    for (int i = coins.size() - 1; i >= 0; i--) {
        while (amount >= coins[i]) { // 尽可能多地选择当前面额的硬币
            result.push_back(coins[i]);
            amount -= coins[i];
        }
    }
    return result;
}
int main() {
    int amount = 48;
    std::vector<int> coins = {25, 10, 5, 1};
    std::cout << "Amount: " << amount << std::endl;
    std::cout << "Coins used: ";
    
    std::vector<int> result = greedyCoinChange(amount, coins);
    for (int coin : result) {
        std::cout << coin << " ";
    }
    
    std::cout << std::endl;
    return 0;
}

这段代码中,我们从最大面额的硬币开始选择,如果当前金额仍然大于等于当前面额的硬币,则选择该硬币,并减去相应的金额。重复这个过程直到金额变为0。

贪心算法在此问题中能够得到最优解,因为每次选择都是局部最优的。但需要注意的是,贪心算法并不适用于所有问题,有些问题可能需要动态规划等其他方法来求解。在使用贪心算法时,需要仔细分析问题性质,并确保它满足贪心选择性质和最优子结构性质。

2.递归算法

递归算法是一种通过调用自身来解决问题的算法。它将一个大问题分解为一个或多个相同或类似的子问题,并通过逐级求解子问题来达到最终解决整个问题的目的。

递归算法通常包含以下两个重要组成部分:

  1. 基本情况(Base Case):确定递归算法何时停止,不再进行递归调用。基本情况应该是最简单的情况,无需进一步递归求解即可得到结果。
  2. 递归调用(Recursive Call):在算法中使用相同的函数来解决规模更小的子问题。通过反复调用自身,将大问题转化为规模较小且相同性质的子问题。

在编写递归算法时,需要注意以下几点:

  • 确保每次递归调用都能使问题规模减小,否则可能会导致无限循环。
  • 保证基本情况被正确处理,确保最终可以终止递归过程。
  • 尽量避免重复计算和重复工作,利用已经计算过的结果进行缓存或剪枝操作。

斐波那契数列

#include <iostream>
int fibonacci(int n) {
    if (n <= 0) {
        return -1; // 错误情况,返回负数表示错误
    } else if (n == 1 || n == 2) {
        return 1; // 基本情况,斐波那契数列的第一项和第二项为1
    } else {
        return fibonacci(n - 1) + fibonacci(n - 2); // 递归调用求解前两个斐波那契数之和
    }
}
int main() {
    int n = 6;
    int result = fibonacci(n);
    
    std::cout << "第 " << n << " 个斐波那契数是:" << result << std::endl;
    return 0;
}

回溯法:

回溯法(Backtracking)是一种解决问题的算法思想,通常用于求解在给定约束条件下的所有可能解。它通过尝试所有可能的选择,并逐步构建出候选解,如果当前构建的部分无法满足问题的限制条件,就会回溯到上一个状态进行其他选择。

八皇后问题

#include <iostream>
#include <vector>
using namespace std;
bool isValid(vector<int>& board, int row, int col) {
    for (int i = 0; i < row; ++i) {
        if (board[i] == col || abs(board[i] - col) == abs(i - row)) {
            return false;
        }
    }
    return true;
}
void backtrack(vector<vector<string>>& res, vector<int>& board, int row, int n) {
    if (row == n) {
        vector<string> solution(n, string(n, '.'));
        for (int i = 0; i < n; ++i) {
            solution[i][board[i]] = 'Q';
        }
        res.push_back(solution);
    } else {
        for (int col = 0; col < n; ++col) {
            if (isValid(board, row, col)) {
                board[row] = col;
                backtrack(res, board, row + 1, n);
                board[row] = -1;
            }
        }
    }
}
vector<vector<string>> solveNQueens(int n) {
    vector<vector<string>> res;
    vector<int> board(n, -1);
    backtrack(res, board, 0, n);
    return res;
}
int main() {
    int n = 4;
    vector<vector<string>> solutions = solveNQueens(n);
    
    for (const auto& solution : solutions) {
        for (const auto& row : solution) {
            cout << row << endl;
        }
        cout << "----------------" << endl;
    }
    
    return 0;
}

在这个示例中,我们通过回溯法解决了八皇后问题。solveNQueens 函数返回了一个二维数组,其中每个元素代表一种合法的八皇后布局。

回溯算法的关键在于 isValidbacktrack 函数。isValid 函数用于判断当前位置是否可以放置皇后,而 backtrack 函数用于递归地尝试所有可能的选择,并生成符合要求的解。

总结:本篇文章讲了一些常用的数据结构算法    如贪心算法 回溯法 递归算法 等   掌握,每一个算法的精髓 才行 根据不同的场景使用不同的算法 能达到意想不到的效果

好了 本篇文章就到这里 在这里小编想向大家推荐一个课程 课程质量杠杠的

https://xxetb.xetslk.com/s/2PjJ3T

相关文章
|
23天前
|
机器学习/深度学习 安全 算法
【图论】【割点】【C++算法】928. 尽量减少恶意软件的传播 II
【图论】【割点】【C++算法】928. 尽量减少恶意软件的传播 II
|
9天前
|
存储 缓存 算法
C++从入门到精通:4.6性能优化——深入理解算法与内存优化
C++从入门到精通:4.6性能优化——深入理解算法与内存优化
|
9天前
|
存储 算法 程序员
C++从入门到精通:2.2.1标准库与STL容器算法深度解析
C++从入门到精通:2.2.1标准库与STL容器算法深度解析
|
23天前
|
人工智能 算法 BI
【图论】【 割边】【C++算法】1192. 查找集群内的关键连接
【图论】【 割边】【C++算法】1192. 查找集群内的关键连接
|
23天前
|
算法 测试技术 C#
【模拟】【C++算法】2826. 将三个组排序
【模拟】【C++算法】2826. 将三个组排序
|
23天前
|
算法 测试技术 C#
【数学】【C++算法】780. 到达终点
【数学】【C++算法】780. 到达终点
|
23天前
|
机器学习/深度学习 算法 测试技术
【深度优先】【图论】【C++算法】2045. 到达目的地的第二短时间
【深度优先】【图论】【C++算法】2045. 到达目的地的第二短时间
|
23天前
|
算法 测试技术 C#
【广度优先搜索】【堆】【C++算法】407. 接雨水 II
【广度优先搜索】【堆】【C++算法】407. 接雨水 II
|
23天前
|
算法 测试技术 Serverless
【二分查找】【C++算法】378. 有序矩阵中第 K 小的元素
【二分查找】【C++算法】378. 有序矩阵中第 K 小的元素
|
23天前
|
机器学习/深度学习 算法 测试技术
【深度优先搜索】【树】【C++算法】2003. 每棵子树内缺失的最小基因值
【深度优先搜索】【树】【C++算法】2003. 每棵子树内缺失的最小基因值