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

高精度超几何分布

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #define MAX_DIGITS 2000 // 高精度数最大位数 #define MAX_PRIMES 200 // 最大质因数数量 // 高精度整数结构体(低位在前存储) typedef struct { int digits[MAX_DIGITS]; int len; // 有效位数 } BigInt; // 质因数结构体 typedef struct { int prime; int exp; } Factor; // 质因数列表 typedef struct { Factor factors[MAX_PRIMES]; int len; // 质因数个数 } FactorList; // ==================== 高精度整数操作 ==================== // 初始化高精度整数为1 void bigIntInit(BigInt *num) { memset(num->digits, 0, sizeof(num->digits)); num->len = 1; num->digits[0] = 1; } // 高精度整数乘以普通整数 void bigIntMultiply(BigInt *num, int factor) { int carry = 0; for (int i = 0; i < num->len; i++) { long long product = (long long)num->digits[i] * factor + carry; num->digits[i] = product % 10; carry = product / 10; } // 处理剩余进位 while (carry > 0 && num->len < MAX_DIGITS) { num->digits[num->len] = carry % 10; carry /= 10; num->len++; } } // 将高精度整数转换为字符串(高位在前) void bigIntToString(BigInt *num, char *str) { int idx = 0; if (num->len == 1 && num->digits[0] == 0) { str[idx++] = '0'; str[idx] = '\0'; return; } // 从高位到低位拼接 for (int i = num->len - 1; i >= 0; i--) { str[idx++] = num->digits[i] + '0'; } str[idx] = '\0'; } // ==================== 质因数相关操作 ==================== // Legendre公式:计算n!中质因数p的指数 int legendre(int n, int p) { int count = 0; while (n > 0) { n /= p; count += n; } return count; } // 分解n的质因数 void primeFactors(int n, FactorList *factors) { factors->len = 0; if (n < 2) return; // 分解2 if (n % 2 == 0) { factors->factors[factors->len].prime = 2; factors->factors[factors->len].exp = 0; while (n % 2 == 0) { factors->factors[factors->len].exp++; n /= 2; } factors->len++; } // 分解奇数 for (int i = 3; i * i <= n; i += 2) { if (n % i == 0) { factors->factors[factors->len].prime = i; factors->factors[factors->len].exp = 0; while (n % i == 0) { factors->factors[factors->len].exp++; n /= i; } factors->len++; } } // 剩余的大质数 if (n > 1) { factors->factors[factors->len].prime = n; factors->factors[factors->len].exp = 1; factors->len++; } } // 获取组合数C(n,k)的质因数分解 void combPrimeFactors(int n, int k, FactorList *factors) { factors->len = 0; if (k < 0 || k > n) return; if (k == 0 || k == n) return; // 收集n以内所有质因数 FactorList allPrimes; allPrimes.len = 0; for (int i = 2; i <= n; i++) { FactorList temp; primeFactors(i, &temp); // 去重添加质因数 for (int j = 0; j < temp.len; j++) { bool exists = false; for (int m = 0; m < allPrimes.len; m++) { if (allPrimes.factors[m].prime == temp.factors[j].prime) { exists = true; break; } } if (!exists) { allPrimes.factors[allPrimes.len].prime = temp.factors[j].prime; allPrimes.len++; } } } // 计算每个质因数的指数 for (int i = 0; i < allPrimes.len; i++) { int p = allPrimes.factors[i].prime; int exp = legendre(n, p) - legendre(k, p) - legendre(n - k, p); if (exp > 0) { factors->factors[factors->len].prime = p; factors->factors[factors->len].exp = exp; factors->len++; } } } // 合并两个质因数列表(指数相加) void mergeFactorLists(FactorList *dst, FactorList *a, FactorList *b) { // 复制a到dst memcpy(dst, a, sizeof(FactorList)); // 合并b到dst for (int i = 0; i < b->len; i++) { int p = b->factors[i].prime; int exp = b->factors[i].exp; bool found = false; for (int j = 0; j < dst->len; j++) { if (dst->factors[j].prime == p) { dst->factors[j].exp += exp; found = true; break; } } if (!found) { dst->factors[dst->len].prime = p; dst->factors[dst->len].exp = exp; dst->len++; } } } // 约分:抵消分子分母的公共质因数 void reduceFactors(FactorList *numFactors, FactorList *denFactors) { for (int i = 0; i < numFactors->len; i++) { int p = numFactors->factors[i].prime; for (int j = 0; j < denFactors->len; j++) { if (denFactors->factors[j].prime == p) { int minExp = numFactors->factors[i].exp < denFactors->factors[j].exp ? numFactors->factors[i].exp : denFactors->factors[j].exp; numFactors->factors[i].exp -= minExp; denFactors->factors[j].exp -= minExp; // 移除指数为0的质因数 if (numFactors->factors[i].exp == 0) { // 移位删除 for (int m = i; m < numFactors->len - 1; m++) { numFactors->factors[m] = numFactors->factors[m + 1]; } numFactors->len--; i--; // 回退索引 } if (denFactors->factors[j].exp == 0) { for (int m = j; m < denFactors->len - 1; m++) { denFactors->factors[m] = denFactors->factors[m + 1]; } denFactors->len--; j--; } break; } } } } // ==================== 超几何分布计算 ==================== void hypergeometricDistribution(int N, int K, int n, int k, BigInt *numerator, BigInt *denominator) { // 边界检查 if (k < 0 || k > K || (n - k) < 0 || (n - k) > (N - K)) { bigIntInit(numerator); numerator->digits[0] = 0; bigIntInit(denominator); denominator->digits[0] = 1; return; } // 1. 计算分子质因数:C(K,k) * C(N-K, n-k) FactorList c1, c2, numFactors; combPrimeFactors(K, k, &c1); combPrimeFactors(N - K, n - k, &c2); mergeFactorLists(&numFactors, &c1, &c2); // 2. 计算分母质因数:C(N,n) FactorList denFactors; combPrimeFactors(N, n, &denFactors); // 3. 约分 reduceFactors(&numFactors, &denFactors); // 4. 高精度计算分子 bigIntInit(numerator); for (int i = 0; i < numFactors.len; i++) { int p = numFactors.factors[i].prime; int exp = numFactors.factors[i].exp; for (int j = 0; j < exp; j++) { bigIntMultiply(numerator, p); } } // 5. 高精度计算分母 bigIntInit(denominator); for (int i = 0; i < denFactors.len; i++) { int p = denFactors.factors[i].prime; int exp = denFactors.factors[i].exp; for (int j = 0; j < exp; j++) { bigIntMultiply(denominator, p); } } } // ==================== 主函数测试 ==================== int main() { // 测试用例1:小参数验证 int N1 = 10, K1 = 5, n1 = 3, k1 = 2; BigInt num1, den1; char numStr1[MAX_DIGITS], denStr1[MAX_DIGITS]; hypergeometricDistribution(N1, K1, n1, k1, &num1, &den1); bigIntToString(&num1, numStr1); bigIntToString(&den1, denStr1); printf("测试用例1 (N=%d, K=%d, n=%d, k=%d):\n", N1, K1, n1, k1); printf(" 分子: %s\n", numStr1); printf(" 分母: %s\n", denStr1); printf(" 最简分数: %s/%s\n\n", numStr1, denStr1); // 测试用例2:大参数验证 int N2 = 1000, K2 = 358, n2 = 600, k2 = 240; BigInt num2, den2; char numStr2[MAX_DIGITS], denStr2[MAX_DIGITS]; printf("正在计算大参数,请稍候...\n"); hypergeometricDistribution(N2, K2, n2, k2, &num2, &den2); bigIntToString(&num2, numStr2); bigIntToString(&den2, denStr2); printf("测试用例2 (N=%d, K=%d, n=%d, k=%d):\n", N2, K2, n2, k2); printf(" 分子: %s\n", numStr2); printf(" 分母: %s\n", denStr2); printf(" 最简分数: %s/%s\n", numStr2, denStr2); return 0; }
http://www.jsqmd.com/news/1184699/

