寒假总结

发布在 杂谈

颓废的大二上之后感觉良好的一个寒假,可能是我自上学以来效率最高的一个寒假了。

学习

LeetCode

大二上刚开学的时候因为数据结构上到链表和树的缘故,在LeetCode上刷了20多道Tag是链表和树的题目。

寒假的时候决心开始刷LeetCode,至寒假结束时已经完成了126道题,其中包括了绝大部分Easy题,以及少部分Medium题,虽然和真正学好算法相差甚远,应该算是基本上入门了。

主要接触了分治法以及相关的复杂度分析,哈希表,随机化相关的算法(蓄水池抽样以及FisherYales洗牌算法),简单的动态规划等。

通过的题目以及解法托管在我的Github上。

Python爬虫入门

参考书是《Python网络数据解析》,目前看到了第三章,主要接触了urlopen以及BeautifulSoup库以及最基本的爬虫思想,原书第三章的最后也简单的提到了爬虫用的Scrapy框架。

学习时候练习的代码托管在我的Github上。

MIT的算法导论公开课

目前看到了“快速排序以及随机化算法”这一节,但是对于之前所重点介绍的分治法的主定理仍然有不清楚的地方,需要花时间巩固学习并且配合LeetCode一起食用。

数据结构课程设计

因为其他事情的原因,我选的是最简单的第三题“基于查找表的单词检索软件”,但是我并没有使用二叉搜索树而是使用了Trie树来实现动态查找表。

抱着既然要做课设就不要糊弄的想法,这次的课设还是浪费了自己不少时间,在完成了最基本的Trie树以及Hash表之后,自己又实现了Hash表的迭代器以及Hash表的序列化,了解到了C语言中命令行参数的处理 - getopt。虽然程序仍然有大量可以优化和改进的地方,但是考虑到今年寒假投入的时间不是特别多,我总体上来说还是很满意的。


虽然说了不立Flag,写寒假总结督促自己,但是实际上今年寒假还是有各种堕怠,想要做的事情还是有很多没做,想想还是有点遗憾,但毕竟还是比大二上和去年寒假要好很多了。


关于输入和输出:仅对于自己而言,我认为输入和输出都是必要的,如果只强调输入,而忽视输出,那么只知道知识本身而不会运用知识,于我而言会失去学习的兴趣,更何况在大多数时候,缺乏一定数量的练习的我们甚至还没有能真正的掌握知识;而如果是以为的强调输出,那么可能和大一的我一样,只能成为为一个劣质的API Caller而已。


想到了去年团队总结说过的话,同样送给今天的自己:身为一个本科生,在扎实自己计算机基础的同时我也愿意更多的接触不同的方向比如iOS,Web的前端、后台技术甚至是一些设计的规范(世界这么大,我想去看看)。未来自己还要更加努力才行啊(毕竟现在的基础还是很弱)。

生活

大二上因为种种原因而陷入了迷茫,加权没有刷上来,在自己想学的东西上也几乎没有花什么时间,一直在懒懒散散地混日子,生活更是一团糟,但是好在并没有做出让自己后悔的事。

寒假刚开始的时候想了很多,虽然前路漫漫,伤痛注定多余喜悦,但我也决定不再逃避过去的自己,正视现在的自己。假期的时候和很多曾经的同学交流过人生和发展,也终于鼓起勇气认识了更多的人,看到了更多不一样的人生。然后这样的自己,突然又获得了梦想。

每一个不曾起舞的日子都是对生命的辜负,以上。

评论和共享

iOS学习笔记(三)

发布在 iOS开发

花了两天半的时间基本实现了APP中让用户选择头像的功能(仿照手机版QQ),整理和总结如下——

思路

- UIImagePickerController


原先想要采用UIImagePickerController来实现这个功能,UIImagePickerController是UINavigationController的子类,是系统提供的拍摄、选择照片和视频的UI。具体来说,在选择头像这个功能中,头像的来源有两种——拍照和从相册选择,同时完成头像的选择后我们还应该能够让用户选择头像的范围以及大小。

若头像的来源为拍照:

1
2
3
4
5
6
UIImagePickerController * imagePickerController = [[UIImagePickerController alloc]init];
imagePickerController.delegate = self;
imagePickerController.allowsEditing = YES;//允许编辑图片
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;//图片的来源为相机
//...还可以在这里修改相机的前后镜头 是否开启闪光灯等
[self presentViewController:imagePickerController animated:YES completion:nil];

同时,实现UIImagePickerDelegate中的如下方法:

