写一个程序,来计算x个工作日后到哪个日子

这个程序解决的问题

1.最近手中有一些资金,按照我现在余额,我算出了我还能定投x天,但是因为周末放假是不能进行定投的,只有周内可以。所以即使我知道了我现在能定投多少天,但也不能解决我想知道以我现在的资金,我可以最多坚持到定投到某一年的某个日子,于是乎,我灵机一动,最近正好在学c++,所以就有了下面这个程序。

程序解读

1.在想到要靠程序来解决问题的时候,我第一个就想到了闰年,闰月的问题,于是乎,我决定创建一个日期类,和一个周类,因为,周和日期之间没有特别的相关联条件,所以每过一天,就要给这个个周加一天,到了周末则置1;

2.week类中我重载了++运算符,为了方便周的++,每次只需要调用++,week类就会自动处理周的循环

3.在Date类中,有个主要的函数,就是判断这个月有多少天,其实也就涉及到了年月日的进位问题。类中有详细的注释,不再赘述。

实现

class weekday {
public:
	weekday(int week){//构造函数
		if (week <= 7 && week >= 1) {
			_week = week;
		}
		else {
			assert(0);
		}
	};

	int getIsWeek() {//返回周几
		return _week;
	}
public://重载----------------------------------------
	weekday& operator++() {
		if (_week < 7) {
			_week++;
		}
		else {
			_week = 1;
		}
		return *this;
	}
private:
	int _week;
};
class Date {
public:

	Date(int year = 2019, int month = 11, int day = 6,int week = 3) 
		:_year(year)
		,_month(month)
		,_day(day)
		,_weekday(week)
	{}
public://功能---------------------------------
	int getDayIsWeek() {
		return _weekday.getIsWeek();
	}

public://重载-------------------------------
	friend 	ostream& operator<<(ostream& out, Date& d);//<<重载

	int& operator++() {
		int monDay = getDaysOfMonth(_year,_month);
		if (_day < monDay) {//不是本月最后一天
			_day++;
		}
		else if (_month < 12) {//是本月最后一天且,month不是12月
			_month++;
			_day=1;
		}
		else {//是本月最后一天且,month==12
			_month = 1;
			_day = 1;
			_year++;
		}
		++_weekday;
		return _day;
	}

private://内部函数-----------------------------------
	int getDaysOfMonth(int year, int month) {
		if (month > 12 || month < 0) {
			assert(1);
		}
		int DaysOfMonth[12] = { 31,28,31,30,
						      31,30,31,31,
						      30,31,30,31 };
		if ( month == 2 && getIsLeap(year)) {
			DaysOfMonth[1]++;
		}
		return DaysOfMonth[month - 1];
	}
	int getIsLeap(int year) {
		return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
	}
private:
	int _year;
	int _month;
	int _day;
	weekday _weekday;
};
ostream& operator<<(ostream& out, Date& d) {
	cout << d._year << ":" << d._month << ":" << d._day << endl;
	return out;
}
Date PrintTheWeekDayAfterDays(int n) {
	int count = 0;
	Date d;
	for (int i = n;i > 0;) {
		if (d.getDayIsWeek() <= 5 && d.getDayIsWeek() >= 1) {
			i--;
		}
		++d;
	}
	return d;
}
int main() {

	Date d = PrintTheWeekDayAfterDays(154);
	cout << d;
	system("pause");
}

 

