Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 求乘法表中不同数字的个数_Algorithm - Fatal编程技术网

Algorithm 求乘法表中不同数字的个数

Algorithm 求乘法表中不同数字的个数,algorithm,Algorithm,灵感来自 假设我有一个nxn乘法表,表上不同值的数目是多少 例如,一个3X3乘法表 1 2 3 2.4.6 369 具有6唯一值,即[1,2,3,4,6,9] 到目前为止,我只有一个O(n2)溶液 public static void findDistinctNumbers(int n) { Set<Integer> unique = new HashSet<>(); for(int i=1; i<=n; i++) { for(

灵感来自

假设我有一个nxn乘法表,表上不同值的数目是多少

例如,一个3X3乘法表

1 2 3
2.4.6
369

具有6唯一值,即[1,2,3,4,6,9]

到目前为止,我只有一个O(n2)溶液

 public static void findDistinctNumbers(int n) {

    Set<Integer> unique = new HashSet<>();

    for(int i=1; i<=n; i++) {
        for(int j=1; j<=n; j++) {
            unique.add(i*j);
        }
    }
    System.out.println("number of unique values: " + unique.size());
  }
公共静态void findDintintNumber(int n){
Set unique=新的HashSet();

对于(inti=1;i来说,问题是要使用一个集合来验证唯一性,必须首先填充它,不管怎样,它都是O(n^2); 没有集合,您无法轻松验证数字是否唯一

作为旁注:因为big-O类有点宽泛(即,它可以描述任何不高于某事物的复杂度,但不一定) 不更低,即线性复杂度和二次复杂度算法都可以描述为O(n^2),因为在这两种情况下,复杂度 不高于n^2)-因此,假设此答案中的每个O(x)表示“大θ”,即渐近上/下边界,这样 f(n)在O(g(n))中表示k1*g(n)O(C)>O(n^2/(logn)^C*(loglogn)^3/2)(请注意,这只表示比纯n^2有微小的改进)

也就是说,我对A的建议如下:

a) 由于矩阵相对于对角线是对称的,假设我们只分析右上三角形加对角线

b) 假设对于n,集合中有任何数字x= c) 计算y=int(sqrt(n))-行ry的每个对角线值 必须进行检查

c')n*(n+1)/2-n-int(sqrt(n))元素需要在“常规”方法中处理(添加到集合中)

d) 现在,由于我们排除了所有容易预测的值,我们进入了主循环: 对于(行r(r-1)*n到目前为止都保证是唯一的,因此假设我们不必维护唯一的数字集,则无需对它们进行处理!; 由于行的集合用于数字(r^2;r*n),因此行r中范围((r-1)n,rn)内的所有数字都在范围内 现在,由于第r行中的实际数字集是a_n=r,2*r,3*r…nr,显而易见的问题是 一个“边界”整数yr,使得y*r>(r-1)*n,因为这意味着我们有n-y保证唯一性。 注意:如果我们发现((r-1)*n)/r的精确值是一个整数,我们可以安全地假设y=((r-1)*n)/r+1(为什么?), 这个整数不是唯一的。 正因为如此,每一行中都有max(n-r,ceil(n/r))保证的唯一性(为什么?);我们在O(1)中得到每一行的唯一性

e) 最棘手的部分:我们得到了一些大于r*r的数,但明显小于(r-1)n; 即“硬范围”[rr,(r-1)*n),其中数字可以是唯一的,也可以不是唯一的; 我们最多可以有i_r=max(0,n-r-floor(n/r))个数字来检查这个范围(为什么?) 即使是简单地检查这个范围内的每个数字也明显比O(n)快(为什么?-地板(n/r)因子相对于n增长!)

我们已经得到了比O(n^2)更好的结果——我们有sum(i_r)迭代,对于r=2..n(第一行不是op),所以这实际上等于 r=2..n的和(max(0,n-r-floor(n/r))-这里我不提供精确的复杂性类结果,因为它不是一个很好的数字, 让我们试着更进一步

f) 弹射器怎么样

g) 对于奇数行,我们不能做更多的事情(因为在许多事情中,这需要我们解决一些与素数相关的问题) 这些问题,已经在评论中提到了,对于世界上最好的Matematicators来说还没有得到解决),但我们仍然可以 请自便吧

把r除以2。每一个的数字我都相信有一个比O(n²)更好的解决方案。我没有找到它,但我相信我走的是正确的道路,只有几点数学见解

这是我正在开发的算法:

public static int numberOfDistinctResults(int n) {
    if (n == 1) {
        return 1;
    }

    // runs a prime-number sieve in O(n log log n)
    Factorization.initialize(n); 
    int total = 1;
    for (int i = 2; i <= n; i++) {
        total += i;
        // divs[i] == 0 iff i is prime, or the lowest prime that divides i
        if (Factorization.divs[i] == 0) {
            // i is prime; for all j<=i, j*i is brand new; nothing to substract
        } else {
            // i is non-prime; discard already-seen decompositions
            total -= magic(n); // <--- this part needs work
        }
    }
    return total;
}

