编程珠玑第三章笔记加习题解答

本文分享了编程中数据结构的应用技巧,如利用数组优化if判断,通过二分查找提高搜索效率,以及解决分段税收计算、多项式系数求解、日期相关问题等习题的方法。同时,介绍了如何用字符图形表示字母,以及文件处理与字符串查找技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.感悟

看到数据第一时间应该想用什么数据结构去表示而不是直接就下手,比如100个if判断完全可以把判断条件放在数组中然后遍历数组判断,从而节省代码量,并且看到有序数据就要想到用二分查找去搜索

2.习题解答

1.分段税收,看到这种不断递增的税收直接二分查找

#include <iostream>  
using namespace std;

int basetax[100]; //固定交税的钱
int lowerbound[100]; //分区金钱
double taxrate[100]; //利率

int find(int left, int right, int Income)
{
	int l = left;
	int r = right;
	while (l <= r)
	{
		int mid = l + (r - l) / 2;
		if (Income - lowerbound[mid] < 500 && Income - lowerbound[mid] >= 0)
			return mid;
		else if (Income - lowerbound[mid] < 0) //目标值在左侧
			r = mid - 1;
		else
			l = mid + 1;
	}
	return 0;
}

int main()
{
	int left = 0;
	int right = 99;
	//给数组赋值
	for (int i = left; i < right; i++)
	{
		if (i == 0)
			lowerbound[i] = 0;
		else
			lowerbound[i] = 2200 + (i-1) * 500;
		if (i == 0 || i == 1) basetax[i] = 0;
		else
			basetax[i] = 75 * i - 80;
		if (i == 0) taxrate[i] = 0;
		else
			taxrate[i] = (double)(14 + i - 1) / 100;
	}
	int Income;
	cout << "请输入收入" << endl;
	cin >> Income;
	int val = find(left, right, Income);
	double tax = basetax[val] + (double)taxrate[val] * (Income - lowerbound[val]);
	cout << "交的税为" << endl;
	cout << tax;

	return 0;
}

2.求多项式系数

​ 没啥多说的暴力就行

3.编写函数,输入一个大写字母,输出一个字符数组,该字符数组用字符图形方式表示该字母

​ 这个题就是对应转换
在这里插入图片描述

4.给定两个日期,计算两者之间的天数;给定一个日期,返回值为周几;给定月和年,使用字符数组生成该月的日历

#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;

vector<int>monthDay = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

class Date
{
public:
	Date(int year, int month, int day) :m_year(year), m_month(month), m_day(day){}
	int dateDay();
	int betweenDay(const Date& date);
	int judgeWeekDay();
	void printCalendar();
private:
	bool judgeLeap(const int year);
	int m_year;
	int m_month;
	int m_day;
};

//判断某年是不是闰年
bool Date::judgeLeap(const int year)
{
	if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
	{
		return true;
	}
	return false;
}

//判断日期是这年第几天
int Date::dateDay()
{
	int allday = 0;
	for (int i = 1; i < this->m_month; i++)
	{
		allday += monthDay[i];
	}
	if (this->m_month > 2 && judgeLeap(this->m_year))
	{
		allday += 1;
	}
	return allday + this->m_day;
}

//计算两个日期的间隔天数
int Date::betweenDay(const Date&date)
{
	int totalDays = 0;
	Date minDate = this->m_year < date.m_year ? *this : date;
	Date maxDate = this->m_year < date.m_year ? date : *this;
	if (this->m_year == date.m_year)
		return abs(this->dateDay() - const_cast<Date&>(date).dateDay());
	else
	{
		for (int i = minDate.m_year; i < maxDate.m_year; i++)
		{
			totalDays += judgeLeap(i) ? 366 : 365;
		}
		return totalDays + maxDate.dateDay() - minDate.dateDay();
	}
}

//判断日期是这周星期几
int Date::judgeWeekDay()
{
	Date td(1900, 1, 1);
	return this->betweenDay(td) % 7 + 1;
}

//打印某年某月月历
void Date::printCalendar()
{
	printf("%d年%d月月历\n", this->m_year, this->m_month);
	printf("日 一 二 三 四 五 六\n");
	this->m_day = 1;
	int firstDay = this->judgeWeekDay();
	int i;
	if (firstDay != 7)  //先打印第一行日期
	{
		for (i = 0; i < firstDay; i++)
		{
			printf("  ");
		}
		for (i = 1; i <= 7 - firstDay; i++) //把第一周打印完,从firstDay开始的星期几到星期天 
		{
			printf("%3d", i);
		}
		cout<<endl;
	}
	int monthday = (this->m_month == 2) ? (this->judgeLeap(this->m_year) ? 29 : 28) : monthDay[this->m_month];

	for (i = 8 - firstDay; i <= monthday; i++)
	{
		printf("%-3d", i);
		if (i % 7 == 7 - firstDay)
			printf("\n");
	}
	printf("\n");
}

int main()
{
	Date d(2019,10,21);
	d.printCalendar();
	return 0;
}

5.查找后缀连字符的连接

​ 没啥好说的直接用find函数查找

#include<iostream>
#include<vector>
#include<string>
using namespace std;

int main()
{
	vector<string>v = { "et-ic", "al-is-tic", "s-tic", "p-tic", "-lyt-ic", "ot-ic", "an-tic", "n-tic", "c-tic", "at-ic", "h-nic", "n-ic", "m-ic", "l-lic", "b-lic", "-clic", "l-ic", "h-ic", "f-ic", "d-ic", "-bic", "a-ic", "-mac", "i-ac" };
	string s;
	while (cin >> s)
	{
		for (auto temp : v)
		{
			int i = s.find(temp);
			if (i != -1)
			{
				cout << temp;
				break;
			}
		}
	}
	return 0;
}

6.就是写一个文件这个文件有好多人的姓名,年龄啥的然后用正则匹配替换

7.完全看不懂在干嘛

8.好吧也没看懂

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白月光soul

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值