C++古老算法介绍

2024-02-14 20:04
文章标签 算法 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

这篇关于C++古老算法介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/709466

相关文章

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

Python中win32包的安装及常见用途介绍

《Python中win32包的安装及常见用途介绍》在Windows环境下,PythonWin32模块通常随Python安装包一起安装,:本文主要介绍Python中win32包的安装及常见用途的相关... 目录前言主要组件安装方法常见用途1. 操作Windows注册表2. 操作Windows服务3. 窗口操作

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

C++11委托构造函数和继承构造函数的实现

《C++11委托构造函数和继承构造函数的实现》C++引入了委托构造函数和继承构造函数这两个重要的特性,本文主要介绍了C++11委托构造函数和继承构造函数的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、委托构造函数1.1 委托构造函数的定义与作用1.2 委托构造函数的语法1.3 委托构造函

C++11作用域枚举(Scoped Enums)的实现示例

《C++11作用域枚举(ScopedEnums)的实现示例》枚举类型是一种非常实用的工具,C++11标准引入了作用域枚举,也称为强类型枚举,本文主要介绍了C++11作用域枚举(ScopedEnums... 目录一、引言二、传统枚举类型的局限性2.1 命名空间污染2.2 整型提升问题2.3 类型转换问题三、C

C++链表的虚拟头节点实现细节及注意事项

《C++链表的虚拟头节点实现细节及注意事项》虚拟头节点是链表操作中极为实用的设计技巧,它通过在链表真实头部前添加一个特殊节点,有效简化边界条件处理,:本文主要介绍C++链表的虚拟头节点实现细节及注... 目录C++链表虚拟头节点(Dummy Head)一、虚拟头节点的本质与核心作用1. 定义2. 核心价值二