mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 22:28:40 +08:00 
			
		
		
		
	feat: add C code in chapter_greedy (#755)
* add fractional_knapsack.c * update CMakeLists * add c code in chapter_greedy * fix header format * format code by clang-format * remove extra comments * replace ternary operator to MACRO * parameters form adjustment * Update fractional_knapsack.c * Update max_capacity.c * Update max_product_cutting.c * add comments for consistency with cpp ver * move MIN&MAX macro to source file * typo fix --------- Co-authored-by: Yudong Jin <krahets@163.com>
This commit is contained in:
		@ -1 +1,4 @@
 | 
				
			|||||||
add_executable(coin_change_greedy coin_change_greedy.c)
 | 
					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
									
								
								codes/c/chapter_greedy/fractional_knapsack.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								codes/c/chapter_greedy/fractional_knapsack.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * File: fractional_knapsack.c
 | 
				
			||||||
 | 
					 * Created Time: 2023-09-14
 | 
				
			||||||
 | 
					 * Author: xianii (xianyi.xia@outlook.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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(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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										43
									
								
								codes/c/chapter_greedy/max_capacity.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								codes/c/chapter_greedy/max_capacity.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * File: max_capacity.c
 | 
				
			||||||
 | 
					 * Created Time: 2023-09-15
 | 
				
			||||||
 | 
					 * Author: xianii (xianyi.xia@outlook.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../utils/common.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MIN(a, b) (a < b ? a : b)
 | 
				
			||||||
 | 
					#define MAX(a, b) (a > b ? a : b)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 最大容量:贪心 */
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Driver Code */
 | 
				
			||||||
 | 
					int main(void) {
 | 
				
			||||||
 | 
					    int ht[] = {3, 8, 5, 2, 7, 7, 3, 4};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 贪心算法
 | 
				
			||||||
 | 
					    int res = maxCapacity(ht, sizeof(ht) / sizeof(int));
 | 
				
			||||||
 | 
					    printf("最大容量为 %d\n", res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								codes/c/chapter_greedy/max_product_cutting.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								codes/c/chapter_greedy/max_product_cutting.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * File: max_product_cutting.c
 | 
				
			||||||
 | 
					 * Created Time: 2023-09-15
 | 
				
			||||||
 | 
					 * Author: xianii (xianyi.xia@outlook.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Driver Code */
 | 
				
			||||||
 | 
					int main(void) {
 | 
				
			||||||
 | 
					    int n = 58;
 | 
				
			||||||
 | 
					    // 贪心算法
 | 
				
			||||||
 | 
					    int res = maxProductCutting(n);
 | 
				
			||||||
 | 
					    printf("最大切分乘积为 %d\n", res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -13,6 +13,7 @@
 | 
				
			|||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <time.h>
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "list_node.h"
 | 
					#include "list_node.h"
 | 
				
			||||||
#include "print_util.h"
 | 
					#include "print_util.h"
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user