三分查找C语言实现

三分查找C语言实现
关键词: 变参函数函数指针三分查找C语言

昨天我动手实现了一下基于变参函数的一元N次函数的代码实现,以及三分查找的代码实现。这份代码中fact_func函数是可变参函数;fact_func2函数的参数是一个大小已知的数组(类似于Linux main函数中的argc, argv[]);thrid_search函数是一个三分查找函数。 不过在调用函数指针的时候遇到了问题:

  1. 不清楚如何表示 变参函数指针
  2. 即使变参函数指针可以传递,变参函数的可变参数列表又该如何传递?(个人想到用C语言的变参宏,不过如果宏定义一个代码块,没有返回值,这个代码实现又有点鸡肋)
  3. thrid_search函数中使用了flag参数,个人觉得具体代码实现有点low(重复代码段有点长,这里还可以优化)。
  4. 这段代码有没有bug?边界条件可能处理不好。

/*************************************************************************
	> File Name: 2.third_search.c
	> Author: ChenXiansen 
	> Mail: 1494089474@qq.com 
	> Created Time: Sun 22 Nov 2020 02:30:21 PM CST
 ************************************************************************/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

typedef double T;
#define T_token "%lf"
#define epsl 1e-10

#define P(val) {\
    printf("%s: "T_token"\n", #val, val);\
}
#define P_ans(ans, temp, x, n) {\
    printf("ans += "T_token" + "T_token" * ("T_token" ^ %d)\n", ans, temp, x, n);\
}
#define P_func(n, argv) {\
    __typeof(n) __temp = n;\
    printf("Func(x) = ");\
    while (--n > -1) {\
        printf("[ "T_token" * (x ^ %d) ]", argv[n], n);\
        n && printf(" + ");\
    }\
    printf("\n");\
    n = __temp;\
}

T fact_func(T x, int n, ...) {
    T ans = 0;
    va_list arg;
    va_start(arg, n);
    while (n--) {
        T temp = va_arg(arg, T);
        P_ans(ans, temp, x, n);
        ans += pow(x, n) * temp;
        P(ans);
    }
    return ans;
}

T fact_func2(T x, int n, T* argv) {
    T ans = 0;
    while(--n > -1) {
        T temp = argv[n];
        ans += pow(x, n) * temp;
    }
    return ans;
}

T thrid_search(T head, T tail, int flag, T(*func)(T, int, T*), int n, T* argv) {
    if (abs(tail - head) < epsl) return head;
    T m1, m2, l = head, r = tail;
    if (flag > 0) {
        while (l + epsl < r) {
            m1 = ((r - l) / 3) + l;
            m2 = ((r - l) / 3 * 2) + l;
            if (func(m1, n, argv) <= func(m2, n, argv)) {
                r = m2;
            } else {
                l = m1;
            }
        }
        return l;
    } else {
        while (l + epsl < r) {
            m1 = ((r - l) / 3) + l;
            m2 = ((r - l) / 3 * 2) + l;
            if (func(m1, n, argv) <= func(m2, n, argv)) {
                l = m1;
            } else {
                r = m2;
            }
        }
        return l;
    }
}

int main() {
    int n, flag;
    T left, right;
    n = 3;
    printf("请输入一元二次函数参数: ");
    T* hz_argv = (T*)malloc(sizeof(T) * 3);
    for (int i = n - 1; i >= 0; i--) {
        scanf(T_token, &hz_argv[i]);
    }
    P_func(n, hz_argv);
    printf("请输入待查询左右边界: ");
    scanf(T_token, &left);
    scanf(T_token, &right);
    flag = (hz_argv[n - 1] > 0) ? 1 : -1;
    printf("查找函数极值点:");
    printf(T_token"\n", thrid_search(left, right, flag, fact_func2, n, hz_argv));
    free(hz_argv);
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值