好吧,如果你计算出
i*j
,你当然不需要计算出
j*i
——它仍然是
O(n^2)
但这是工作的一半。我认为这是不用钻研数论就可以做到的最好的方法;在Java或任何其他语言中,我看不到更好的方法。基于此,我认为这应该结束。这不是一个关于编程的问题,而是一个数学问题,它肯定很有趣。如果有π(x)的公式,素数计数函数,它可以在O(1)中求解;-)@user1990169即使在3x3示例中,我们也有8,它介于n和n^2之间,但既不是素数,也不是解的一部分。@tucuxi:在OP的示例中,
n
是3。所以他的方法是O(n^2)。正如您所指出的,筛选是O(n log log n),其中
n
是运行它所针对的项目数。在这种情况下,您必须对9个项目运行它。因此筛选是O(n^2 log(n^2))),其中n==3。如果你需要迭代n²,那么显然没有办法低于n²。我一直在试图找到一个递增的答案,但oeis.org/A108407很难破解。天哪。如果有人真的解决了这个问题,他/她最好写一篇论文,而不是一个SO答案。这个问题与计算素数不同,它与counti完全相同n^2减去n和n^2之间的素数,因为n和n^2之间的每一个数都必须被2和n之间的一个数整除,或者它必须是素数。@MarkRansom没有标记,这是错误的。我实际上做了一次失败的尝试,基于“减去n和n^2之间的素数可整除的事物”。有一个简单的计数r示例:在
n=3
的情况下,
8
不在乘法表中,也不能被
3
9
之间的任何素数整除。另一个说服您的示例是:以
n=9
为例,那么
75
也不能被
9
之间的任何素数整除
f(1) = 1 ( prev + 1 = 1 - 0)
f(2) = 3 ( prev + 2 = 2 - 0)
f(3) = 6 ( prev + 3 = 3 - 0)
f(4) = 9 ( prev + 3 = 4 - 1)
    4 = 2^2; available = 2·3
f(5) = 14 ( prev + 5 = 5 - 0)
f(6) = 18 ( prev + 4 = 6 - 2)
    6 = 2·3; available = 2^2·3·5
f(7) = 25 ( prev + 7 = 7 - 0)
f(8) = 30 ( prev + 5 = 8 - 3)
    8 = 2^3; available = 2^2·3·5·7
f(9) = 36 ( prev + 6 = 9 - 3)
    9 = 3^2; available = 2^3·3·5·7
f(10) = 42 ( prev + 6 = 10 - 4)
    10 = 2·5; available = 2^3·3^2·5·7
f(11) = 53 ( prev + 11 = 11 - 0)
f(12) = 59 ( prev + 6 = 12 - 6)
    12 = 2^2·3; available = 2^3·3^2·5·7·11
f(13) = 72 ( prev + 13 = 13 - 0)
f(14) = 80 ( prev + 8 = 14 - 6)
    14 = 2·7; available = 2^3·3^2·5·7·11·13
f(15) = 89 ( prev + 9 = 15 - 6)
    15 = 3·5; available = 2^3·3^2·5·7·11·13
f(16) = 97 ( prev + 8 = 16 - 8)
    16 = 2^4; available = 2^3·3^2·5·7·11·13
f(17) = 114 ( prev + 17 = 17 - 0)
f(18) = 123 ( prev + 9 = 18 - 9)
    18 = 2·3^2; available = 2^4·3^2·5·7·11·13·17
f(19) = 142 ( prev + 19 = 19 - 0)
f(20) = 152 ( prev + 10 = 20 - 10)
    20 = 2^2·5; available = 2^4·3^2·5·7·11·13·17·19
f(21) = 164 ( prev + 12 = 21 - 9)
    21 = 3·7; available = 2^4·3^2·5·7·11·13·17·19
f(22) = 176 ( prev + 12 = 22 - 10)
    22 = 2·11; available = 2^4·3^2·5·7·11·13·17·19
f(23) = 199 ( prev + 23 = 23 - 0)
f(24) = 209 ( prev + 10 = 24 - 14)
    24 = 2^3·3; available = 2^4·3^2·5·7·11·13·17·19·23
f(25) = 225 ( prev + 16 = 25 - 9)
    25 = 5^2; available = 2^4·3^2·5·7·11·13·17·19·23
f(26) = 239 ( prev + 14 = 26 - 12)
    26 = 2·13; available = 2^4·3^2·5^2·7·11·13·17·19·23
f(27) = 254 ( prev + 15 = 27 - 12)
    27 = 3^3; available = 2^4·3^2·5^2·7·11·13·17·19·23
f(28) = 267 ( prev + 13 = 28 - 15)
    28 = 2^2·7; available = 2^4·3^3·5^2·7·11·13·17·19·23
f(29) = 296 ( prev + 29 = 29 - 0)
f(30) = 308 ( prev + 12 = 30 - 18)
    30 = 2·3·5; available = 2^4·3^3·5^2·7·11·13·17·19·23·29
f(31) = 339 ( prev + 31 = 31 - 0)
f(32) = 354 ( prev + 15 = 32 - 17)
    32 = 2^5; available = 2^4·3^3·5^2·7·11·13·17·19·23·29·31
f(33) = 372 ( prev + 18 = 33 - 15)
    33 = 3·11; available = 2^5·3^3·5^2·7·11·13·17·19·23·29·31
f(34) = 390 ( prev + 18 = 34 - 16)
    34 = 2·17; available = 2^5·3^3·5^2·7·11·13·17·19·23·29·31
f(35) = 410 ( prev + 20 = 35 - 15)
    35 = 5·7; available = 2^5·3^3·5^2·7·11·13·17·19·23·29·31
f(36) = 423 ( prev + 13 = 36 - 23)
    36 = 2^2·3^2; available = 2^5·3^3·5^2·7·11·13·17·19·23·29·31
f(37) = 460 ( prev + 37 = 37 - 0)
f(38) = 480 ( prev + 20 = 38 - 18)
    38 = 2·19; available = 2^5·3^3·5^2·7·11·13·17·19·23·29·31·37
f(39) = 501 ( prev + 21 = 39 - 18)
    39 = 3·13; available = 2^5·3^3·5^2·7·11·13·17·19·23·29·31·37