Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add C code in chapter_greedy #755

Merged
merged 15 commits into from
Sep 21, 2023
3 changes: 3 additions & 0 deletions codes/c/chapter_greedy/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
add_executable(coin_change_greedy coin_change_greedy.c)
add_executable(fractional_knapsack fractional_knapsack.c)
add_executable(max_capacity fractional_knapmax_capacitysack.c)
add_executable(max_product_cutting max_product_cutting.c)
62 changes: 62 additions & 0 deletions codes/c/chapter_greedy/fractional_knapsack.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* File: fractional_knapsack.c
* Created Time: 2023-09-14
* Author: xianii ([email protected])
*/

#include "../utils/common.h"

/* 物品 */
struct item {
int w; // 物品重量
int v; // 物品价值
};

typedef struct item Item;

/* 按照价值密度排序 */
int sortByValueDensity(const void *a, const void *b) {
Item *t1 = (Item *)a;
Item *t2 = (Item *)b;
return (float)(t1->v) / t1->w < (float)(t2->v) / t2->w;
}

/* 分数背包:贪心 */
float fractionalKnapsack(int wgt[], int val[], int itemCount, int cap) {
// 创建物品列表,包含两个属性:重量、价值
Item *items = malloc(sizeof(Item) * itemCount);
for (int i = 0; i < itemCount; i++) {
items[i] = (Item){.w = wgt[i], .v = val[i]};
}
// 按照单位价值 item.v / item.w 从高到低进行排序
qsort(items, (size_t)itemCount, sizeof(struct Item), sortByValueDensity);
// 循环贪心选择
float res = 0.0;
for (int i = 0; i < itemCount; i++) {
if (items[i].w <= cap) {
// 若剩余容量充足,则将当前物品整个装进背包
res += items[i].v;
cap -= items[i].w;
} else {
// 若剩余容量不足,则将当前物品的一部分装进背包
res += (float)cap / items[i].w * items[i].v;
cap = 0;
break;
}
}
free(items);
return res;
}

/* Driver Code */
int main(void) {
int wgt[] = {10, 20, 30, 40, 50};
int val[] = {50, 120, 150, 210, 240};
int capacity = 50;

// 贪心算法
float res = fractionalKnapsack(wgt, val, sizeof(wgt) / sizeof(int), capacity);
printf("不超过背包容量的最大物品价值为 %0.2f\n", res);

return 0;
}
39 changes: 39 additions & 0 deletions codes/c/chapter_greedy/max_capacity.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* File: max_capacity.c
* Created Time: 2023-09-15
* Author: xianii ([email protected])
*/

#include "../utils/common.h"

/* 最大容量:贪心 */
int maxCapacity(int ht[], int htLength) {
// 初始化 i, j 分列数组两端
int i = 0;
int j = htLength - 1;
// 初始最大容量为 0
int res = 0;
// 循环贪心选择,直至两板相遇
while (i < j) {
// 更新最大容量
int capacity = MIN(ht[i], ht[j]) * (j - i);
res = MAX(res, capacity);
// 向内移动短板
if (ht[i] < ht[j]) {
i++;
} else {
j--;
}
}
return res;
}

int main(void) {
krahets marked this conversation as resolved.
Show resolved Hide resolved
int ht[] = {3, 8, 5, 2, 7, 7, 3, 4};

// 贪心算法
int res = maxCapacity(ht, sizeof(ht) / sizeof(int));
printf("最大容量为 %d\n", res);

return 0;
}
37 changes: 37 additions & 0 deletions codes/c/chapter_greedy/max_product_cutting.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* File: max_product_cutting.c
* Created Time: 2023-09-15
* Author: xianii ([email protected])
*/

#include "../utils/common.h"

/* 最大切分乘积:贪心 */
int maxProductCutting(int n) {
// 当 n <= 3 时,必须切分出一个 1
if (n <= 3) {
return 1 * (n - 1);
}
// 贪心地切分出 3 ,a 为 3 的个数,b 为余数
int a = n / 3;
int b = n % 3;
if (b == 1) {
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
return pow(3, a - 1) * 2 * 2;
}
if (b == 2) {
// 当余数为 2 时,不做处理
return pow(3, a) * 2;
}
// 当余数为 0 时,不做处理
return pow(3, a);
}

int main(void) {
int n = 58;
// 贪心算法
int res = maxProductCutting(n);
printf("最大切分乘积为 %d\n", res);

return 0;
}
2 changes: 2 additions & 0 deletions codes/c/utils/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>

#include "list_node.h"
#include "print_util.h"
#include "tree_node.h"
#include "greedy.h"

// hash table lib
#include "uthash.h"
Expand Down
16 changes: 16 additions & 0 deletions codes/c/utils/greedy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

#ifndef _GREEDY_H_
#define _GREEDY_H_

#ifdef __cplusplus
extern "C" {
#endif

#define MIN(a, b) (a < b ? a : b)
Nigh marked this conversation as resolved.
Show resolved Hide resolved
#define MAX(a, b) (a > b ? a : b)

#ifdef __cplusplus
}
#endif

#endif