### 关于题目分解及解答 您提出的问题包含四个部分:**工作与休息判断、逆波兰表达式求值、循环报数问题以及链表排序问题**。以下是针对每个问题的详细说明和C语言实现。 --- #### **1. 工作与休息判断** 根据描述,该人每周工作5天并休息2天。我们需要编一个程序来判断给定日期是否处于工作的状态。 ```c #include <stdio.h> int is_working(int year, int month, int day) { // 基准日期为 2000 年 1 月 1 日 星期六 (假设当天为周六) const int base_year = 2000; const int base_month = 1; const int base_day = 1; struct tm date = { .tm_year = year - 1900, .tm_mon = month - 1, .tm_mday = day }; time_t target_date = mktime(&date); struct tm base_date = { .tm_year = base_year - 1900, .tm_mon = base_month - 1, .tm_mday = base_day }; time_t start_date = mktime(&base_date); long days_diff = difftime(target_date, start_date) / (60 * 60 * 24); // 计算相差天数 int weekday = (days_diff + 6) % 7; // 调整基准星期为周六 return weekday <= 4 ? 1 : 0; // 如果是周一至周五则返回 true 表示工作日 } void work_or_rest() { int year, month, day; printf("请输入年份、月份、日子(yyyy mm dd): "); scanf("%d%d%d", &year, &month, &day); if(is_working(year, month, day)) { printf("这一天他在工作。\n"); } else { printf("这一天他在休息。\n"); } } ``` --- #### **2. 逆波兰表达式求值** 我们通过栈结构对逆波兰表达式进行解析,并逐项计算结果。 ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define MAX_STACK_SIZE 100 typedef struct { double data[MAX_STACK_SIZE]; int top; } Stack; void init_stack(Stack *s) { s->top = -1; } int push(Stack *s, double value) { if(s->top == MAX_STACK_SIZE - 1){ return 0; // 栈满无法压入 } s->data[++(s->top)] = value; return 1; } double pop(Stack *s) { if(s->top == -1){ exit(EXIT_FAILURE); // 异常退出 } return s->data[(s->top)--]; } double evaluate(char expr[]) { Stack stack; init_stack(&stack); char token[10]; // 存储读取的字符块 for(int i=0;;i++) { sscanf(expr+i,"%[^+-/*] ",token); if(token[0]== '\0') break; i += strlen(token)+1; if(isdigit(token[0]) || token[0]=='-' ){ push(&stack, atof(token)); }else{ double opnd_2 = pop(&stack),opnd_1 = pop(&stack); switch(*expr){ case '+':push(&stack,opnd_1+opnd_2);break; case '-':push(&stack,opnd_1-opnd_2);break; case '*':push(&stack,opnd_1*opnd_2);break; case '/':push(&stack,opnd_1/opnd_2);break; } i++; } } return pop(&stack); } void test_rpn(){ char rpn_expr[]="3 4 + 2 * 7 /"; printf("逆波兰表达式的值:%f\n",evaluate(rpn_expr)); } ``` --- #### **3. 循环报数问题(约瑟夫斯问题)** 对于 n 个人围圈报数的情况,可以采用递归的方式解决约瑟夫问题。 ```c #include<stdio.h> // 约瑟夫斯问题函数 m 是步长,n 是人数,k 是起始位置 int Josephus(int n,int m,int k){ if(n==1)return 0;// 只剩一人直接返回索引0 int x=Josephus(n-1,m,k);// 上一轮的结果 return(x+m)%n; } void josephus_problem(){ int n,m; printf("请输入总人数 n 和报数上限 m:"); scanf("%d %d",&n,&m); int result=Josephus(n,m,0); printf("最终留下的人最初的位置:%d\n",result+1); } ``` --- #### **4. 链表排序问题** 使用 C 实现链表插入排序算法: ```c #include <stdio.h> #include <stdlib.h> struct Node { int val; struct Node *next; }; // 插入排序核心代码 void insert_sorted(struct Node **head_ref, struct Node *new_node) { struct Node **current = head_ref; while (*current && ((*current)->val < new_node->val)) current = &((*current)->next); new_node->next = *current; *current = new_node; } struct Node *createNode(int v){ struct Node *tmp=(struct Node*)malloc(sizeof(struct Node)); tmp->val=v; tmp->next=NULL; return tmp; } void sort_linked_list(){ struct Node *head = NULL,*temp=NULL; int input_val; printf("请输入若干个数字构成链表,以任意非数值字符结束:\n"); while(scanf("%d",&input_val)!=EOF){ temp=createNode(input_val); insert_sorted(&head,temp); } printf("排序后的链表为:\n"); for(temp=head;temp!=NULL;temp=temp->next){ printf("%d -> ",temp->val); } puts("END"); } ``` --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值