程序设计范式四
要求
从txt文件里面读入群成员名称
输入红包个数:10
输入红包金额:88.88
随机分配金额到10个小红包里面,要考虑特殊情况(红包数量不能超过总人数,不能是负数,要够分)
(金有额一定要对得上,要足够随机,不要太平均)
20个线程---去抢红包。用互斥锁,锁住竞争资源,不要导致分配错误,抢的过程添加一些随机延时
显示人员---金额的分配表
实现代码中对金额的随机分配集中在avg左右,随机幅度除去最后一个数后较小。
#include <iostream>
#include <cstring>
#include <pthread.h>
#include <cmath> // 引入cmath头文件来使用round函数
#include <cstdlib>
#include <ctime>
#include <unistd.h>
#define MAX_NAMES 100
#define MAX_PACKETS 100
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
char names[MAX_NAMES][100];
int num_names = 0;
double remaining_sum = 0.0; // 剩余总金额
int total = 0; // 剩余红包数量
double getRandMoney(){
if(remaining_sum <= 0 || total <= 0){
return 0;
}
if (total == 1) {
total--;
return remaining_sum;
}
double avg = remaining_sum / total;
double min = avg / 2;
if (min < 0.01) min = 0.01; // 避免分配过小的红包
double max = (avg * 2 > remaining_sum) ? remaining_sum : avg * 2;
double money = min + (max - min) * ((double)rand() / RAND_MAX);
money = std::round(money * 100) / 100.0; // 四舍五入到小数点后两位
if (money > remaining_sum) {
money = remaining_sum;
}
remaining_sum -= money;
total--;
return money;
}
void* distribute_to_name(void* arg) {
char* name = (char*)arg;
double money = 0.0;
pthread_mutex_lock(&mtx);
if (total > 0) {
money = getRandMoney(); // 尝试获取红包金额
if (money > 0.0) {
printf("%s抢到了%.2lf元\n", name, money);
}
}
else {
printf("%s没有抢到红包\n", name);
}
pthread_mutex_unlock(&mtx);
return NULL;
}
void readNamesFromFile(const char* filename, int max_names) {
FILE* file = fopen(filename, "r");
if (!file) {
perror("无法打开文件");
exit(1);
}
while (num_names < max_names && fscanf(file, "%99s", names[num_names]) == 1) {
num_names++;
}
fclose(file);
}
void distributeRedPacket(int numPackets, double totalAmount, int numNames) {
if (numPackets > MAX_PACKETS) {
fprintf(stderr, "红包个数不能超过%d个\n", MAX_PACKETS);
exit(1);
}
num_names = numNames;
remaining_sum = totalAmount; // 设置剩余总金额
total = numPackets; // 假设每个名字都可以分到一个红包
srand(time(NULL)); // 初始化随机数生成器
pthread_t threads[num_names];
for (int i = 0; i < num_names; i++) {
pthread_create(&threads[i], NULL, distribute_to_name, (void*)names[i]);
sleep(rand() % 2);
}
for (int i = 0; i < num_names; i++) {
pthread_join(threads[i], NULL);
}
}
int main() {
char filename[] = "D:\\class1.txt";
readNamesFromFile(filename, MAX_NAMES);
int numPackets;
double totalAmount;
printf("红包个数:");
scanf("%d", &numPackets);
printf("总金额:");
scanf("%lf", &totalAmount);
distributeRedPacket(numPackets, totalAmount, num_names);
return 0;
}