1

我有一个问题,我正在努力解决。给定任意数量的数组和一个称为“特异性”的整数,我需要在数组的叉积中生成表示该点的行。数组的长度始终至少为 2,并且每个数组的最后一个值始终为空。除了每个数组中的最后一个元素外,没有其他元素为空。例如,给定数组 {1, 2, null} 和 {A, B, null},叉积实际上是:

0:1 A
1:1 B
2:1 无
3:2 A
4:2 B
5:2 无
6:无 A
7:无 B
8:无 无

因此,给定“特异性”4,例如上面列出的两个数组,它应该返回数组 {2,B}。那是容易的部分。我已经在下面的代码部分完成了这个特殊案例。但是,请考虑没有空值的组合优先的情况。现在的顺序是:

0:1 A
1:1 B
2:2 A
3:2 B
4:1 无
5:2 无
6:无 A
7:无 B
8:无 无

这是我到目前为止实现的算法。上面的第一种情况处理得很好,但我不知道如何处理第二种情况。关于“其他”条款的内容有什么想法吗?

    public static String generateKeyForSource(int specificity, KeySource keySource) {
    if (specificity > keySource.getNumPossibleKeys()) {
        throw new IllegalArgumentException("The specificity " + specificity + " is larger than the max number of possible keys for this KeySource, which is " + keySource.getNumPossibleKeys());
    }
    Object[][] hierarchies = keySource.getHierarchies();
    boolean combinedPrecedence = keySource.isCombinedPrecedence();

    int[] indexes = new int[hierarchies.length];
    int multiplier = 1;

    if (!(combinedPrecedence && specificity >= keySource.getFirstSpecificityContainingNull())) {
        for (int i = hierarchies.length - 1; i >= 0; i--) {
            Object[] hierarchy = hierarchies[i];
            int range;
            if (combinedPrecedence)
                range = hierarchy.length - 1;
            else
                range = hierarchy.length;

            int currentArrayIndex = specificity / multiplier % range;
            indexes[i] = currentArrayIndex;
            multiplier *= hierarchies[i].length;
        }
    }
    else {
        //?????????
    }

    return generateKey(indexes, hierarchies);
}
4

1 回答 1

1

在寻找此类问题的解决方案时,归纳是您的朋友。

对于简单的情况,它看起来像

easy( a, i ) ≡ easyHelper( a, a.length, i )  
easyHelper( a, n, i ) ≡ easyInduction( easyHelper, 0 )( a, n, i )

easyInduction( f, b )( a, 0, 0 ) ≡ []  
easyInduction( f, b )( a, 0, i + 1 ) ≡ undefined
easyInduction( f, b )( a, n + 1, i ) ≡
   let t = a[n + 1].length - b
    in f( a, n, ⌊i / t⌋ ) ++ [ a[n + 1][i mod t] ]

对于困难的情况,我认为你需要一个更强的归纳假设。也就是说,您的辅助递归方法需要将偏移量和函数映射特性返回到元组。该函数在应用于低于偏移量的索引时,返回所有数组的叉积的成员,其中删除了空值;在偏移量之上,空案例开始。对于n 个数组的情况了解这一点,您可以通过以下三种情况为n + 1 个数组构造新的偏移量和新函数:

  1. 你小于新的偏移量,所以你把它当作最后一个数组的非空成员的简单情况
  2. 你在新偏移量和新旧偏移量之和之间,所以你应该返回递归结果,最后为空
  3. 您大于总和,因此您再次将其视为简单的情况,除非您确保其中的递归调用使用超出旧偏移量的索引

这是我未经测试的伪代码。

hard( a, i ) ≡ hardHelper( a, a.length ).second( i )
hardHelper( a, 0 ) ≡ ( 1, { case 0 => [] } )
hardHelper( a, n + 1 ) ≡
  let t = a[n + 1].length
  and ( k, f ) = hardHelper( a, n )
  and k' = k * ( t - 1 )
  and f'( i ) =
        if ( i < k' )
        then easyInduction( f, 1 )( a, n + 1, i )
        else if ( k' <= i < k' + k )
        then easyInduction( f, 1 )( a[ 0..n ] ++ [ [ null ] ], n + 1, i - k' )
        else easyInduction( ( b, m, j ) => f( b, m, j + k ), 0 )( a, n + 1, i - k' - k )
   in ( k', f' )
于 2013-10-15T03:42:56.560 回答