生成 Successor 元素的算法没有使用任何特别的技巧。实质上你从最右边的元素开始向左移动直到你定位于应该增加的最左边的原子。这时你以索引 i 增加原子并重新安排所有原子到 i 的右边比左边的值大 1。举个例子,设 n = 5 和 k = 3 并且你想得到组合{ 0, 3, 4 }的后继者。索引 i 开始于地址 2(指向值为 4 的原子),并且左移直到它到地址 0(指向值为 0 的原子)。原子值被加1,并且右边(3 和 4)的所有原子从数组左边的值增加,得到结果{ 1, 2, 3 }。
一旦你有了 Successor 方法,便需要一个 ApplyTo 方法,它将某个组合元素放到一个字符串数组中。ApplyTo 方法很简单:
public string[] ApplyTo(string[] strarr) { if (strarr.Length != this.n) throw new Exception("Bad array size"); string[] result = new string[this.k]; for (long i = 0; i < result.Length; ++i) result[i] = strarr[this.data[i]]; return result; }
通过对字符串数组输入参数的检查,确保字符串个数的正确性之后,用子集 k 的大小创建一个结果数组。然后遍历输入字符串 ,并将一个引用存储到结果数组相应的单元中。与组合所实现的许多操作一样,如果你不从头到尾跟踪一两个例子,所发生的事情并不是那么显而易见。
根据适当的条目数和子集大小实例化一个 Combination 对象之后,创建一个字符串数组来保存结果组合元素。用一个 While 循环来遍历所有组合元素——回想一下我们曾说过,当 不存下一个元素时,Successor 方法返回 null——并且 ApplyTo 方法将当前元素映射到原始字符串数组上。
结束语
在计划和进行配置测试的过程中,组合是一个不可或缺的工具,尤其是在被称为交互式分析的子领域里。举个例子,假设你需要在一台安装了多个浏览器和多媒体播放器 的机器上测试产品。你想要从八个浏览器集合中选装三个浏览器,从六个多媒体播放器集合中选装两个播放器来进行系统结合测试。这里有多少配置的组合呢?你怎样才能 编写程序列出这些配置?本文呈现的技术使得你很容易就计算出有 Choose(8,3) * Choose(6,2) = 840 个可能的测试配置。它也让你很容易编程列出所有这些配置。
在检查和测试执行路径时,组合是很有用的。我将用一个经典的问题来举例说明,它是一个分析执行路径的代理(微软常用这种例子问题来对测试工程师候选 人进行面试)。假设你在开发一个游戏。玩家进入一个铺了地板砖的房间的西南角。玩家必须通过移动一块地砖到东边或移动一块地砖到北边以便自己移动到房间的东北角(换句话说玩家总是向出口方向移动并且不能 走回头路)。如果这个房间很小-只有 10 块地砖长 6 块地砖那么宽——玩家会有多少种不同的路径走法?你能测试所有这些路径吗?如果移动到东边用字母 E 代表而移动到北边用字母 N 代表,一个到出口的可能路径就是玩家先向东移动所有步然后一直向北:
E E E E E E E E E E N N N N N N
一个不同的路径是:
E N E N E N E N E N E N E E E E
注意这里玩家无论怎么移动,总是恰好只有16步。还要注意你可以认为移动一步为“E”或“not E”。如果你想象16格的一个序列,你必须用“E”填满16格中的10格 (因为剩下的格子一定为“N”)。因此,这个问题的答案是这里有 Choose(16,10) = 8,008 个可能路径,并且你可以用本文示例代码轻松地生成它们。
正如我早先说过的,测试是软件开发的一个极其重要的方面。下次还是在这里,我将给你提供更多的技巧应用到你的测试过程中。
文章来源于领测软件测试网 https://www.ltesting.net/