当前位置: 首页 > news >正文

rust语言项目实战:生成双色球、大乐透所有玩法的所有数字组合(逐行注释)

1、福彩、体彩玩法

  • 福彩
    • 双色球
    • 快乐8
    • 3D
    • 七乐彩
  • 体彩
    • 大乐透
    • 七星彩
    • 排列三
    • 排列五
    • 3D
    • 22选5

2、程序输出结果

===== 福彩双色球 ======
后五个组合: ["28293031323312", "28293031323313", "28293031323314", "28293031323315", "28293031323316"]
前五个组合: ["01020304050601", "01020304050602", "01020304050603", "01020304050604", "01020304050605"]
组合总数量: 17721088===== 福彩快乐8 ======
后五个组合: ["7576777880", "7576777980", "7576787980", "7577787980", "7677787980"]
前五个组合: ["0102030405", "0102030406", "0102030407", "0102030408", "0102030409"]
生成的样本数量: 24040016
提示: 选择10个号码时的组合数约为: 1.6069380442589903e+12(无法在普通计算机上生成所有样本)===== 福彩3D ======
后五个组合: ["995", "996", "997", "998", "999"]
前五个组合: ["000", "001", "002", "003", "004"]
组合总数量: 1000===== 福彩七乐彩 ======
后五个组合: ["23242526282930", "23242527282930", "23242627282930", "23252627282930", "24252627282930"]
前五个组合: ["01020304050607", "01020304050608", "01020304050609", "01020304050610", "01020304050611"]
组合总数量: 2035800===== 体彩大乐透 ======
后五个组合: ["31323334350911", "31323334350912", "31323334351011", "31323334351012", "31323334351112"]
前五个组合: ["01020304050102", "01020304050103", "01020304050104", "01020304050105", "01020304050106"]
组合总数量: 21425712===== 体彩七星彩 ======
后五个组合: ["0009995", "0009996", "0009997", "0009998", "0009999"]
前五个组合: ["0000000", "0000001", "0000002", "0000003", "0000004"]
生成的样本数量: 10000
理论上的总组合数: 10,000,000(可生成所有样本,但需要足够内存)===== 体彩排列三 ======
后五个组合: ["995", "996", "997", "998", "999"]
前五个组合: ["000", "001", "002", "003", "004"]
组合总数量: 1000===== 体彩排列五 ======
后五个组合: ["99995", "99996", "99997", "99998", "99999"]
前五个组合: ["00000", "00001", "00002", "00003", "00004"]
组合总数量: 100000===== 体彩3D ======
后五个组合: ["995", "996", "997", "998", "999"]
前五个组合: ["000", "001", "002", "003", "004"]
组合总数量: 1000===== 体彩22选5 ======
后五个组合: ["1718192022", "1718192122", "1718202122", "1719202122", "1819202122"]
前五个组合: ["0102030405", "0102030406", "0102030407", "0102030408", "0102030409"]
组合总数量: 26334

3、完整代码