1
2
3
4
5
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
UIImage * originImage = info[UIImagePickerControllerOriginalImage];//这样获取的是原图像
UIImage * editedImage = info[UIImagePickerControllerEditedImage];//这样获取的是修改后的图像
//...在这里实现图像的保存
}

如果头像的来源为相册,则只需修改imagePickerController的sourceType属性即可:

`imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;`

这样做就可以实现我们的需求了,但是这个方法的缺点也很明显,在这个方法中,我们使用的是系统封装好的UI,参考手机版QQ的选择头像我们可以发现,我们不能自定义相册中图片的分类、排版。同样的,我们也不能自定义编辑头像的界面,你不能将正方形的头像选框改成圆形的。因此,我们需要自己实现一个“UIImagePickerController”。在这个UIImagePickerController中,除了图片来源为拍照的情况下我们采用系统原生的UIImagePickerController以外,编辑图片和从相册中选取图片的功能我们都自己实现。

- PhotoKit和UICollectionView


参考博客:iOS 开发之照片框架详解

对于从相册选择图片的功能,我们可以采用PhotoKit来获取到图片的信息,并通过UICollectionView加以展示,这里主要给出PhotoKit的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#import <Photos/Photos.h>

PHFetchOptions *options = [[PHFetchOptions alloc]init];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
PHFetchResult * results = [PHAsset fetchAssetsWithOptions:options];
//...这样就取得了照片库中所有照片并将它们通过创建时间排序 当然这只是最简单的做法 还可以创建多个不同类别的相册

//...然后我们要通过如下的代码取得照片
PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc]init];
requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;//这里指定了照片的清晰度
[[PHImageManager defaultManager]requestImageForAsset:results[number]
targetSize:CGSizeMake(length, length)//指定了照片的大小
contentMode:PHImageContentModeDefault
options:requestOptions resultHandler:^(UIImage * result, NSDictionary * info) {
//...在这里展示照片
}];

- 自定义编辑头像的界面


主要有两个方面

  • 展示图片 我采用的方法是向一个UIScrollView中添加一个UIImageView
  • 圆形选框 采用了两个CAShapeLayer,一个是选框的Layer,另一个是遮罩的Layer

实现展示图片的功能首先需要了解UIScrollView中frame,contentSize和contentOffset的区别。同时,为了将图片限制在我们所画的边框内,关键是设置合理的minimumZoomScale(最小缩放比例)以及实时更新ContentSize,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
- (void)imageConfiguration {
self.imageView.frame = CGRectMake(WIDTH/2-LENGTH/2, HEIGHT/2-LENGTH/2-32, _imageSize.width, _imageSize.height);
//设置图片的位置
CGFloat zoomScale =[self zoomScaleWithSize:_imageSize];
//计算初始的zoomScale
CGFloat minimumZoomScale = [self minimumZoomScaleWithSize:_imageSize];
//计算最小的zoomScale
CGFloat maximumZoomScale = (minimumZoomScale <= 1.2) ? 1.2 : minimumZoomScale;
//这里的1.2可以替换成其他值
self.scrollView.minimumZoomScale = minimumZoomScale;
self.scrollView.maximumZoomScale = maximumZoomScale;
self.scrollView.zoomScale = zoomScale;
self.scrollView.contentSize = CGSizeMake(_imageSize.width*zoomScale+WIDTH-LENGTH, _imageSize.height*zoomScale+HEIGHT-LENGTH-64);
//为了保证将图片限制在边框内初始的ContentSize
self.scrollView.contentOffset = CGPointMake(WIDTH/2-LENGTH/2, HEIGHT/2-LENGTH/2-32);
//WIDTH是屏幕宽度 HEIGHT是屏幕高度 LENGTH是边框变长
}

- (CGFloat)zoomScaleWithSize:(CGSize)size {
CGFloat width = size.width;
CGFloat height = size.height;
CGFloat scale = (CGFloat)width/height;
CGFloat screenScale = (CGFloat)WIDTH/HEIGHT;
if (scale > screenScale) {
if ((CGFloat)WIDTH/width*height>LENGTH) {
return ((CGFloat)WIDTH / width);
} else {
return (LENGTH/height);
}
} else {
if ((CGFloat)HEIGHT/height*width>LENGTH) {
return ((CGFloat)HEIGHT/height);
} else {
return (LENGTH/width);
}
}
}
//思路是通过比较宽高比确定让图片正好容纳在屏幕内的比例,同时还保证图片能够包括边框