相关文章:

  • Windows系统深度清理指南:安全释放C盘与数据盘空间
  • 系统引导故障修复指南:从原理到实践的完整解决方案
  • UE5蓝图交互系统实战:从开关门案例掌握事件驱动与组件通信
  • 15分钟用Elasticsearch搭建真实可用的全文搜索系统
  • Linux系统硬件信息一站式查询:从GPU显存到硬盘分区的实用命令集
  • Jetson TK1终端优化:bash-completion与command-not-found实战配置
  • DonkeyCar树莓派部署避坑指南:版本兼容性与环境配置实战
  • 铁路轨道设备探析1:从有砟到无砟的轨道结构演进
  • 遗传算法工程化实战:从理论到工业级优化器构建
  • Ubuntu截图工具演进:从Shutter到Flameshot的迁移指南
  • WPS Pro特殊版深度解析:免费解锁VIP功能的技术实现与风险
  • 主数据清洗实战:Python分层流水线与20个高可用库
  • 2026年AI前沿部署工程师(FDE)核心技能与实战指南
  • 豆包AI搜索推广技术解析:从GEO优化到智能出价实战指南
  • Windows系统深度清理指南:彻底解决C盘空间不足问题
  • LangChain v1.3实战:Agent智能体与RAG检索增强生成开发指南
  • 为什么91%的AI Office插件在Win11 24H2更新后失效?——微软Partner工程师紧急发布的3步修复协议
  • 遗传算法工程落地五大断层与实操解决方案
  • Claude Mythos:首个端到端自主渗透测试的大模型
  • L9958与TM4C1294KCPDT电机驱动方案解析
  • Makefile快速上手笔记
  • Claude Code图片生成API实战:从请求构建到生产环境部署
  • Pandas数据清洗与分析实战速查:从摸底到交付的27个关键操作
  • AI商业秘密保护失效的根源:从代码窃取到能力迁移
  • AI工作流集成:从内容创作到变现的自媒体自动化实践
  • 系统引导修复工具:从原理到实战的完整解决方案
  • 用SIR玩具模型理解疫情传播:从R0到拐点的数学逻辑
  • 行测言语理解:结构分析法实战,总分结构如何快速锁定主旨
  • AI高效推理技术:动态计算分配与路径优化
  • YOLOv26目标检测:RepViT与双路径特征混合技术解析