假设我们有多个整数数组。您可以将每个数组视为一个级别。我们尝试找到一个元素序列,恰好是每个数组中的一个元素,然后继续使用相同谓词的下一个数组。例如,我们有v1, v2, v3
作为数组:
v1 | v2 | v3
-----------------
1 | 4 | 16
2 | 5 | 81
3 | 16 | 100
4 | 64 | 121
我可以说谓词是:next_element == previous_element^2
上例中的有效序列为:2 -> 4 -> 16
实际上,在这个例子中没有另一个有效的序列。
我可以编写三个循环来强制提到上面提到的例子,但是如果数组的数量是可变的,但是当然知道顺序,你会如何解决这个问题呢?
非常感谢提示或对设计模式的引用。我将在C ++中完成它,但我只需要这个想法。
谢谢,
答案 0 :(得分:3)
如果您事先订购了数组,搜索可以更快地完成。您可以从较小的阵列开始,然后二进制搜索每个阵列上的预期数字。这将是O(n k logM),n是最小数组的大小,k是数组的数量,M是更大数组的大小
如果您使用Hashmaps而不是数组,则可以更快地完成此操作。这将允许您在O(n * k)中搜索。
如果使用反向函数(在早期数组中搜索)不是一个选项,那么你应该从第一个数组开始,n =第一个数组的大小。
为简单起见,我将从第一个数组开始
//note the 1-based arrays
for (i : 1 until allArrays[1].size()) {
baseNumber = allArrays[1][i];
for (j: 2 until allArrays.size()) {
expectedNumber = function(baseNumber);
if (!find(expectedNumber, allArrays[j]))
break;
baseNumber = expectedNumber;
}
}
你可以做一些空检查并在那里添加一些布尔值来知道序列是否存在
答案 1 :(得分:3)
(设计模式适用于类和API设计以提高代码质量,但它们不是用于解决计算问题。)
视情况而定:
SHA1(next_elem) xor SHA1(prev_elem) == 0x1234
),那么蛮力也是唯一的解决方案。(由于递归,所有空间计数都没有考虑堆栈使用情况。)
消耗O(Nb k )空间的一般方法是通过连续过滤来构建解决方案,例如
solutions = [[1], [2], ... [N]]
filterSolution (Predicate, curSols, nextElems) {
nextSols = []
for each curSol in curSols:
find elem in nextElems that satisfy the Predicate
append elem into a copy of curSol, then push into nextSols
return nextSols
}
for each levels:
solutions = filterSolution(Predicate, solutions, all elems in this level)
return solutions
答案 2 :(得分:0)
您可以生成一个单独的索引,将索引从一个数组映射到另一个数组的索引。从索引中,您可以快速查看是否存在解决方案。
生成索引需要蛮力方法,但之后你只需要一个。如果要改进数组搜索,请考虑使用更合适的数据结构以允许快速搜索(例如红黑树而不是数组)。
答案 3 :(得分:0)
我会将所有向量保持为heaps,以便在搜索元素时可以O(log n)
复杂化。因此,对于总共k
个向量,您将获得类似O(k * log n)
答案 4 :(得分:0)
如果谓词保留了数组中的排序(例如,使用您的示例,如果值都保证非负数),您可以调整合并算法。考虑每个数组的关键是结束值(根据所有数组的需要多次应用谓词)。
如果谓词不保留排序(或者数组没有被命令启动),您可以先按结束值排序,但需要这样做表明另一种方法可能更好(例如哈希其他地方建议的表格。
基本上,检查所有数组的下一个结束值是否相等。如果没有,则跳过最低位置(仅在一个阵列中)并重复。如果你把所有三个都相等,那就是一个(可能的)解决方案 - 在搜索下一个之前跳过所有三个。
“可能”的解决方案,因为您可能需要进行检查 - 如果谓词函数可以将多个输入值映射到相同的输出值,您可能会遇到某些数组中找到的值的情况(但不是第一个或者说)错了。
编辑 - 当谓词没有将每个输入映射到唯一输出时,可能会出现更大的问题 - 此刻无法思考。基本上,合并方法可以很好地工作,但仅适用于某些类型的谓词函数。