VBA实战(Excel)(5):介绍一种排列组合算法
1. 需求场景
有多个条件,条件个数不定,每个条件有若干种情况,情况个数不定,输出所有条件可能的情况的排列组合。
2.举例
假设第一次有5个情况要填,第一个条件20种情况,第二个5种,第三个40种,第四个10种,第五个4种。那么共要输出条件数=20x5x40x10x4=160000种,第二次可能要输出30万钟,等等......
3.实现程序
Sub getalldata(control As Office.IRibbonControl) '生成sht_name = Sheets("参数").Cells(2, 2)datamp4 = Sheets(sht_name).Range("A1:Z20000")Dim datamp5(50, 2000) As String 'datamp5存储批量条件数据Dim datamp6(1000000, 20) As VariantDim ribbon As IRibbonUItn = 0For i = 1 To 20000If datamp4(i, 1) = "" And datamp4(i, 2) = "" Then'Call ProcessBarUpdater(20000, 20000, "正在处理")Exit ForEnd IfIf datamp4(i, 1) = "" And datamp4(i, 2) <> "" Thentn = tn + 1End IfNexttnn = 0jd = TrueFor i = 1 To 20000If datamp4(i, 1) = "" And datamp4(i, 2) = "" ThenExit ForEnd IfIf datamp4(i, 1) = "" And datamp4(i, 2) <> "" Thentnn = tnn + 1'------处理条件,生成条件二维数组------For j = 2 To 25If InStr(datamp4(i, j), ";") > 0 Or InStr(datamp4(i, j), "~") > 0 ThenIf InStr(datamp4(i, j), ";") > 0 ThenIf InStr(datamp4(i, j), "~") > 0 Then'情况1含波浪号和波浪号n = 0For ni = 0 To UBound(Split(datamp4(i, j), ";"))If InStr(Split(datamp4(i, j), ";")(ni), "~") > 0 ThenFor nn = Split(Split(datamp4(i, j), ";")(ni), "~")(0) To Split(Split(Split(datamp4(i, j), ";")(ni), "~")(1), "(")(0) Step Replace(Split(Split(Split(datamp4(i, j), ";")(ni), "~")(1), "(")(1), ")", "")datamp5(j - 2, n) = nnn = n + 1Nextdatamp5(j - 2, n) = Split(Split(Split(datamp4(i, j), ";")(ni), "~")(1), "(")(0)n = n + 1Elsedatamp5(j - 2, n) = Split(datamp4(i, j), ";")(ni)n = n + 1End IfNextElse'情况2只含分号For n = 0 To UBound(Split(datamp4(i, j), ";")) '从情况2和情况3理解情况1datamp5(j - 2, n) = Split(datamp4(i, j), ";")(n)NextEnd IfElse'情况3只含波浪号If InStr(datamp4(i, j), "~") > 0 Thenn = 0For ni = Split(datamp4(i, j), "~")(0) To Split(Split(datamp4(i, j), "~")(1), "(")(0) Step Replace(Split(Split(datamp4(i, j), "~")(1), "(")(1), ")", "")datamp5(j - 2, n) = nin = n + 1Nextdatamp5(j - 2, n) = Split(Split(datamp4(i, j), "~")(1), "(")(0)End IfEnd IfElsedatamp5(j - 2, 0) = datamp4(i, j)End IfNext'------处理条件,生成条件二维数组------'------计算数据量------tn = 1For li = 0 To 50 'li为条件个数,lj为每个条件的选项个数If datamp5(li, 0) <> "" ThenFor lj = 0 To 2000If datamp5(li, lj) = "" ThenExit ForElse'Debug.Print datamp5(li, lj)End IfNexttn = tn * ljEnd IfNext'Debug.Print tn'------计算数据量------'------二维数组转为一维排列组合------For li = 0 To 50 'li为条件个数If datamp5(li, 0) <> "" ThenFor lj = 0 To 2000If datamp5(li, lj) = "" ThenExit ForEnd IfNext'Debug.Print lj 'lj为每个条件的选项个数If li = 0 ThenFor jj = 0 To lj - 1If datamp5(0, jj) <> "" Thendatamp6(jj, 0) = datamp5(0, jj) '赋值给数组ElseExit ForEnd IfNext'Debug.Print jj’第一个条件的情况数Else'Debug.Print "-----------"If li = 1 ThenFor ii = 0 To 10000 '每个条件开始前计算已有的情况个数对应的行数If datamp6(ii, 0) = "" ThenExit ForEnd IfNextElseIf n = 0 ThenFor ii = 0 To 10000 '每个条件开始前计算已有的情况个数对应的行数If datamp6(ii, 0) = "" ThenExit ForEnd IfNextElseii = n 'End IfEnd If'Debug.Print "ii=" & iin = 0For mi = 0 To lj - 1 'datamp5第i个条件的选项个数For ni = 0 To ii - 1 'datamp6数组的行数For nj = 0 To li 'datamp6数组的列数If nj < li Then'第i之前直接复制datamp6(n, nj) = datamp6(ni, nj)' If i < 7 Then' Debug.Print n & ";" & ni & ";" & nj' End IfElse'第i个取datamp5的值datamp6(n, nj) = datamp5(li, mi)' If i < 7 Then' Debug.Print n & ";" & i' End If'Debug.Print datamp5(i, mi)End IfIf li = 7 Then'Debug.Print n & "," & nj & "=" & datamp6(n, nj)End IfNextIf lj - 1 > 0 Or ii - 1 > 0 Thenn = n + 1End IfNextNextEnd IfElseExit ForEnd If'Debug.Print "n=" & nNextApplication.ScreenUpdating = Falseni = Sheets("扭矩查询").Range("a" & Rows.Count).End(xlUp).Row + 1For li = 0 To 1000000If datamp6(li, 0) <> "" ThenFor j = 0 To 20'Debug.Print i & "," & j & "=" & datamp6(i, j)Sheets("扭矩查询").Cells(ni + li, j + 1) = datamp6(li, j)NextElseExit ForEnd IfNext'------二维数组转为一维排列组合------Sheets(sht_name).Cells(i, 1) = TrueFor t = 1 To 25If datamp4(1, t) = "" ThenFor ti = t + 1 To 26If datamp4(i, ti) = "" ThenSheets(sht_name).Cells(i, ti) = Format(Now(), "YYYY/MM/DD hh:mm")Exit ForEnd IfNextExit ForEnd IfNextErase datamp5Erase datamp6Application.ScreenUpdating = TrueEnd IfIf tnn <> 0 And jd = True Then'Debug.Print tnn & ";" & tnCall ProcessBarUpdater(tnn, tn, "正在处理")End IfIf tnn = tn Thenjd = FalseEnd IfNextFor i = 0 To 50 '打印For j = 0 To 500If datamp5(i, j) <> "" Then'Debug.Print i & ";" & j & "=" & datamp5(i, j)ElseExit ForEnd IfNextNextErase datamp4
End Sub
4. 算法思路讲解
4.1先把条件列转为二维数组,可以得出当前有多少个条件,每个条件多少种情况。
4.2把条件二维数组的第一行(第一种排列组合)赋值给“排列组合”二维数组,此时二维数组只有一行
4.3从“排列组合”一维数组的第一位开始,第一个条件有n种情况,就循环n次赋值,每次只变一位,其他位复制,第二个条件同理,以此类推。
5. 应用实例
此实例涉及商业保密,不便上传文件,想要演示实例,请私信博主。
相关文章:
VBA实战(Excel)(5):介绍一种排列组合算法
1. 需求场景 有多个条件,条件个数不定,每个条件有若干种情况,情况个数不定,输出所有条件可能的情况的排列组合。 2.举例 假设第一次有5个情况要填,第一个条件20种情况,第二个5种,第三个40种&…...
迭代器的使用
参考: 生成器迭代器next函数 迭代器的使用 说到迭代器就必须先要提一下可迭代对象(iterable),可迭代对象是能够逐一返回其成员项的对象。可迭代对象包括序列类型(如list、str、tuple)和非序列类型&#…...
安卓手机APP开发___广播概述
安卓手机APP开发___广播概述 目录 概述 关于系统广播 系统广播所发生的更改 接收广播 清单声明的接收器 上下文注册的接收器 对进程状态的影响 发送广播 通过权限限制广播 带权限的发送 带权限的接收 安全注意事项和最佳做法 概述 Android 应用可以通过 Android …...
【封装】Unity切换场景不销毁物体
在切换场景时,如果物体不需要销毁,可以直接使用下方脚本 代码 public class DontDestroyLoader : MonoBehaviour{ //所有不销毁的物体预制体[SerializeField] private GameObject[] dontDestroyPrefabs;//实例化预制体public void Load(){foreach (var …...
基于学习的决策树
基于学习的决策树概述 决策树是一种监督学习方法,广泛应用于分类和回归任务中。基于学习的决策树模型通过学习数据中的特征来构建树状结构,帮助做出决策。以下是对基于学习的决策树的详细介绍,包括其基本概念、工作流程、构建算法、优势和挑…...

godot.bk2
1.$node_name 其实 就是 get_node 的语法糖 2.场景内部用get_node,场景外部用信号 这是自定义信号的绑定,如果是内置信号,直接右键点击链接到一个函数即可 3.场景切换和摄像头一直居中 4.class_name命名一个类,extends继承&…...
STM32 IIC 使用 HAL 库操作eeprom
在STM32上通过I2C接口(注意:在标准STM32库中,I2C接口通常被写为"I2C"而不是"IIC")与EEPROM芯片通信时,你需要遵循I2C通信协议,并使用STM32的HAL库或标准外设库(如果适用&am…...

YOLOv8+PyQt5海洋船只检测(可以重新训练,yolov8模型,从图像、视频和摄像头三种路径识别检测)
1.效果视频:海洋船只检测yoloV8检测(https://mbd.pub/o/bread/mbd-ZpaYk55r)_哔哩哔哩_bilibili资源包含可视化的海洋船只检测系统,可对于高空拍摄到的海洋图片进行轮船检测,基于最新的YOLOv8训练的海洋船只检测模型&a…...

PCL 高阶多项式曲线回归拟合(二维)
文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 高阶多项式曲线回归(Polynomial Regression)是一种线性回归模型的扩展,它允许数据拟合一个非线性的曲线。虽然多项式本身是非线性的,但我们可以通过引入新的变量(例如,原始变量的平方、立方等)来将问题转化为…...
深入理解 Python3 函数:从基础语法到高级应用
Python3 函数是构建模块化代码的基本单位,允许我们将代码组织成独立的、可重用的块。本文将详细介绍 Python3 函数的基本语法、常用命令、示例、应用场景、注意事项,并进行总结。 基本语法 在 Python 中,函数的定义使用 def 关键字…...

03_初识Spring Cloud Gateway
文章目录 一、网关简介1.1 网关提出的背景1.2 网关在微服务中的位置1.3 网关的技术选型1.4 补充 二、Spring Cloud Gateway的简介2.1 核心概念:路由(Route)2.2 核心概念:断言(Predicate)2.3 核心概念&#…...

python数据分析——线性模型
参考资料:活用pandas库 1、简单线性回归 线性回归的目标是描述响应变量(或“因变量”)和预测变量(也称“特征”、“协变量”、“自变量”)之间的直线关系。本例中将讨论tips数据集中的total_bill对tip的影响。 # 导入…...

网络原理——HTTP/HTTPS ---- HTTPS
T04BF 👋专栏: 算法|JAVA|MySQL|C语言 🫵 今天你敲代码了吗 目录 HTTPS加密与解密HTTPS的工作流程使用对称密钥来加密使用非对称密钥 来对 对称密钥进行加密第三方公证总结 HTTPS https本质上就是在http的基础之上 增加了加密层,抛开加密层之后,剩下的部…...

网络协议二
一、套接字Socket 基于 TCP UDP 协议的 Socket 编程,在讲 TCP 和 UDP 协议的时候,我们分客户端和服务端,在写程序的时候,我们也同样这样分。 在网络层,Socket 函数需要指定到底是 IPv4 还是 IPv6,分别对应设…...

内存映射mmap技术详解
一、mmap基础概念 mmap 即 memory map,也就是内存映射。mmap 是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后,…...
react 合成事件
React合成事件-CSDN博客 当然,很高兴为你解释React中的合成事件概念,非常适合React初学者理解。 想象一下,你正在组织一场派对,为了让派对顺利进行,你需要管理各种活动,比如游戏、音乐和食物分配。但是&a…...

springboot配置集成RedisTemplate和Redisson,使用分布式锁案例
文章要点 自定义配置属性类集成配置RedisTemplate集成配置分布式锁Redisson使用分布式锁简单实现超卖方案 1. 项目结构 2. 集成RedisTemplate和Redisson 添加依赖 依赖的版本与继承的spring-boot-starter-parent工程相对应,可写可不写 <!--spring data redis…...
随机数相关
产生随机数对象 固定写法: Random 随机数变量名 new Random();Random r new Random();生成随机数 int i r.Next(); //生成一个非负数的随机数 Console.WriteLine(i);i r.Next(100); // 生成一个 0~99的随机数 左边始终是0 左包含 右边是100 右不包含 Consol…...

EulerMaker Yocto Open Build Service
EulerMaker & Yocto & Open Build Service 1 介绍1.1 概述 2 工具2.1 Yocto 【嵌入式领域】介绍目标好处三大关键组件创建流程发行版本 2.2 Open Build Service 【OBS】【服务器领域】介绍应用 2.3 EulerMaker 【全场景】介绍特性需求背景(1)能支…...

SQL面试问题集
目录 Q.左连接和右连接的区别 Q.union 和 union all的区别 1、取结果的交集 2、获取结果后的操作 Q.熟悉开窗函数吗?讲一下row_number和dense_rank的区别。 Q.hive行转列怎么操作的 Q.要求手写的题主要考了聚合函数和窗口函数,row_number()&#…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...

STM32标准库-ADC数模转换器
文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT)1.4.2 信号 “调度站”:多路开关1.4.3 信号 “加工厂”:ADC 转换器(规则组 注入…...
node.js的初步学习
那什么是node.js呢? 和JavaScript又是什么关系呢? node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说, 需要在node.js的环境上进行当JavaScript作为前端开发语言来说,需要在浏览器的环境上进行 Node.js 可…...