// 导入Write特质,用于支持write!宏直接写入String类型,相比push_str更高效地进行字符串拼接
use std::fmt::Write;/// 计算组合数 C(n,k) - 从n个元素中选择k个元素的组合方式数
/// 此函数主要用于预分配内存空间,避免后续动态扩容带来的性能损耗
/// 
/// # 参数
/// - n: 总元素数量,范围为1到n
/// - k: 需要选择的元素数量,范围为1到k
/// 
/// # 返回值
/// 组合数 C(n,k) 的计算结果,表示从n个元素中选择k个元素的不同组合方式总数
fn combination_count(n: u8, k: u8) -> usize {// 边界条件检查:如果选择数量大于总数量或选择数量为0,则没有有效的组合if k > n || k == 0 {return 0;}// 利用组合数的对称性进行计算优化:C(n,k) = C(n,n-k)// 例如,计算C(5,3)等同于计算C(5,2),选择较小的k值可以减少计算次数let k = k.min(n - k); let mut result = 1; // 初始化结果为1// 使用迭代方式计算组合数,避免递归调用可能带来的栈溢出问题// 计算公式:C(n,k) = n*(n-1)*...*(n-k+1)/(k*(k-1)*...*1)for i in 1..=k {result = result * (n - k + i) as usize / i as usize; // 逐步计算组合数}result // 返回计算得到的组合数
}/// 使用迭代方式生成不重复数字组合
/// 采用高效的迭代算法而非递归,避免大规模数据时可能出现的栈溢出问题,适合处理大量组合
/// 
/// # 参数
/// - a: 总数字范围的上限(从1到a)
/// - b: 需要选择的数字数量
/// 
/// # 返回值
/// 包含所有不重复数字组合的字符串向量,每个字符串表示一种有效的组合方式
fn create_unique_combinations(a: u8, b: u8) -> Vec<String> {// 计算组合总数,并预分配结果向量空间,避免后续动态扩容带来的性能损耗let count = combination_count(a, b);let mut result = Vec::with_capacity(count);// 初始化索引数组为[0, 1, 2, ..., b-1],用于跟踪当前组合中每个位置所选数字的索引let mut indices: Vec<u8> = (0..b).collect();// 使用迭代方式生成所有可能的组合// 当indices数组存在(即仍有组合可生成)时继续循环while let Some(_last_idx) = indices.last().copied() {// 生成当前组合对应的数字字符串(数字从1开始)// 预分配字符串容量为b*2,因为每个数字最多需要两位(如01, 23等)let mut s = String::with_capacity(b as usize * 2);// 将索引转换为实际数字并格式化for &idx in &indices {let num = idx + 1; // 将0-based索引转换为1-based数字if num < 10 {write!(s, "0{}", num).unwrap(); // 小于10的数字前补0,保持格式一致性} else {write!(s, "{}", num).unwrap(); // 大于等于10的数字直接写入}}// 将生成的组合添加到结果向量中result.push(s);// 寻找下一个可以递增的索引位置,从右向左查找let mut i = b as isize - 1; // 从最右侧索引开始// 检查当前索引是否已达到其最大值(即a - b + i)// 如果已达到最大值,则向左移动继续查找while i >= 0 && indices[i as usize] == a - b + i as u8 {i -= 1; // 当前索引已达到最大值,继续向左查找}// 如果所有索引都已达到最大值(i < 0),则表示所有组合已生成完毕,退出循环if i < 0 {break;}// 递增当前找到的索引indices[i as usize] += 1;// 重置当前索引右侧的所有索引为连续递增的序列// 例如,如果indices是[0, 2, 3],递增第一个索引后变为[1, 2, 3],然后重置右侧索引为[1, 2, 3]for j in (i + 1) as usize..b as usize {indices[j] = indices[j - 1] + 1;}}result // 返回包含所有组合的向量
}/// 生成可重复数字的排列(如七星彩、排列三/五等玩法)
/// 采用迭代方式高效生成排列,避免递归调用可能带来的性能问题和栈溢出风险
/// 
/// # 参数
/// - digits: 可用数字的数量(通常为10,代表0-9)
/// - length: 排列的长度(如3位、5位、7位等)
/// - max_results: 可选的结果数量限制,用于避免内存溢出
/// 
/// # 返回值
/// 包含所有(或指定数量的)可重复数字排列的字符串向量
fn create_permutations_with_repetition(digits: u8, length: u8, max_results: Option<usize>) -> Vec<String> {// 计算理论上的排列总数上限,使用saturating_mul方法避免整数溢出// 对于不同长度的排列,采用不同的计算策略let max_possible_count = match length {1 => digits as usize, // 1位数字,直接返回可用数字数量2 => (digits as usize).saturating_mul(digits as usize), // 2位数字,digits^2种可能3 => (digits as usize).saturating_mul(digits as usize).saturating_mul(digits as usize), // 3位数字,digits^3种可能5 => {// 对于5位数字(如排列五),有10^5=100,000种组合,内存消耗可接受let base = digits as usize;base.saturating_mul(base).saturating_mul(base).saturating_mul(base).saturating_mul(base)},7 => {// 七星彩有10^7=10,000,000种组合,对普通计算机内存压力较大// 如果需要生成全部组合,可以将此处改为10000000,但需注意内存使用100000 // 默认只生成10万个样本,避免内存占用过大},_ => {// 对于其他长度,根据实际情况动态计算并决定是否生成全部组合let base = digits as usize;let mut count: usize = 1; // 明确指定为usize类型,避免类型推断问题// 计算digits^length,使用saturating_mul防止溢出for _ in 0..length {count = count.saturating_mul(base);}// 如果计算结果小于100,000,000,认为内存可以容纳,允许生成全部组合if count < 100_000_000 {count} else {100_000 // 数量过大时限制样本数,避免内存溢出}}};// 确定实际要生成的结果数量,取理论最大值和用户指定限制的较小值let count = match max_results {Some(limit) => max_possible_count.min(limit), // 用户指定了限制,取两者较小值None => max_possible_count // 用户未指定限制,使用理论最大值};// 预分配结果向量空间,避免动态扩容let mut result = Vec::with_capacity(count);// 预分配每个字符串的容量,等于排列长度let str_capacity = length as usize;// 生成排列结果for i in 0..count {// 为当前排列创建一个新字符串,并预分配容量let mut s = String::with_capacity(str_capacity);let mut num = i; // 使用循环索引作为基础数值// 从右到左构建数字字符串(按位分解)for _ in 0..length {let digit = num % digits as usize; // 通过取模运算获取当前位的数字write!(s, "{}", digit).unwrap(); // 将数字写入字符串num /= digits as usize; // 通过整除运算移至高位}// 反转字符串,因为我们是从右到左构建的,需要恢复为从左到右的顺序s = s.chars().rev().collect();// 将生成的排列添加到结果向量中result.push(s);}result // 返回生成的所有排列
}/// 创建两组不重复数字组合的笛卡尔积
/// 适用于需要两组独立数字组合的彩票类型,如双色球(红球+蓝球)、大乐透(前区+后区)等
/// 
/// # 参数
/// - a: 第一组的数字范围上限(从1到a)
/// - b: 第一组需要选择的数字数量
/// - c: 第二组的数字范围上限(从1到c)
/// - d: 第二组需要选择的数字数量
/// 
/// # 返回值
/// 包含两组组合所有可能配对的笛卡尔积结果的字符串向量
fn create_combined_list(a: u8, b: u8, c: u8, d: u8) -> Vec<String> {// 生成两组独立的不重复数字组合let group1 = create_unique_combinations(a, b); // 第一组组合(例如双色球的红球)let group2 = create_unique_combinations(c, d); // 第二组组合(例如双色球的蓝球)// 计算笛卡尔积的总数量并预分配结果向量空间,避免动态扩容let result_count = group1.len() * group2.len();let mut result = Vec::with_capacity(result_count);// 计算并预分配每个组合字符串的容量,提高内存使用效率// 获取第一组和第二组中第一个字符串的长度作为参考let s1_len = group1.first().map_or(0, |s| s.len());let s2_len = group2.first().map_or(0, |s| s.len());// 执行笛卡尔积操作:将第一组的每个组合与第二组的每个组合进行配对for s1 in &group1 {for s2 in &group2 {// 创建新的组合字符串,并预分配足够的容量let mut combined = String::with_capacity(s1_len + s2_len);combined.push_str(s1); // 添加第一组组合combined.push_str(s2); // 添加第二组组合result.push(combined); // 将组合结果添加到结果向量中}}result // 返回所有可能的组合配对
}// ===== 福彩类型 =====/// 显示福彩双色球的所有组合结果
/// 双色球规则:从1-33中选择6个不重复的红球,从1-16中选择1个蓝球
fn show_double_color_ball_result() {println!("===== 福彩双色球 ======");// 生成双色球组合:33选6(红球组合)和16选1(蓝球组合)的笛卡尔积let combined_result = create_combined_list(33, 6, 16, 1);// 显示后五个组合,使用saturating_sub确保在数组长度不足5时不会发生索引溢出println!("后五个组合: {:?}", &combined_result[combined_result.len().saturating_sub(5)..]);// 显示前五个组合,使用min确保在数组长度不足5时不会发生索引溢出println!("前五个组合: {:?}", &combined_result[0..5.min(combined_result.len())]);// 显示双色球的总组合数量println!("组合总数量: {}", combined_result.len());
}/// 显示福彩快乐8的组合结果
/// 快乐8规则:从1-80中选择1-10个不重复的号码
/// 注意:快乐8选择10个号码时的组合数约为1.6e+12,数量过大,无法在普通计算机上生成所有样本
fn show_happy_eighty_result() {println!("===== 福彩快乐8 ======");// 为了避免内存溢出和处理时间过长,这里仅生成选择5个号码的组合// 实际中快乐8可以选择1-10个号码,但选择10个号码的组合数约为1.6e+12,// 远超过普通计算机的内存和处理能力let results = create_unique_combinations(80, 5);// 显示生成的组合样本println!("后五个组合: {:?}", &results[results.len().saturating_sub(5)..]);println!("前五个组合: {:?}", &results[0..5.min(results.len())]);println!("生成的样本数量: {}", results.len());println!("提示: 选择10个号码时的组合数约为: 1.6069380442589903e+12(无法在普通计算机上生成所有样本)");
}/// 显示福彩3D的所有组合结果
/// 福彩3D规则:从0-9中选择3个可重复的数字
fn show_welfare_3d_result() {println!("===== 福彩3D ======");// 福彩3D:从0-9中选择3个可重复的数字,总共有10^3=1,000种组合// None参数表示生成所有可能的组合let results = create_permutations_with_repetition(10, 3, None);println!("后五个组合: {:?}", &results[results.len().saturating_sub(5)..]);println!("前五个组合: {:?}", &results[0..5.min(results.len())]);println!("组合总数量: {}", results.len());
}/// 显示福彩七乐彩的所有组合结果
/// 福彩七乐彩规则:从1-30中选择7个不重复的数字
fn show_welfare_seven_happiness_result() {println!("===== 福彩七乐彩 ======");// 福彩七乐彩:从1-30中选择7个不重复的数字let results = create_unique_combinations(30, 7);println!("后五个组合: {:?}", &results[results.len().saturating_sub(5)..]);println!("前五个组合: {:?}", &results[0..5.min(results.len())]);println!("组合总数量: {}", results.len());
}// ===== 体彩类型 =====/// 显示体彩大乐透的所有组合结果
/// 大乐透规则:从1-35中选择5个不重复的前区号码,从1-12中选择2个不重复的后区号码
fn show_lotto_result() {println!("===== 体彩大乐透 ======");// 生成大乐透组合:35选5(前区号码组合)和12选2(后区号码组合)的笛卡尔积let combined_result = create_combined_list(35, 5, 12, 2);println!("后五个组合: {:?}", &combined_result[combined_result.len().saturating_sub(5)..]);println!("前五个组合: {:?}", &combined_result[0..5.min(combined_result.len())]);println!("组合总数量: {}", combined_result.len());
}/// 显示体彩七星彩的组合结果
/// 七星彩规则:从0-9中选择7个可重复的数字
fn show_seven_star_result() {println!("===== 体彩七星彩 ======");// 七星彩:从0-9中选择7个可重复的数字,理论上有10^7=10,000,000种组合// 为了避免内存占用过大,默认只生成10,000个样本// 如果需要生成全部组合,可以将max_results参数改为None(约需要数百MB内存)let results = create_permutations_with_repetition(10, 7, Some(10000));println!("后五个组合: {:?}", &results[results.len().saturating_sub(5)..]);println!("前五个组合: {:?}", &results[0..5.min(results.len())]);println!("生成的样本数量: {}", results.len());println!("理论上的总组合数: 10,000,000(可生成所有样本,但需要足够内存)");
}/// 显示体彩排列三的所有组合结果
/// 排列三规则:从0-9中选择3个可重复的数字
fn show_permutation_three_result() {println!("===== 体彩排列三 ======");// 排列三:从0-9中选择3个可重复的数字,总共有10^3=1,000种组合// None参数表示生成所有可能的组合let results = create_permutations_with_repetition(10, 3, None);println!("后五个组合: {:?}", &results[results.len().saturating_sub(5)..]);println!("前五个组合: {:?}", &results[0..5.min(results.len())]);println!("组合总数量: {}", results.len());
}/// 显示体彩排列五的所有组合结果
/// 排列五规则:从0-9中选择5个可重复的数字
/// 说明:排列五有10^5=100,000种组合,数量适中,可以在普通计算机上生成所有样本
fn show_permutation_five_result() {println!("===== 体彩排列五 ======");// 排列五:从0-9中选择5个可重复的数字,总共有10^5=100,000种组合// 此数量在普通计算机内存中完全可行,因此生成所有组合let results = create_permutations_with_repetition(10, 5, None);println!("后五个组合: {:?}", &results[results.len().saturating_sub(5)..]);println!("前五个组合: {:?}", &results[0..5.min(results.len())]);println!("组合总数量: {}", results.len());
}/// 显示体彩3D的所有组合结果
/// 体彩3D规则:从0-9中选择3个可重复的数字
fn show_sports_3d_result() {println!("===== 体彩3D ======");// 体彩3D:从0-9中选择3个可重复的数字,总共有10^3=1,000种组合// None参数表示生成所有可能的组合let results = create_permutations_with_repetition(10, 3, None);println!("后五个组合: {:?}", &results[results.len().saturating_sub(5)..]);println!("前五个组合: {:?}", &results[0..5.min(results.len())]);println!("组合总数量: {}", results.len());
}/// 显示体彩22选5的所有组合结果
/// 体彩22选5规则:从1-22中选择5个不重复的数字
fn show_sports_22_choose_5_result() {println!("===== 体彩22选5 ======");// 体彩22选5:从1-22中选择5个不重复的数字let results = create_unique_combinations(22, 5);println!("后五个组合: {:?}", &results[results.len().saturating_sub(5)..]);println!("前五个组合: {:?}", &results[0..5.min(results.len())]);println!("组合总数量: {}", results.len());
}/// 程序入口函数
/// 按照福彩在前、体彩在后的顺序显示所有彩票的组合结果
fn main(){// 首先显示所有福彩类型的组合结果// ===== 福彩 =====show_double_color_ball_result(); // 显示福彩双色球结果println!(); // 输出空行,分隔不同的彩票类型show_happy_eighty_result(); // 显示福彩快乐8结果println!();show_welfare_3d_result(); // 显示福彩3D结果println!();show_welfare_seven_happiness_result(); // 显示福彩七乐彩结果println!();// 然后显示所有体彩类型的组合结果// ===== 体彩 =====show_lotto_result(); // 显示体彩大乐透结果println!();show_seven_star_result(); // 显示体彩七星彩结果println!();show_permutation_three_result(); // 显示体彩排列三结果println!();show_permutation_five_result(); // 显示体彩排列五结果println!();show_sports_3d_result(); // 显示体彩3D结果println!();show_sports_22_choose_5_result(); // 显示体彩22选5结果
}
http://www.dtcms.com/a/388916.html

