06扩展欧几里得&简版printf函数实现

文章目录

扩展欧几里得&简版printf函数实现

一、扩展欧几里得

欧几里得算法可以快速求解 a * x + b * y = 1 方程的一组整数解。

当 b = 0 时,可得 a * x = 1,当 a = 1,x = 1,y = 任意值 时满足条件。欧几里得算法最后一步也是 b = 0 时,返回 a 的值。求解一组解的过程与欧几里得算法的流程类似,属于递归和回溯的应用。

#include <stdio.h>

int ex_gcd(int a, int b, int *x, int *y) {
        if (!b) {
                *x = 1, *y = 0;
                return a;
        }
        int xx, yy, ret = ex_gcd(b, a % b, &xx, &yy);
        *x = yy;
        *y = xx - a / b * yy;
        return ret;
}

int main() {
        int a, b, x, y;
        while (~scanf("%d%d", &a, &b)) {
                printf("ex_gcd(%d, %d) = %d\n", a, b, ex_gcd(a, b, &x, &y));
                printf("%d * %d + %d * %d = %d\n", a, x, b, y, a * x + b * y);
        }
}

此代码为扩展欧几里得算法,解决的问题是: a * x + b * y = gcd(a, b) 的一组整数解。

二、简版 printf 函数实现

#include <stdio.h>
#include <stdarg.h>
#include <inttypes.h>

int output_num(int x, int digit) {
        int cnt = 0;
        while (x) {
                putchar(x % 10 + '0'), ++cnt;
                x /= 10;
        }
        return cnt;
}

int reverse_num(int x, int *temp) {
        int cnt = 0;
        do {
                *temp = *temp * 10 + x % 10;
                x /= 10;
                cnt++;
        } while (x);
        return cnt;
}

// const 代表可以接收一个常量,是不允许被修改的 
int my_printf(const char *frm, ...) {
        int cnt = 0;
        va_list arg;
        va_start(arg, frm);
        #define PUTC(a) putchar(a), ++cnt
        // 字符串的末尾是字符 '\0', '\0' = 0 
        for (int i = 0; frm[i]; i++) {
                switch (frm[i]) {
                        case '%': {
                                switch (frm[++i]) {
                                        case '%': PUTC(frm[i]); break;
                                        case 'd': {
                                                int x = va_arg(arg, int);
                                                uint32_t xx = 0;
                                                if (x < 0) {
                                                        PUTC('-');
                                                        xx = -x;
                                                }
                                                int x1 = xx / 100000, x2 = xx % 100000;
                                                int temp1 = 0, temp2 = 0;
                                                int digit1 = reverse_num(x1, &temp1);
                                                int digit2 = reverse_num(x2, &temp2);
                                                if (x1) digit2 = 5;
                                                else digit1 = 0;
                                                cnt += output_num(temp1, digit1);
                                                cnt += output_num(temp2, digit2);
                                        } break;
                                        case 's': {
                                                const char *str = va_arg(arg, const char *);
                                                for (int i = 0; str[i]; i++) {
                                                        PUTC(str[i]);
                                                }
                                        } break;
                                  }
                        } break;
                        default: PUTC(frm[i]); break;
                }
        }
        #undef PUTC
        va_end(arg);
        return cnt;
}

int main() {
        int a = -123;
        printf("hello world!\n");
        my_printf("hello world!\n");
        printf("int (a) = %d\n", a);
        my_printf("int (a) = %d\n", a);
        printf("INT32_MAX = %d\n", INT32_MAX);
        my_printf("INT32_MAX = %d\n", INT32_MAX);
        printf("INT32_MIN = %d\n", INT32_MIN);
        my_printf("INT32_MIN = %d\n", INT32_MIN);
        return 0;
}
上一篇:Linux学习之系统编程篇:条件变量(pthread_cond_init / wait / signal / broadcast / destroy)


下一篇:QT c++实现web网页的一些操作