当前位置: 首页 > 知识库问答 >
问题:

以3个函数的中位数进行比较的次数?

龙玄天
2023-03-14

到目前为止,我的函数找到3个数字的中位数并对它们进行排序,但它总是进行三次比较。我想我可以在某个地方使用嵌套的if语句,这样有时我的函数只会进行两次比较。

int median_of_3(int list[], int p, int r)
{
    int median = (p + r) / 2;

    if(list[p] > list[r])
        exchange(list, p, r);
    if(list[p] > list[median])
        exchange(list, p, median);
    if(list[r] > list[median])
        exchange(list, r, median);

    comparisons+=3;                // 3 comparisons for each call to median_of_3

    return list[r];
}

我不确定我在哪里可以使嵌套的if语句。

共有3个答案

杨豪
2023-03-14
int m = (p + r) / 2;
if (list[p] < list[m])
    if (list[p] >= list[r])
        return list[p];
    else if (list[m] < list[r])
        return list[m];
else
    if (list[p] < list[r])
        return list[p];
return list[r];
茹元魁
2023-03-14

如果我们允许额外的操作,我们最多可以使用2个比较来找到中位数。诀窍是使用排他性或找到三个数字之间的关系。

void median3(int A[], int p, int r)
{
    int m = (p+r)/2;
    /* let a, b, c be the numbers to be compared */
    int a = A[p], b = A[m], c = A[r];
    int e = a-b;
    int f = a-c;

    if ((e^f) < 0) {
        med_comparisons += 1;
        /* a is the median with 1 comparison */
        A[m] = a;
        /* b < a < c ? */
        if (b < c) /* b < a < c */ { A[p] = b, A[r] = c; }
        else       /* c < a < b */ { A[p] = c, A[r] = b; }
        comparisons += 2;
    } else {
        med_comparisons += 2;
        int g = b-c;
        if ((e^g) < 0) {
            /* c is the median with 2 comparisons */ 
            A[m] = c;
            /* a < c < b ? */
            if (a < b) /* a < c < b */ { A[p] = a, A[r] = b; }
            else       /* b < c < a */ { A[p] = b, A[r] = a; }
        } else {
            /* b is the median with 2 comparisons */
            A[m] = b;
            /* c < b < a ? */
            if (a > c) /* c < b < a */ { A[p] = c; A[r] = a; }
            else       /* a < b < c */ { /* do nothing */    }
        }
        comparisons += 3;
    }
}

第一个异或(e^f)是找出(a-b)和(a-c)之间符号位的差异
如果它们有不同的符号位,则a是中值。否则,a是最小值或最大值。在这种情况下,我们需要第二个异或。

同样,我们要找出(a-b)和(b-c)之间符号位的差异。如果它们有不同的符号位,一种情况是

如果(a-b)和(b-c)具有相同的符号位,则b是使用与上述相似的参数的中位数。实验表明,一个随机输入将需要1.667个比较来找出中值,并需要一个额外的比较来获得顺序。

融渊
2023-03-14

如果您只需要中间值,这里有一个基于最小/最大运算符的无分支解决方案:

中值=最大值(最小值(a,b),最小值(最大值(a,b,c))

英特尔CPU具有SSE最小/最大矢量指令,因此根据您或编译器的矢量化能力,这可以运行得非常快。

 类似资料:
  • 过滤出数组中比较函数不返回 true 的所有值。 类似于difference ,除了接受一个 comparator (比较函数)。 使用 Array.filter() 和 Array.findIndex() 来查找合适的值。 const differenceWith = (arr, val, comp) => arr.filter(a => val.findIndex(b => comp(a, b

  • 有没有一个相当标准的C(Linux)函数,或者一种代码高效但性能良好的方法来比较任意大小的两个整数? 我正在寻找一些参数为int intcmp(const void*a,const void*b,size\t size)的东西,它适用于任何实际大小的整数。(如果架构是big-endian的话(我认为)可以工作。) 我倾向于使用这样的实现(通过高效整数比较函数的改进),但它不是完全通用的,并且有足够

  • 问题内容: 如何比较javascript中的2个函数?我不是在谈论内部参考。说 可以比较和吗? 问题答案:

  • 所以我正在使用一些预先存在的比较器,它们比较两个元组中的某些值,如果第一个大于第二个,则返回true,否则返回false。这是其中之一的代码: 现在,我有一个字典,里面有许多上面比较的类型的元组条目。我想以相反的顺序对它们进行排序,但我真的不知道如何完成。我在想这样的事情: 但是我不知道向比较器传递什么,因为每个比较器都有两个参数(subInfo1、subInfo2)。我不能更改比较器函数。

  • 问题内容: 我正在尝试编写代码以比较两个数组。在第一个数组中,我输入了自己的数字,但是在第二个数组中,输入了输入文件中的数字。该数组的大小由文件中的第一个数字确定,而第一个数组的大小始终为10。两个数组以及数字的长度必须相同。 我的代码如下: 问题答案: