Algorithm 找到第n个比较

Algorithm 找到第n个比较,algorithm,performance,comparison,Algorithm,Performance,Comparison,我必须比较M项,其中单个项不应与自身进行比较。在本例中,我想设计一个算法来查找nth比较。例如,如果我正在比较两个项目,则比较列表应为: 2: (1,2) 3: (1,2), (1,3), (2,3) 同样,如果我比较3个项目,比较列表应为: 2: (1,2) 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

我必须比较
M
项,其中单个项不应与自身进行比较。在本例中,我想设计一个算法来查找
nth
比较。例如,如果我正在比较两个项目,则比较列表应为:

2: (1,2)
3: (1,2), (1,3), (2,3)
同样,如果我比较3个项目,比较列表应为:

2: (1,2)
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)
等等

我的问题是,如果输入是
M
,那么第n个
(i,j)
是什么

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);
}
第n个是(i,j),其中:

第n个是(i,j),其中:

私有静态void n(int m,int n){
int计数器=1;
对于(int i=1;iprivate static void nth(int m,int n){
int计数器=1;
对于(int i=1;i对于(int j=i+1;j如果你有序列
1,2,2,3,3,4,4,4
有多少个数字小于或等于4?有
1+2+3+4
其中
=10
1+2+…+n=n*(n+1)的公式/2
。另一种方法是,从1开始计算位置x=10的数字是多少?
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,1,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必须被视为一个估计值,并且必须在整数范围内验证上限。

如果你有序列
1,2,2,3,3,3,4,4,4
有多少个数字小于或等于第4个这里有
1+2+3+4
其中
=10
1+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,1,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必须被视为一个估计值,上限必须在整数范围内进行验证。

我将您的问题视为第I个组合,您可以从C(n,k)的组合列表中找到第I个元素,在你的情况下,k将是2。还有一个答案,另一篇文章,我将你的问题视为第I个组合,你会发现第I个元素构成C(n,k)的组合列表,在你的情况下,k将是2。还有一个答案,另一篇文章