我有两个字符串数组,不一定长度相同,我想找到数组中两个值之间所有可能的“组合”组合,而不是从任何一个数组重复。
例如,给定阵列:
{“A1”,“A2”,“A3”}
{“B1”,“B2”}
我想要的结果是以下几组:
{(“A1”,“B1”),(“A2”,“B2”)}
{(“A1”,“B1”),(“A3”,“B2”)}
{(“A1”,“B2”),(“A2”,“B1”)}
{(“A1”,“B2”),(“A3”,“B1”)}
{(“A2”,“B1”),(“A3”,“B2”)}
{(“A2”,“B2”),(“A3”,“B1”)}
我的总体方向是创建递归函数,该函数将两个数组作为参数并一次删除每个“选定”的字符串,调用自身直到任一数组为空,但是我有点担心性能问题(我需要在大约1000对字符串数组上运行此代码。) 任何人都可以指导我采用有效的方法来做到这一点吗?
答案 0 :(得分:9)
将两个数组视为表的一边可能是有益的:
A1 A2 A3
---+-------+-------+-------+
B1 | B1,A1 | B1,A2 | B1,A3 |
---+-------+-------+-------+
B2 | B2,A1 | B2,A2 | B2,A3 |
---+-------+-------+-------+
这意味着一个循环嵌套在另一个循环中,一个循环用于行,另一个循环用于列。这将为您提供初始的一组对:
{B1,A1} {B1,A2} {B1,A3} {B2,A1} {B2,A2} {B2,A3}
然后是建立初始集的组合的问题。您可以使用行和列的成对集来类似地可视化组合:
B1,A1 B1,A2 B1,A3 B2,A1 B2,A2 B2,A3
-----+-----+-----+-----+-----+-----+-----+
B1,A1| | X | X | X | X | X |
-----+-----+-----+-----+-----+-----+-----+
B1,A2| | | X | X | X | X |
-----+-----+-----+-----+-----+-----+-----+
B1,A3| | | | X | X | X |
-----+-----+-----+-----+-----+-----+-----+
B2,A1| | | | | X | X |
-----+-----+-----+-----+-----+-----+-----+
B2,A2| | | | | | X |
-----+-----+-----+-----+-----+-----+-----+
B2,A3| | | | | | |
-----+-----+-----+-----+-----+-----+-----+
同样可以通过一对嵌套循环来完成(提示:你的内循环的范围将由外循环的值决定)。
答案 1 :(得分:2)
非常简单的方法是
string[] arr = new string[3];
string[] arr1 = new string[4];
string[] jointarr = new string[100];
for (int i = 0; i < arr.Length; i++)
{
arr[i] = "A" + (i + 1);
}
for (int i = 0; i < arr1.Length; i++)
{
arr1[i] = "B" + (i + 1);
}
int k=0;
for (int i = 0; i < arr.Length; i++)
{
for (int j = 0; j < arr1.Length; j++)
{
jointarr[k] = arr[i] + " " + arr1[j];
k++;
}
}
答案 2 :(得分:2)
您的问题等同于以下问题:
问题陈述:
给定两个大小为A
的{{1}},大小为n
的{{1}},其中B
。
m
。
n <= m
。
从A = [0, 1, 2, ..., n - 1]
到B = [0, 1, 2, ..., m - 1]
查找所有可能的injective and non-surjective mappings。
<强>解决方案强>:
由于A的大小较小,在一次映射中,对应的数量等于A的大小,即n。
然后我们生成B的所有可能的排列,以便每个排列中的起始n个元素可以与A中的元素一一对应。
前几个排列和映射如下:
<强>实施强>
A
答案 3 :(得分:0)
它的问题不完全相同,但是我对以下问题做了一个解决方案,可能是一个不错的起点:
答案 4 :(得分:0)
关于本网站上两个列表的组合,有很多问题(和答案)(见边栏)。如果我理解正确,你的用例似乎只是表面上不同。
拥有方法
是不够的IEnumerable<Tuple<string, string>> Combinations(
IEnumerable<string> list1,
IEnumerable<string> list2) {}
(已经在'重复'中以各种形式和大小存在)然后按照这些步骤使用它(作业=你填写详细信息):
迭代列表1和列表的所有组合;清单2(使用类似上面的内容)和
答案 5 :(得分:0)
如果我正确理解您的问题,可以使用以下方法派生所有组合:
{A_i, A_j}
{B_k, B_l}
,{ (A_i, B_k), (A_j, B_l) }, { (A_i, B_l), (A_j, B_k) }
进行2次组合。通过A和B中2个元素子集的所有组合,您可以获得所需的所有组合。
有|A| * (|A| - 1) * |B| * (|B| - 1) / 2
种组合。
易于实现4循环:
for i = 1 ... |A|
for j = i+1 ... |A|
for k = 1 ... |B|
for l = k+1 ... |B|
make 2 combinations {(A_i, B_k),(A_j, B_l)}, {(A_i, B_l), (A_j, B_k)}
答案 6 :(得分:0)
当我看到一个填字游戏风格的拼图时,我看到了这个挑战,其中每个方格都有一个数字,你必须找到哪个字母对应于哪个数字才能使单词正确。知道我已经触及已经给出的答案,我将尝试总结问题,并说明如何以递归方式解决问题。
在x字的情况下,较小的数组A是一系列数字,而大数组B包含字母表的字母。问题是将每个数字分配给一个字母,并找到所有可能的组合。一般来说,我们有:
A={1,2,...m} and B={1,2,....n} n>=m
对于对A(i)B(j),每个可能的结果可以写为具有m个元素的数组C,其中元素i携带值j。排列的总数,即C阵列,是n(n-1)......(n-m + 1)或更整齐地写:n!/(m + 1)!
这个数字来自于认为当A的第一个元素与B中的任何元素配对时,A的第二个元素可以与任何元素配对,除了所采用的元素。第一个,依此类推。
我们可以通过以下伪 - code:
来实现这一目标for i= 1 to n
C(1)=B(i)
for j= 1 to n-1
C(2)=B'(j) ' B' is B with element i removed
.........
for x = 1 to n-m
C(m)=B'''(x) 'B is now reduced with (m-1) elements
next x
我使用基于1的数组来实现直观性。
这段代码对于任意长度的A都不起作用,并且为大m编写会很麻烦,所以我们最好用一个可以调用自身的过程AllPairs进行递归:
AllPairs (A,B,C)
if Size(A)>1 ' check no of elements in A
for i=1 to Size(B)
C(Size(C)-Size(A)+1)= B(i)
A'=Remove element 1 from A
B'=Remove element i from B
Call AllPairs(A',B',C) 'recursive call
Next i
else ' only one element in A
for j=1 to Size(B)
C(Size(C)) = B(i) 'looping last element in C through all unused in B
Collect.ADD(C) 'collect C-arrays here for later use
Next j
End AllPairs
请注意,C最初是一个与A大小相同的空数组(也可以是A的副本)。 C保持相同的大小,而A和B连续减少,直到A只包含一个元素,递归调用结束。这样做会。也许(在所有方面),这类似于代码Jingie Zheng的答案 - (我不能告诉)。我的目的是尝试提供一个简单直观的伪代码版本。可以在VB here.
中实现此解决方案