面试题积累_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;
}
2
找出数组中最小可用的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:
分区操作 + 二分查找