news 2026/7/7 9:45:18

【C++ 经典算法】贪心算法求解股票最大利润(兼容 C++98/03)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【C++ 经典算法】贪心算法求解股票最大利润(兼容 C++98/03)

在股票交易策略分析中,“单次买卖最大化利润” 是经典的算法问题,贪心算法凭借 O (n) 时间复杂度、O (1) 空间复杂度的优势,成为该问题的最优解。本文将从原理、实现、兼容优化三个维度,详解贪心算法求解股票最大利润的完整方案,且所有代码兼容 C++98/03(5.11 以下版本),适配老旧编译器。

一、问题背景与贪心核心思想

1. 问题定义

给定一组连续 N 天的股票价格,只能进行一次 “买入 - 卖出” 操作(买入必须在卖出前),求能获得的最大利润;若价格持续下跌,利润为 0(不交易)。

2. 贪心算法核心逻辑

贪心算法的本质是 “局部最优推导全局最优”,针对该问题的核心策略:

  • 找最小买入价:遍历过程中持续更新 “当前为止的最低价格”,作为最优买入点;
  • 算最大卖出利润:对于每个价格,计算 “当前价格 - 最小买入价” 的利润,持续更新全局最大利润。

简单来说:在最便宜的时候买入,在之后最贵的时候卖出

二、完整实现代码(C++98/03 兼容版)

代码包含 “随机生成 30 天股票价格”+“贪心算法求解”+“性能计时”,全程无 C++11 特性,兼容所有老旧编译器:

#include <vector>
#include <iostream>
#include <climits>
#include <ctime> // 计时+随机数种子头文件
#include <iomanip> // 格式化输出
#include <cstdlib>

// 定义返回结构体
struct StockResult {
int maxProfit; // 最大利润
int buyDay; // 买入日期(1-based)
int sellDay; // 卖出日期(1-based)
double elapsedTime; // 算法执行耗时(秒)
bool hasProfit; // 是否存在盈利空间

// C++98 构造函数(替代列表初始化)
StockResult() : maxProfit(0), buyDay(0), sellDay(0), elapsedTime(0.0), hasProfit(false) {}
};

// 生成30天随机股票价格
std::vector<int> generate30DaysRandomPrices() {
std::vector<int> prices;
prices.reserve(30); // 预分配空间

// ===== 关键适配:随机数种子初始化 =====

// 拆分转换步骤,避免编译器类型校验警告
time_t raw_seed = time(0); //用time(0)替代time(NULL),C++98 更兼容
unsigned int seed = static_cast<unsigned int>(raw_seed);
srand(seed); // C++98 标准写法,无任何高版本依赖

// 第一天价格:5~100 随机
int prevPrice = 5 + (rand() % 96); // rand()%96 生成0~95,+5后5~100
prices.push_back(prevPrice);

// 生成后续29天价格:每日波动±10%以内
for (int i = 1; i < 30; ++i) {
// 计算波动幅度:±10%(取整)
int fluctuate = static_cast<int>(prevPrice * 0.1);
if (fluctuate < 1) {
fluctuate = 1; // 避免波动为0
}

// 随机涨跌:-fluctuate ~ +fluctuate
int change = (rand() % (2 * fluctuate + 1)) - fluctuate;
int currentPrice = prevPrice + change;

// 确保价格不低于5(避免负数/极低价格)
if (currentPrice < 5) {
currentPrice = 5;
}
prices.push_back(currentPrice);
prevPrice = currentPrice; // 更新前一天价格
}

// 打印生成的30天价格(格式化输出)
std::cout << "=== 生成30天随机股票价格 ===" << std::endl;
for (int i = 0; i < 30; ++i) {
std::cout << "第" << std::setw(2) << (i+1) << "天:" << std::setw(3) << prices[i];
if ((i+1) % 6 == 0) {
std::cout << std::endl; // 每6个换行
} else {
std::cout << " | ";
}
}
std::cout << "\n" << std::endl;

return prices;
}

