编程珠玑第三章

习题


1、首先是按照税率找到刚好税率最好的情况。这里用二分。

int a[100] = { 2200, 2700, ....}

double c[100] = {0, 0.14, 0.15, 0.16, ...}

首先用二分找最刚好比其小的那个数

int bs(int *a, int b, int e, int v)
{
	int *begin = a + b, int *end = a + e, *mid;
	if (!a || b >= e) return -1;
	while (begin < end)
	{
		mid = begin + ((end - begin) >> 1);
		if (*mid > v) end = mid;
		else if (*mid < v) begin = mid + 1;
		else return mid - a;
	}
	while (*mid > v) --mid;
	return mid - a;
}

然后

int iter = bs(a, 0, 100, v);

double tax = (money - a[iter]) * c[iter+1];

2、求多项式系数

y = a[n];
for (i = n - 1; i >= 0; --i)
   y = x * y + a[i];




3、略过,网上见到过源代码

4、日期处理

这里把所有相关的处理函数放出来。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
typedef struct _date
{
	int year, month, day;
}date;

//看是否是闰年
int leap(int year)
{
	return (0 == year % 4 && year % 100) || year % 400 == 0;
}

//看是时间是否有效
int legal(date a)
{
	if (a.month <0 || a.month > 12) return 0;
	if (a.month == 2) return a.day > 0 && a.day <= (28 + leap(a.year));
	return a.day >0 && a.day <= days[a.month -1];
}


//比较时间
int datecmp(date a, date b)
{
	if (a.year != b.year) return a.year - b.year;
	if (a.month != b.month) return a.month - b.month;
	return a.day - b.day;
}


//计算周几?
int weekday(date a)
{
	int tm = a.month >= 3 ? (a.month - 2) : (a.month + 10);
	int ty = a.month >= 3 ? (a.year) : (a.year - 1);
	return (ty + ty/4 - ty/100 + ty/400 + (int)(2.6 * tm - 0.2) + a.day) % 7;
}

//时间化为天数
int date2int(date a)
{
	int i ;
	int ret = a.year * 365 + (a.year - 1) / 4 - (a.year -1) / 100 + (a.year - 1) / 400;
	days[1] += leap(a.year);
	for (i = 0; i < a.month - 1; ret += days[i++]);
	days[1] = 28;
	return ret + a.day;
}

//天数化为时间
date int2date(int a)
{
	date ret;
	int i = 0;
	ret.year = a/146097*400;
	for (a %= 146097; a >= 365+leap(ret.year); 
		a -= 365 + leap(ret.year), ret.year++);
	days[i] += leap(ret.year);
	for (ret.month = 1; a >= days[ret.month - 1]; a -= days[ret.month - 1], ret.month++);
	days[1] = 28;
	ret.day = a + 1;
	return ret;
}

//计算距离
int dist(date a, date b)
{
	int ad = date2int(a);
	int bd = date2int(b);
	return ad - bd > ? ad - bd : bd - ad;
}


//生成日历
void cal(date a)
{
	int i, w, j, k;
	a.day = 1;
	if (a.month == 2) { k = days[a.month - 1] + leap(a.year);}
	else k = days[a.month - 1];

	printf("     %2d月%4d年   \n", a.month, a.year);
	printf("日 一 二 三 四 五 六\n");
	w = weekday(a);
	i = w % 7; while (i--) printf("   "); printf("%2d", 1);
	if (w % 7 == 6) printf("\n"); ++w;

	for (i = 1; i <= k; ++i, w = (w + 1) % 7)
	{
		if (w % 7 == 0) printf("%2d", i);
		else printf(" %2d", i);
		if (w % 7 == 6) printf("\n");
	}
}

第5题,解法是hash表中带hash。第一个以ic, tic 等做hash

首先根据后缀找到hash_set,再把余下的字段,依次在hash_set中查找,并取出最长的。

#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<iterator>
#include<iostream>
#include<algorithm>
#include<hash_map>
#include<hash_set>

using namespace std;
using namespace stdext;

char *p[] = {"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"};


void build_map(hash_map<string, hash_set<string> >& dict)
{
	const int n = sizeof(p)/ sizeof(char *);
	for (int i = 0; i < n; ++i)
	{
		string line = p[i]; reverse(line.begin(), line.end());
		int pos = line.find('-');
		dict[line.substr(0, pos)].insert(line.substr(pos + 1, line.length() - pos - 1));
	}
}

string lookup(hash_map<string, hash_set<string> >& dict, string word)
{
	string line = word; reverse(line.begin(), line.end());
	int pos = line.find('-');
	string ret;

	hash_map<string, hash_set<string> >::iterator  iter;
	if (dict.end() != (iter = dict.find(line.substr(0, pos))))
	{
		hash_set<string> &h = iter->second;
		string temp = line.substr(pos + 1, line.length() - pos - 1);
		for (int j = 1; j <= temp.length(); ++j)
		{
			string c = temp.substr(0, j);
			if (h.find(c) != h.end() && c.length() > ret.length()) 
				ret = c;
		}
	}
	ret = iter->first + "-" + ret;
	reverse(ret.begin(), ret.end());
	return ret;
}
int main(void)
{
	string sline;
	hash_map<string, hash_set<string> > dict;
	build_map(dict);

	while (cin >> sline)
	{
		cout << lookup(dict, sline) << endl;
	}
	return 0;
}

6、这个可以用python来写,下面先看一下示例代码。

模板文件/tmp/win03.domain.template

;SetupMgrTag
[Unattended]

[GuiUnattended]
    AdminPassword=${admin_password}
    EncryptedAdminPassword=NO

    OEMSkipRegional=1

[UserData]
    ComputerName=${computer_name}

代码

import os

Template = None
if Template is None:
    t = __import__('Cheetah.Template', globals(), locals(),
                   ['Template'], -1)
    Template = t.Template

fp = open('/tmp/unattend.xml', 'w')
tem = open('/tmp/win03.domain.template').read()
domain_list = {'computer_name': 'computer',
               'admin_password': 'admin',
               'Use':'Use'}
info = str(Template(tem, searchList=[domain_list]))
fp.write(info)
fp.close()
如果采用C++实现,并且${}里面的代单词表明是要被替换的单词。那么处理方法如下:

void Template(char *fname, char *temp_fname, map<string, string>& dict)
{
    ofstream output(fname);
    ifstream temp(temp_fname);
    string line;
    while (getline(temp, line, '\n'))
    {
        int bpos = 0;
        string::size_type pos = 0;
        while (string::npos != (pos = line.find("${", bpos)))
        {
            string::size_type epos = line.find("}", pos);
            string t = line.substr(pos + 2, epos - pos - 2);
            cout << t << endl;
            map<string, string>::iterator iter = dict.find(t);
            if (dict.end() != iter)
            {
                line.replace(pos, epos - bpos + 1, iter->second);
                bpos += iter->second.length();
            }
            else
            {
                bpos = epos + 1;
            }
        }
        output << line << "\n\r";
    }
    temp.close();
    output.close();
}

7、略去,比较扯

8、2^16 = 65536个数。所以5个七段显示器肯定是够用的。

首先可以预处理一下,把0 =  {0, 2, 3, 4, 5, 6}相应的8个bit置1之后的值保存到一个数组中。

char rec[10];

char temp[7];

char *get(int n)

{

     int iter = 5;

     memset(temp, 0, sizeof(temp));

     while (n)

     {

          temp[iter--] = rec[n % 10];

          n /= 10;

     }

     while (iter>= 0) { temp[iter] = rec[0]; iter --;}

     return temp;

}


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值