java - 从字符串数组生成所有可能的组合而不重复
问题描述
我想将字符串数组的每个元素与除自身之外的其他元素进行比较,结果将是一个由 this 分隔的字符串-->
,结果的第二部分将是元素,第一部分将是 1 个或多个由分隔的字符串,
例如 vect[a1,a2,a3] 输出:
a2-->a1
a3-->a1
a2,a3 -->a1
a1-->a2
a3-->a2
a1,a3 -->a2
a1-->a3
a2-->a3
a1,a2-->a3
我试试这段代码
public static void main(String[] args) {
String vect[] = { "a1", "a2", "a3" };
int n = 3;
String attribut;
int i = 0, j = 0, k = 0;
for (i = 0; i < n; i++) {
attribut = vect[i];
for (j = 0; j < n; j++) {
if (!attribut.equals(vect[j])) {
System.out.println(vect[j] + "-->" + attribut);
}
}
for (j = 0; j < n; j++) {
for (k = j + 1; k < n; k++) {
if ((!attribut.equals(vect[j])) && (!attribut.equals(vect[k]))) {
System.out.println(vect[j] + "," + vect[k] + "-->" + attribut);
}
}
}
}
}
代码返回结果,但是当我有一个包含例如 5 个字符串的数组时,我不知道该怎么做,例如输出 vect[a1,a2,a3,a4]
a2-->a1
a3-->a1
a4-->a1
a2,a3 -->a1
a2,a4 -->a1
a3,a4-->a1
a2,a3,a4 -->a1
....
在这种情况下, --> 之前的逗号数增加到 4。
解决方案
使用位操作,我们可以轻松地从字符串数组中迭代所有字符串组合。
例如,如果我们有 3 个字符串 ( "a1"
, "a2"
, "a3"
),我们将从 1 迭代到 7 (2³-1)。在这些数字的二进制表示中,从右边开始的每一位都指定该输入字符串是否包含在结果中。
001 "a1"
010 "a2"
011 "a1", "a2"
100 "a3"
101 "a1", "a3"
110 "a2", "a3"
111 "a1", "a2", "a3"
现在我们修改该逻辑以提取位于右侧的字符串值-->
。我们称之为结果值。
例如,如果我们当前正在为"a2"
(结果索引 1)生成结果,我们将其“拉”出位池,因此我们现在只有 2 位。结果索引上或之后的任何位表示比位索引高一的值索引。
这意味着位 0 是值索引 0,但位 1 是值索引 2。
01 "a1"
10 "a3"
11 "a1", "a3"
我们现在可以这样写代码:
static void printCombinations(String... values) {
if (values.length < 2 || values.length > 30)
throw new IllegalArgumentException("There must be between 2 and 30 values (got " + values.length + ")");
if (values.length != new HashSet<>(Arrays.asList(values)).size())
throw new IllegalArgumentException("Duplicate values not allowed");
final int maxBit = values.length - 1;
final int maxMask = 1 << maxBit;
StringBuilder buf = new StringBuilder();
for (int resIdx = 0; resIdx < values.length; resIdx++) {
for (int bitMask = 1; bitMask < maxMask; bitMask++) {
buf.setLength(0);
for (int bitIdx = 0; bitIdx < maxBit; bitIdx++)
if ((bitMask & (1 << bitIdx)) != 0)
buf.append(',').append(values[bitIdx >= resIdx ? bitIdx + 1 : bitIdx]);
System.out.println(buf.append("-->").append(values[resIdx]).substring(1));
}
}
}
测试
printCombinations("a1", "a2", "a3", "a4");
输出
a2-->a1
a3-->a1
a2,a3-->a1
a4-->a1
a2,a4-->a1
a3,a4-->a1
a2,a3,a4-->a1
a1-->a2
a3-->a2
a1,a3-->a2
a4-->a2
a1,a4-->a2
a3,a4-->a2
a1,a3,a4-->a2
a1-->a3
a2-->a3
a1,a2-->a3
a4-->a3
a1,a4-->a3
a2,a4-->a3
a1,a2,a4-->a3
a1-->a4
a2-->a4
a1,a2-->a4
a3-->a4
a1,a3-->a4
a2,a3-->a4
a1,a2,a3-->a4
推荐阅读
- r - Change the filename of a plotly file downloaded from a shiny app which is opened in a browser
- bash - 在 zsh 上运行 bash 脚本不会获取环境变量
- javascript - 创建本地存储的“购物车”
- tfs - TFS 准备关机/重启
- java - 为什么我无法使用 maven 获取源代码文档
- git - Git推送除一个文件外的所有文件,不删除
- javascript - 尝试从 opentable 获取 JSON 并输出结果
- algorithm - 2-sum 问题,列表版本的“添加”
- javascript - 提示年龄会带来意想不到的结果
- swift - 使用 CVPixelBuffer 重复调用 Vision 时 iOS 崩溃