i系列RPGLE多数组公共值高效查找实现方法咨询
IBM i RPGLE 单元素数组公共值检索实现方案
因为所有待比对元素都是单字符,单数组上限100元素、最多10个参与比对的数组,完全可以用线性计数法实现O(n)复杂度的逻辑,彻底避开多层嵌套的问题。
核心实现逻辑
不需要写10层嵌套的DO循环,只需要依托RPGLE原生的定长数组能力,分步骤落地:
- 预先定义两个静态全局结构,无动态内存开销:
- 长度256的计数数组
CharCnt,每个元素初始值为0,下标直接对应单字符的ASCII/Unicode码点 - 长度100的结果存储数组
CommonRes,每个元素长度1,用来存最终匹配到的公共值 - 明确记录本次参与比对的数组总个数
ArrTotal(比如示例里是4个)
- 长度256的计数数组
- 单层遍历所有待比对数组,全程无深层嵌套判断:
对每一个待处理的数组做单遍扫描,只统计当前数组内非空格的有效字符,同一个数组内重复出现的同一字符只做1次计数累加,避免重复值导致计数不准。
单数组处理的RPGLE代码片段参考:dcl-s CharPos uns(8); // 存储单字符的码点下标 dcl-s CurMark int(5) dim(256) inz(0); // 标记当前数组内已统计的字符,防重复计数 dcl-s i int(5); // 处理单个输入数组 for i = 1 to 100; if InArray(i) = ' '; leave; // 碰到填充空格直接跳出,后面都是无效值 endif; // 获取单字符的码点作为计数数组的下标 CharPos = %uchar(InArray(i)); // 仅当当前字符未在本数组内被统计过时,累加全局计数 if CurMark(CharPos) = 0; CharCnt(CharPos) += 1; CurMark(CharPos) = 1; endif; endfor; reset CurMark; // 清空本数组的标记,供下一个数组使用 - 所有数组处理完成后,单遍扫描计数数组,只要某一下标位置的计数值等于
ArrTotal,该下标对应的字符就是所有数组共有的元素,直接存入结果数组即可。
性能对比优势
- 总循环次数固定上限:10个待比对数组 * 100个元素 + 256次计数数组遍历 = 1256次循环,哪怕所有数组都占满100个有效元素,也不会出现多层嵌套的代码膨胀
- 无低效字符串查找操作,所有计数访问都是直接通过数组下标定位,IBM i上的原生数组操作比字符串扫描快一个数量级
- 代码结构完全扁平化,后续维护只需要在单数组处理段加逻辑,不需要修改多层嵌套的判断分支
示例验证匹配结果
针对给出的4组示例数组,处理完成后计数值等于4的码点对应字符刚好是a/b/d/e,和预期结果完全一致,全程只需要加一个判断:碰到字符为空格时跳过计数,就能避开填充空值的干扰。
注意:如果后续扩展到单元素长度大于1的场景,只需要把计数结构换成按值排序的RPGLE定长表,配合
%lookup做快速匹配,依然可以保持线性遍历的逻辑,不会退化成多层嵌套结构。
内容的提问来源于stack exchange,提问作者user1420914
相关产品推荐
相关产品推荐

