找到第n个比较

时间:2016-10-04 22:12:10

标签: algorithm performance comparison

我必须比较不应将单个项目与其自身进行比较的M个项目。在这种情况下,我想设计一个算法来查找nth比较。例如,如果我正在比较2个项目,则比较列表应为:

2: (1,2)

同样,如果我比较3个项目,那么比较列表应为:

3: (1,2), (1,3), (2,3)

遵循这种模式:

4: (1,2), (1,3), (1,4), (2,3), (2,4), (3,4)
5: (1,2), (1,3), (1,4), (1,5), (2,3), (2,4), (2,5), (3,4), (3,5), (4,5)

等等。

我的问题是,如果输入为nth(i,j)M是什么?

M: (1,2), ..., (i,j), ..., (M-1,M)

虽然我可以轻松编写一个简单的程序来计算这个特设,但我想知道是否有一个封闭的表单解决方案,以便它不会与M一起扩展。

编辑:为了使这个更清晰(并且有一个可以用于测试的示例),我希望代码位于C中,并带有以下模板:

void findIJ(int M, int n) {
    int i = 0;
    int j = 0;

    /* Do work to find i and j*/

    printf("(i,j) = (%i,%i)\n", i, j);
}

3 个答案:

答案 0 :(得分:0)

第n个是(i,j):

i = max(k; Sum(M-i, i = 1, k) <= n)
i = max(k; M*k - k*(k+1)/2 <= n)
i = 1 + floor(1/2*(-1+2*M-sqrt(1-4*M+4*M*M-8*(n-1))))

所以:

j = n - M * (i-1) + i*(i+1)/2

答案 1 :(得分:0)

private static void nth(int m, int n) {
    int counter = 1;

    for (int i = 1; i < m; i++) {
        for (int j = i + 1; j <= m; j++) {
            if (counter == n) {
                System.out.println(i + " " + j);
                return;
            }
            counter++;
        }
    }
}

答案 2 :(得分:0)

如果序列1, 2, 2, 3, 3, 3, 4, 4, 4, 4有多少个小于或等于4的数字?其中1+2+3+4 = 101+2+...+n = n*(n+1)/2的公式。现在另一方面,位置x=10上的数字是多少,从1开始计算位置? x = n*(n+1)/2,这是二次方程和n = (sqrt(1+8*x)-1)/2。对于x = 10,它是4.位置7上的数字是多少?该公式给出了类似3.275的结果...事实证明,我们所需要的只是将它四舍五入,然后我们再次得到4。

与原始问题的连接很接近。如果我们从5中减去序列,我们得到4, 3, 3, 2, 2, 2, 1, 1, 1, 1,如果我们反过来,我们得到1, 1, 1, 1, 2, 2, 2, 3, 3, 4。这是我们的第一对数。第二个数字可以从公式给出整数的位置到距离来计算,实际上比解释更容易实现。代码是C#,应该很容易适应C。

int sqrSum(int n)
{
    return n * (n + 1) / 2;
}

void GetNth(int M, int n)
{
    int total = sqrSum(M - 1);
    int nReversed = total + 1 - n;

    int closestBigger = (int)Math.Ceiling((Math.Sqrt(1 + 8 * nReversed) - 1) / 2);
    int difference = sqrSum(closestBigger) - nReversed;

    int i = M - closestBigger;
    int j = i + 1 + difference;

    textBox2.AppendText("(" + i + ", " + j + "), " + Environment.NewLine);
}

代码依赖于事实,即sqrt是准确的。根据IEEE应该是,但事实并非如此,必须将sqrt作为估计值,并且必须在整数范围内验证上限。