观察者模式中的回调函数注册和非静态函数注册

相关文章:C++中的观察者模式

1.关于回调函数传输的传递

在上文(C++中的观察者模式)中,采用了常用的void函数和空参数。

我们可以通过修改typedef void   (*EventHandler)(void);中的参数列表,如改成typedef void   (*EventHandler)(double,double,double);

这样就可以传递三个参数。

调用的时候按照如下的方法调用:
EventHandler notifyEvent = AllEvent.GetEvent()[i];

(*notifyEvent)(tmpdouble1,tmpdouble2,tmpdouble3);

2.注册类成员的非静态函数

上面的用法,我们可以看到,需要输入函数的地址。但是在C++的类设计中,非静态类方法是设置为共用的,即无论实例化多少个对象,都只会分配一个函数地址,只有一个函数副本。
例如fun()是类foo中的一个成员,foo a,b;
我们在调用a.fun()是,编译器会自动修改为fun(&a),即传递对象的this指针,共用相同的函数。
这时,我们无法通过foo::fun注册回调函数。因为我们每个实例化的对象对应的fun里面操作的属性可能都不一样。

需要使用std::bind来进行非静态函数绑定,具体方法如下:

#include<functional>
typedef std::function<void(void)> callBackFunction;
callBackFunction bindFun=std::bind(&foo::func,this);

带参数的版本如下:

#include<functional>
typedef std::function<void(double,double,double)> callBackFunction;
callBackFunction bindFun=std::bind(&foo::func,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3);
 

然后我们可以把bindFun添加到相应的容器或函数参数中。

JsonParser–使用python编写的json解析器

最近在练习python,于是尝试使用python编写json解析器,目前已经大体实现,通过了jsonTestFile.txt中的测试例子。代码github网址为:https://github.com/siukwan/jsonparser

下面重点介绍编写过程中遇到的一些需要注意的问题。

1.json的主体内容

我这里所提及的json主体内容主要是指两大类:1.对象object;2.数组array。

因为一个json格式的字符串不是一个object就是一个array。所以编写jsonparser的类中,有_parse_object和_parse_array两个函数。首先通过parse函数直接判断开始的符号为{还是[进而决定调用_parse_object还是_parse_array。

2.json中的key

标准json格式中的key是string类型,使用双引号包括。其中类中的_parse_string函数专门用来解析key。

3.json中的value

json中的value相对复杂,类型可以是object,array,string,数字,true,false,null。

在编写过程中,我刚开始没有编写解析嵌套的object和array,先编写了_parse_number和_parse_string。我们在解析了key后,会遇到冒号:,然后跳过冒号,我们进一步判断非空字符,如果为”,则接下来是string,否则的话接下来是number。

number中需要注意的是,我们要判断是整型还是浮点数,需要进行一个int或float的强制转换。json中小数的表达方式有科学记数法和普通的小数点表示法,所以如果字符串中包含e、E和.则强制转换成float,其他转换成int。

完成上述解析后,我们开始考虑解析嵌套的object和array。如果遇到的字符为{则调用_parse_object函数,遇到[则调用_parse_array函数。我们把value解析统一封装到函数_parse_value中,如下:

def _parse_value(self):
	'''
	解析值,包括string,数字
	'''
	c = self._str[self._index]

	#解析对象
	if c == '{':
		self._index+=1
		self._skipBlank()
		return self._parse_object()
	#解析数组
	elif c == '[':
		#array
		self._index+=1
		self._skipBlank()
		return self._parse_array()
	#解析string
	elif c == '"':
		#string
		self._index += 1
		self._skipBlank()
		return self._parse_string()
	#解析null
	elif c=='n' and self._str[self._index:self._index+4] == 'null':
		#null
		self._index+=4
		return None
	#解析bool变量true
	elif c=='t' and self._str[self._index:self._index+4] == 'true':
		#true
		self._index+=4
		return True
	#解析bool变量false
	elif c=='f' and self._str[self._index:self._index+5] == 'false':
		#false
		self._index+=5
	return False
	#剩下的情况为number
	else:
		return self._parse_number()

其中开始parse函数只会调用_parse_object或者_parse_array,而这两个函数中的value解析又有可能继续调用_parse_object或者_parse_array,从而实现了json对象或数组的嵌套解析。

4.避开空格

json字符串或者文件中,非key或非value的地方可能会存在换行,空格,缩进等,所以编写了_skipBlank函数,跳过这些空格。

5.记录当前解析的位置

使用了类成员_index来记录当前解析的位置,其中这个部分比较多细节,不是很难,具体请查看代码。

#1288 : Font Size

1.通过分析这道题目的规模,采用朴素方法的时间复杂度为O(n^2),即10^6,理论上可以通过,于是先采用朴素方法进行求解。

描述

Steven loves reading book on his phone. The book he reads now consists of N paragraphs and the i-th paragraph contains ai characters.

Steven wants to make the characters easier to read, so he decides to increase the font size of characters. But the size of Steven’s phone screen is limited. Its width is W and height is H. As a result, if the font size of characters is S then it can only show ⌊W / S⌋ characters in a line and ⌊H / S⌋ lines in a page. (⌊x⌋ is the largest integer no more than x)

So here’s the question, if Steven wants to control the number of pages no more than P, what’s the maximum font size he can set? Note that paragraphs must start in a new line and there is no empty line between paragraphs.

输入

Input may contain multiple test cases.

The first line is an integer TASKS, representing the number of test cases.

For each test case, the first line contains four integers N, P, W and H, as described above.

The second line contains N integers a1, a2, … aN, indicating the number of characters in each paragraph.

For all test cases,

1 <= N <= 103,

1 <= W, H, ai <= 103,

1 <= P <= 106,

There is always a way to control the number of pages no more than P.

输出

For each testcase, output a line with an integer Ans, indicating the maximum font size Steven can set.

样例输入

2
1 10 4 3
10
2 10 4 3
10 10

样例输出

3
2

 
AC代码:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
#include <string>
#include <unordered_map>
#include <set>
#include <map>
#include <memory.h>
using namespace std;

int main()
{
	int t = 0;
	scanf("%d", &t);
	long long a[1001];
	while (t--)
	{
		memset(a, 0, sizeof(a));
		int n, p, w, h;
		scanf("%d%d%d%d", &n, &p, &w, &h);
		for (int i = 0; i < n; ++i)
			scanf("%d", &a[i]);

		int maxSize = min(w, h);
		bool flag = true;
		int size = maxSize;
		for (size = maxSize; size >=1; size--)
		{
			flag = true;
			int eachLineWords = w / size;//每行能放的单词数量
			int lineWords = h / size;//每页能放的行数
			long long totalLine = p*lineWords;//一共能放的单词行数

			int sumCount = 0;
			int tmp = 0;
			for (int i = 0; i < n; ++i)
			{
				tmp = a[i] / eachLineWords;
				if (a[i] % eachLineWords != 0)
					sumCount += (tmp + 1);
				else
					sumCount += tmp;
				if (sumCount > totalLine)
					flag = false;
			}
			if (flag) break;
		}
		if (flag)
			printf("%d\n", size);
		else
			printf("%d\n", 0);
	}

	return 0;
}