相关文章:

  • 远程配置服务器 ubuntu22.04 里的 docker 的x11
  • rust编写web服务03-错误处理与响应封装
  • Docker基础篇07:Docker容器数据卷
  • WPF 拖拽(Drag Drop)完全指南:从入门到精通
  • rust编写web服务05-数据库连接池
  • AppInventor2使用本地SQLite实现用户注册登录功能
  • Prompt(提示词工程)优化
  • Ubuntu 系统安装 PostgreSQL 17.6
  • Kotlin-基础语法练习四
  • 开源的消逝与新生:从 TensorFlow 的落幕到开源生态的蜕
  • 原创GIS FOR Unity3d PAD VR LINUXPC 同时支持。非cesium
  • Kotlin中协程的管理
  • django如何自己写一个登录时效验证中间件
  • 【大前端++】初始技术栈跨平台方案Electron+Vue,MacOS开发环境搭建【十分钟一个Demo】
  • 限时起售价17.38万元,吉利银河M9上市
  • Vue : defineModel()
  • 一套基于Java+Vue+UniApp开发的同城配送系统
  • Vue 3 手机外观组件库
  • 部署分布式CephFS,存储的服务器的最低配置
  • 【Spring AI】Ollama大模型-智能对话实现+项目实战(Spring Boot + Vue)
  • Vue 3 实战:GIS 系统模块化设计与多功能融合方案
  • Docker多容器编排:Compose 实战教程——从入门到精通
  • Vue2 基础知识点一:数据绑定 (Data Binding)
  • layui tree组件回显bug问题,父级元素选中导致子集全部选中
  • centos7上使用Docker+ RagFlow + ollama + 数据集 搭建自己的AI问答机器人(2025-09)
  • # 从 Gymnasium 到 Minari:新一代机器人强化学习工具链全指南
  • 系统架构设计师备考第27天——基于构件的软件工程
  • Centos下安装docker
  • OpenAPI 规范:构建高效 RESTful API 指南
  • 基于 AForge.NET 的 C# 人脸识别