- (CGFloat)minimumZoomScaleWithSize:(CGSize)size {
CGFloat width = size.width;
CGFloat height = size.height;
if ((LENGTH / height)>(LENGTH / width)) {
return (LENGTH / height);
} else {
return (LENGTH / width);
}
}
//只保证图片能够包括边框即可

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
self.scrollView.contentSize = CGSizeMake(_imageSize.width*self.scrollView.zoomScale+WIDTH-LENGTH, _imageSize.height*self.scrollView.zoomScale+HEIGHT-LENGTH-64);
}
//UIScrollView代理 在缩放时能够正确的更新contentSize

圆形选框则比较简单,用一个CAShapeLayer即可实现,实现阴影遮罩(效果可以参考手机版QQ)则需要另一个CAShapeLayer,这里有一个问题,如果直接把遮罩设在self.view上,将会在页面切换的时候造成动画的不自然,我的解决方法是在self.view上添加一个UIView的实例contentView作为容器,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
self.contentView.layer.mask = self.maskLayer;
[self.contentView.layer insertSublayer:self.borderLayer above:self.imageView.layer];

- (CAShapeLayer *)borderLayer {
if (!_borderLayer) {
//...在此设置边框
}
return _borderLayer;
}

- (CAShapeLayer *)maskLayer {
if (!_maskLayer) {
_maskLayer = [CAShapeLayer layer];
[_maskLayer setFrame:CGRectMake(0, 0, WIDTH, HEIGHT)];
[_maskLayer setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.5].CGColor];
//确定阴影的明暗
//...setPath确定无阴影的范围
}
return _maskLayer;
}

问题

- 修改导航栏的高度


1
2
3
4
5
6
7
8
9
10
11
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
CGRect navRect = self.navigationController.navigationBar.frame;
self.navigationController.navigationBar.frame = CGRectMake(navRect.origin.x, navRect.origin.y, navRect.size.width, 64);
}

- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
CGRect navRect = self.navigationController.navigationBar.frame;
self.navigationController.navigationBar.frame = CGRectMake(navRect.origin.x, navRect.origin.y, navRect.size.width, 44);
}

- 调整导航栏中Title和Button的垂直位置


Title:

1
2
3
4
5
6
7
8
9
10
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController.navigationBar setTitleVerticalPositionAdjustment:-10.0 forBarMetrics:UIBarMetricsDefault];
//-10.0可以根据需要调节
}

- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.navigationController.navigationBar setTitleVerticalPositionAdjustment:0.0 forBarMetrics:UIBarMetricsDefault];
}

Button:

1
2
[self.barButtonItem setBackgroundVerticalPositionAdjustment:-10.0 forBarMetrics:UIBarMetricsDefault];
//-10.0可以根据需要调节

- 隐藏状态栏


1
2
3
- (BOOL)prefersStatusBarHidden {
return YES;
}

- UIScrollView不能缩放


需要实现代理方法- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView指定需要缩放的子控件

- 截取缩放过的UIImageView中的特定位置和大小的图片


1
2
3
4
5
6
7
8
9
10
- (UIImage *)imageWithZoomScale:(CGFloat)zoomScale {
UIGraphicsBeginImageContextWithOptions(self.imageView.bounds.size, NO, zoomScale);
[self.imageView drawViewHierarchyInRect:self.imageView.bounds afterScreenUpdates:YES];
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGRect imageRect = //...在这里指定位置和大小
CGImageRef sourceImageRef = [image CGImage];
CGImageRef targetImageRef = CGImageCreateWithImageInRect(sourceImageRef, imageRect);
return [UIImage imageWithCGImage:targetImageRef];
}

评论和共享

C语言复习问题总结

发布在 C语言

C语言复习问题总结


1.字段结构的成员的地址

改错题:

1
2
3
4
struct _half_byte {
unsigned short hb0: 4, hb1: 4, hb2: 4, hb3: 4;
} m;
scanf("%hu %hu %hu %hu", &m.hb0, &m.hb1, &m.hb2, &m.hb3);

这里需要注意到字段结构的成员是没有地址的,因此scanf("%hu %hu %hu %hu", &m.hb0, &m.hb1, &m.hb2, &m.hb3);是错误的,正确的代码可以类似:

1
2
3
unsigned short tmp[4];
scanf(“%hu %hu %hu %hu”, &tmp[0] , &tmp[1] , &tmp[2] , &tmp[3]);
m.hb0 = tmp[0], m.hb1 = tmp[1] , m.hb2 = tmp[2] , m.hb3 = tmp[3];

2.&&和||的编译器优化

