面试题积累_02

1

写一个程序,实现分数相加。用户以分子/分母的形式输入分数,程序打印相加后的结果。如:
输入:
5/6
3/4

输出:
The sum is 19/12
辗转相除法化简

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// 定义SWAP宏函数,用来交换两个整数
#define SWAP(x, y) {	\
	int tmp = x;	\
	x = y;		\
	y = tmp;	\
}

int main(void) {
	int num1, denom1;
	printf("Enter first fraction: ");
	scanf("%d/%d", &num1, &denom1);

	int num2, denom2;
	printf("Enter second fraction: ");
	scanf("%d/%d", &num2, &denom2);

	int result_num = num1 * denom2 + num2 * denom1;
	int result_denom = denom1 * denom2;
	int result_gcd = gcd(result_num, result_denom);

	printf("The sum is %d/%d\n", result_num / result_gcd, result_denom / result_gcd);

	return 0;
}

// 用辗转相除法求最大公约数: gcd(a, b) = gcd(b, r)
int gcd(int a, int b) {
	if (a < b) {
		SWAP(a, b);
	}
	while (b != 0) {
		int r = a % b;
		a = b;
		b = r;
	}
	return a;
}

找出数组中最小可用的ID

unsigned min_free(unsigned arr[], int n);

ex:
input:[0,3,9,8,19,6,4,1,7,2,5]
output:10

方法1:

暴力破解

方法2:

先排序,再找最小可用ID

方法3:

先遍历给定的数组,标记已经使用的ID。再重新遍历标记用的数组,查找最小可用ID

unsigned min_free(unsigned arr[], int n)
{
	int* flag = calloc(n, sizeof(int));
	int value;
	// 遍历数组,标记已使用过的ID
	for (int i = 0; i < n; i++)
	{
		value = arr[i];
		flag[value] = 1;		// 将使用过的ID与下标对应起来
	}
	// 遍历做标记用的数组,查找第一个未被使用的元素,返回其下标
	for (int i = 0; i < n; i++)
	{
		if (!flag[i])
			return i;
	}	
}

方法4:

分区操作 + 二分查找

posted @ 2023-02-01 19:37  MyXjl  阅读(53)  评论(0编辑  收藏  举报