// 贪心算法
StockResult greedyOnePassOptimized(const std::vector<int>& prices) {
clock_t start = clock(); // C++98 计时
int n = prices.size();
StockResult result; // 调用默认构造函数

if (n < 2) {
clock_t end = clock();
result.elapsedTime = static_cast<double>(end - start) / CLOCKS_PER_SEC;
std::cout << "价格数据不足,无法进行买卖操作!" << std::endl;
return result;
}

int minBuyPrice = prices[0];
int bestBuyDay = 1;
int bestSellDay = 1;
int currentMaxProfit = 0;
int prevMaxProfit = 0;

std::cout << "执行日志: 开始遍历30天价格数据,实时监控最优买卖时机..." << std::endl;
for (int i = 1; i < n; ++i) {
int currentDay = i + 1;
int currentPrice = prices[i];

if (currentPrice < minBuyPrice) {
minBuyPrice = currentPrice;
bestBuyDay = currentDay;
std::cout << "更新: 第" << currentDay << "天价格" << currentPrice
<< ",刷新最小买入价→" << minBuyPrice << std::endl;
} else {
int currentProfit = currentPrice - minBuyPrice;
if (currentProfit > currentMaxProfit) {
prevMaxProfit = currentMaxProfit;
currentMaxProfit = currentProfit;
bestSellDay = currentDay;
result.hasProfit = true;
std::cout << "最优更新: 第" << bestBuyDay << "天买入(" << minBuyPrice << "),第" << bestSellDay << "天卖出(" << currentPrice << ")"
<< ",最大利润从" << prevMaxProfit << "提升至" << currentMaxProfit << std::endl;
}
}
}

result.maxProfit = currentMaxProfit;
result.buyDay = result.hasProfit ? bestBuyDay : 0;
result.sellDay = result.hasProfit ? bestSellDay : 0;

clock_t end = clock();
result.elapsedTime = static_cast<double>(end - start) / CLOCKS_PER_SEC;

std::cout << "\n算法执行完毕:耗时:" << result.elapsedTime << " 秒" << std::endl;
if (result.hasProfit) {
std::cout << "最终最优解:买入日:第" << result.buyDay << "天,卖出日:第" << result.sellDay << "天,最大利润:" << result.maxProfit << std::endl;
} else {
std::cout << "最终结论:价格持续下跌,无盈利空间,建议持币观望!" << std::endl;
}

return result;
}

// 主函数
int main() {
std::vector<int> prices30Days = generate30DaysRandomPrices();
std::cout << "=== 开始分析30天股票最优买卖时机 ===" << std::endl;
greedyOnePassOptimized(prices30Days);
return 0;
}

三、代码核心解析

1. 兼容 C++98 的关键设计

特性兼容方案
随机数生成rand()/srand()替代 C++11<random>,种子基于time(0)确保随机性
计时功能clock()+CLOCKS_PER_SEC替代std::chrono,适配老旧编译器
结构体初始化自定义构造函数替代列表初始化,避免 C++11 语法依赖
向量初始化数组迭代器 /push_back替代列表初始化,兼容 C++98 的vector用法

2. 贪心算法执行流程

  1. 初始化:将第一天价格设为初始最小买入价,最大利润初始为 0;
  2. 遍历价格:从第二天开始,要么更新最小买入价,要么计算当前利润并刷新最大利润;
  3. 结果封装:根据是否盈利,返回对应的买卖日期和利润,同时输出算法耗时;
  4. 边界处理:覆盖 “价格数组长度 < 2”“全程下跌无盈利” 等极端场景。

3. 性能优势

  • 时间复杂度:O (n),仅需一次遍历即可完成计算;
  • 空间复杂度:O (1),仅使用常数级临时变量,无额外空间开销;
  • 实际耗时:30 天价格数据的计算耗时通常在 10 微秒以内,效率极高。

四、运行结果示例

=== 生成30天随机股票价格 ===
第 1天: 6 | 第 2天: 6 | 第 3天: 7 | 第 4天: 8 | 第 5天: 7 | 第 6天: 6
第 7天: 5 | 第 8天: 6 | 第 9天: 5 | 第10天: 6 | 第11天: 5 | 第12天: 6
第13天: 5 | 第14天: 5 | 第15天: 6 | 第16天: 6 | 第17天: 6 | 第18天: 5
第19天: 5 | 第20天: 5 | 第21天: 6 | 第22天: 5 | 第23天: 5 | 第24天: 5
第25天: 5 | 第26天: 5 | 第27天: 5 | 第28天: 6 | 第29天: 6 | 第30天: 5