如果开启了编译器优化,那么若&&的第一个条件为假或者||的第一个条件为真,那么编译器将不会去看&&或||的第二个条件,因此:

Declare int x = 0, y = 1; , which values of the following expressions are nonzero?

A. x++ + y--

B. y-x||x++, x

C. x*y&&y--, y

D. y-- ? y++ : y

这道题目的B和C为例,B中y-x已经为1,所以编译器将忽略x++,所以x仍然为0,所以B错误。而C中x*y为0所以编译器将忽略y–,所以y为1,C正确。

3.注意标识符和关键字的区别

例如:main是一个合法的标识符,而非关键字。

再例如:Case是一个合法的标识符,而非关键字。(注意C语言区分大小写)

4.词法分析

How many tokens are there in the statement of *p+++=12.L;?

A. 5

B. 6

C. 7

D. 10

记号共有5类:标识符、关键字、常量(含字符串常量)、运算符、标点符号。

*p+++=12.L;可以被分解为 * p ++ += 12.L ;共计6个记号,所以,答案为B。

5.转义序列

根据文档:

Escape sequences are used to represent certain special characters within string literals and character constants.

在C中可以由 \(反斜杠)+ 字符来进行转义。

6.类型转换

long x, y; x = -6L; y = 5UL; Which expression is equal to 1?

A. x<y && -6L<5UL

B. x<y && -6L>5UL

C. x>y && -6L<5UL

D. x>y && -6L>5UL

x,y的类型为long,因此5UL将会被转换为5L,所以x<y。而在进行比较运算的时候-6L会被提升至Unsigned Long,此时-6L>5UL,所以答案选B。

7.后缀自增自减运算符的计算延迟

后缀式++/–在遇到&& || ?: , 运算符后、或者完整表达式结束后自增/自减。

8.注意作用域、链接和存储时期

作用域描述程序中可以访问一个标识符的一个或多个区域;链接包括外部、内部和空链接,具有空链接的变量被代码块或函数原型所私有,外部链接的变量可以在多文件程序的任何地方使用,内部链接的变量可以在一个文件的任何地方使用;静态存储时期的变量将在程序执行期间一直存在,并且只能初始化一次。

具体可以参考C Primer Plus第十二章《存储类、链接和内存管理》或是课本。以下列出5个存储类的组合(来自C Primer Plus):
















































存储类 时期 作用域 链接 声明方式
自动 自动 代码块 代码块内
寄存器 自动 代码块 代码块内,使用关键字register
具有外部链接的静态 静态 文件 外部 所有函数之外
具有内部链接的静态 静态 文件 内部 所有函数之外,使用关键字static
空链接的静态 静态 代码块 代码块内,使用关键字static

In the following descriptions about the using of static, which ones are correct?

A. The static declaration can be used to variables and functions.

B. The external static declaration limits the scope of that object.

C. Internal static variables are local to a particular function just as auto variables are.

D. Internal static variables provide permanent storage and are initialized only once.

A正确,B external static具有内部链接,因此被限制了只能被当前文件引用,正确,C内部定义的静态变量具有代码块作用域,正确,D正确。

同时在另外一个文件中引用具有外部链接的变量时需要使用关键字 extern,因此,下面一道题选D。

Suppose that file_a.c and file_b.c can be compiled independently. and they share the following global variables

extern int x; char ch;

which are declared in file_a.c. The allowed global variables declared in file_b.c are

A、extern int x; char ch;

B、extern int x; extern char ch;

C、int x; char ch;

D、int x; extern char ch;

9.改错题注意悬挂指针

例如:

1
2
3
4
char *a[5];
int i = 0;
for (i=0; i<5; i++)
scanf("%s", a[i]);

10.Switch中的break

若switch中的case不加break,将会将该case后的所有语句全部执行完。

11.字段成员的内存分配

字段成员的内存分配是由低位到高位的。例如下面的题目,答案为C:

Suppose declared:

1
2
3
4
5
6
7
struct direction {
unsigned short int east:4,south:4,west:4,north:4; //east为最低位4,north为最高位1
};
union ud{
unsigned short int all;
struct direction d;
} a={0x1234};

the output of printf("%d\n",a.d.south); is

A、1

B、2

C、3

D、4

12.细心审题

C语言考试审题还是很重要的,稍微一不小心看错了一个字母,有可能题目就错了,务必仔细审题。

评论和共享

  • 第 1 页 共 1 页
作者的图片

码龙黑曜

iOS开发者/计算机科学/兽人控


华中科技大学 本科在读


Wuhan, China