=== 开始分析30天股票最优买卖时机 ===
执行日志: 开始遍历30天价格数据,实时监控最优买卖时机...
最优更新: 第1天买入(6),第3天卖出(7),最大利润从0提升至1
最优更新: 第1天买入(6),第4天卖出(8),最大利润从1提升至2
更新: 第7天价格5,刷新最小买入价→5

算法执行完毕:耗时:0.008 秒
最终最优解:买入日:第7天,卖出日:第4天,最大利润:2

五、应用场景与扩展

  1. 量化交易回测:结合历史价格数据,验证贪心策略的实际收益;
  2. 多维度优化:可扩展为 “允许多次买卖” 的贪心变种(拆分上涨区间);
  3. 跨语言适配:核心逻辑可无缝迁移至 Java、Python 等语言,仅需调整语法细节。

总结

贪心算法以 “局部最优” 的简洁思路,完美解决了 “单次股票买卖最大化利润” 问题,本文实现的版本不仅保留了算法的高性能,还通过 C++98 兼容设计,适配了老旧编译器环境。无论是算法学习、面试刷题,还是实际量化策略开发,该方案都具备极高的参考价值。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 16:10:07

K8S-蓝绿发布与金丝雀发布

一、蓝绿发布在Kubernetes中&#xff0c;蓝绿发布&#xff08;Blue-Green Deployment&#xff09; 是一种部署策略&#xff0c;通过同时维护两个完全独立的生产环境&#xff08;“蓝”和“绿”&#xff09;&#xff0c;在验证新版本&#xff08;绿&#xff09;后&#xff0c;一…

作者头像 李华
网站建设 2026/7/7 14:21:20

并发编程的锁有哪些?怎么分类?

文章目录一、按【实现方式】分类1. synchronized(JVM内置锁)2. lock&#xff08;JUC显示锁&#xff09;二、按【线程是否阻塞】分类1. 阻塞锁2. 自旋锁三、 按【是否公平】划分1. 公平锁2. 非公平锁四、按【锁的重入性】划分1. 可重入锁2. 不可重入锁五、 按【锁的作用范围】划…

作者头像 李华
网站建设 2026/7/7 11:30:22

航空机票预定系统|基于springboot 航空机票预定系统(源码+数据库+文档)

航空机票预定 目录 基于springboot vue航空机票预定系统 一、前言 二、系统功能演示 ​三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 基于springboot vue航空机票预定系统 一、前言 博主介绍&am…

作者头像 李华
网站建设 2026/7/7 4:30:58

【奶茶Beta专项】【LVGL9.4源码分析】07-API映射管理

【奶茶Beta专项】【LVGL9.4源码分析】07-API映射管理1 概述1.1 文档目的1.2 代码版本与范围2 设计意图与总体定位2.1 问题背景2.2 API 映射头的角色2.3 设计目标2.4 本文分析对象与侧重点3 使用方法3.1 在 C/C 代码中的使用3.2 在绑定/自动生成工具中的使用3.3 从 v8 升级到 v9…

作者头像 李华
网站建设 2026/7/7 11:54:55

【奶茶Beta专项】【LVGL9.4源码分析】08-theme主题管理

【奶茶Beta专项】【LVGL9.4源码分析】08-theme主题管理1 概述1.1 文档目的1.2 代码版本与范围2 设计意图与总体定位2.1 主题在 LVGL 中扮演的角色2.2 与对象系统/样式系统的关系2.3 主题链与可扩展性3 使用方法3.1 在 C 代码中启用并应用主题3.2 在自定义主题中复用默认行为3.3…

作者头像 李华
网站建设 2026/7/7 18:15:04

[Windows] 剪映自动预合成v1.0

[Windows] 剪映自动预合成v1.0 链接&#xff1a;https://pan.xunlei.com/s/VOgRWgF_QfvslGjXSYwZaeDXA1?pwdrd56# 从零散的元素 【进入】预合成状态&#xff0c;一键完成。 配合47kb的【剪映草稿助手】还是不错的。

作者头像 李华