参考资料:
• Apple: Coding Guidelines for Cocoa
• Google: Objective-C Style Guide
• Three20: Source code style guildelines
正文:
• 格式化代码
◦ 指针“*”号的位置
▪ 如:NSString *varName;
◦ 空格 VS tabs
▪ 只允许使用空格,将编辑器设置为1个TAB = 2个字符缩进
◦ 每行的长度
▪ 每行最多不得超过100个字符
▪ 以15寸Macbook Pro的大小,每行100个字符时能最大化地同时容下编辑器和iPhone模拟器
▪ Google的80字符的标准有点少,这导致过于频繁的换行(Objectve-C的代码一般都很长)
▪ 通过 “Xcode => Preferences => TextEditing => 勾选Show Page Guide / 输入
100 => OK” 来设置提醒◦ 方法的声明和定义
▪ 在 - OR + 和返回值之间留1个空格,方法名和第一个参数间不留空格。如:- (void)doSomethingWithString:(NSString *)theString {
...}
▪ 当参数过长时,每个参数占用一行,以冒号对齐。如:- (void)doSomethingWith:(GTMFoo *)theFoo
rect:(NSRect)theRect
interval:(float)theInterval {
...}
▪ 如果方法名比参数名短,每个参数占用一行,至少缩进4个字符,且为垂直对齐(而非使用冒号对齐)。如:
- (void)short:(GTMFoo *)theFoo
longKeyword:(NSRect)theRect
evenLongerKeyword:(float)theInterval {
...
}
◦ 方法的调用
▪ 调用方法沿用声明方法的习惯。例外:如果给定源文件已经遵从某种习惯,继续遵从那种习惯。
▪ 所有参数应在同一行中,或者每个参数占用一行且使用冒号对齐。如:
[myObject doFooWith:arg1 name:arg2 error:arg3];
或
[myObject doFooWith:arg1
name:arg2
error:arg3];
▪ 和方法的声明一样,如果无法使用冒号对齐时,每个参数一行、缩进4个字符、垂直对其(而非使用冒号对齐)。如:
[myObj short:arg1
longKeyword:arg2
evenLongerKeyword:arg3];
◦ @public 和 @private
▪ @public 和 @private使用单独一行,且缩进1个字符
◦ Protocals
▪ 类型标示符、代理名称、尖括号间不留空格。
▪ 该规则同样适用于:类声明、实例变量和方法声明。如:
@interface MyProtocoledClass : NSObject<NSWindowDelegate> {
@private
id<MyFancyDelegate> _delegate;
}
- (void)setDelegate:(id<MyFancyDelegate>)aDelegate;
@end
▪ 如果类声明中包含多个protocal,每个protocal占用一行,缩进2个字符。如:@interface CustomViewController : ViewController<
AbcDelegate,
DefDelegate>{
...}
•命名
◦ 类名
▪ 类名(及其category name 和 protocal name)的首字母大写,写使用首字母大写的形式分割单词
▪ 在面向特定应用的代码中,类名应尽量避免使用前缀,每个类都使用相同的前缀影响可读性。
▪ 在面向多应用的代码中,推荐使用前缀。如:GTMSendMessage◦ Category Name
▪ 待完善◦ 方法名
▪ 方法名的首字母小写,且使用首字母大写的形式分割单词。方法的参数使用相同的规则。
▪ 方法名+参数应尽量读起来像一句话(如:)。在这里查看苹果对方法命名的规范。
▪ getter的方法名和变量名应相同。不允许使用“get”前缀。如:
- (id) getDelegate; // 禁止
- (id)delegate; // 对头
▪ 本规则仅针对Objective-C代码,C++代码使用C++的习惯
◦ 变量名
▪ 变量名应使用容易意会的应用全称,且首字母小写,且使用首字母大写的形式分割单词
▪ 成员变量使用“_”作为前缀(如:“NSString *_varName;”。虽然这与苹果的标准(使
用“_”作为后缀)相冲突,但基于以下原因,仍使用“_”作为前缀。
▪ 使用“_”作为前缀,更容易在有代码自动补全功能的IDE中区分“属性
(self.userInfo)”和“成员变量(_userInfo)”
▪ 常量(#define, enums, const等)使用小写“k”作为前缀,首字母大写来分割单词。如:
kInvalidHandle
•注释
◦ 待完善
• Cocoa 和 Objective-C特有的规则
成员变量使用@private。如:
@interface MyClass : NSObject {
@private
id _myInstanceVariable;
}
// public accessors, setter takes ownership
- (id)myInstanceVariable;
- (void)setMyInstanceVariable:(id)theVar;
@end
Indentify Designated Initializer▪ 待完善
Override Desingated Initializer
▪ 待完善◦ 初始化
▪ 在初始化方法中,不要将变量初始化为“0”或“nil”,那是多余的
▪ 内存中所有的新创建的对象(isa除外)都是0,所以不需要重复初始化为“0”或“nil”◦ 避免显式的调用+new方法
▪ 禁止直接调用NSObject的类方法+new,也不要在子类中重载它。使用alloc和init方法◦ 保持公共API的简洁性
▪ 待完善
◦ #import VS #include
▪ 使用#import引入Ojbective-C和Ojbective-C++头文件,使用#include引入C和C++头文件
◦ import根框架(root frameworks),而非各单个文件
▪ 虽然有时我们仅需要框架(如Cocoa 或 Foundation)的某几个头文件,但引入根文件编译
器会运行的更快。因为根框架(root frameworks)一般会预编译,所以加载会更快。再次强调:使用 #import 而非 #include 来引入Objective-C框架。如:
#import <Foundation/NSArray.h> // 禁止
#import <Foundation/NSString.h>
...
#import <Foundation/Foundation.h> // 对头◦ 创建对象时尽量使用autorelease
▪ 创建临时对象时,尽量同时在同一行中 autorelease 掉,而非使用单独的 release 语句
▪ 虽然这样会稍微有点慢,但这样可以阻止因为提前 return 或其他意外情况导致的内存泄露。
通盘来看这是值得的。如:
// 避免这样使用(除非有性能的考虑)
MyController* controller = [[MyController alloc] init];
// ... 这里的代码可能会提前return ...
[controller release];
// 这样更好
MyController* controller = [[[MyController alloc] init] autorelease];
◦ 先autorelease,再retain
▪ 在为对象赋值时,遵从“先autorelease,再retain”
▪ 在将一个新创建的对象赋给变量时,要先将旧对象release掉,否则会内存泄露。市面上有很
多方法来handle这种情况,这里选择“先autorelease,再retain”的方法,这种方法不易引入error。注意:在循环中这种方法会“填满”autorelease pool,稍稍影响效率,但是Google和我( )认为这个代价是可以接受的。如:
- (void)setFoo:(GMFoo *)aFoo {
[foo_ autorelease]; // 如果foo_和aFoo是同一个对象(foo_ == aFoo),dealloc不会被调用
foo_ = [aFoo retain];
}
◦ dealloc的顺序要与变量声明的顺序相同
▪ 这有利于review代码
▪ 如果dealloc中调用其他方法来release变量,将被release的变量以注释的形式标注清楚
◦ NSString的属性的setter使用“copy”
▪ 禁止使用retain,以防止意外的修改了NSString变量的值。如:
- (void)setFoo:(NSString *)aFoo {
[foo_ autorelease];
foo_ = [aFoo copy];
}
或
@property (nonatomic, copy) NSString *aString;
◦ 避免抛出异常(Throwing Exceptions)▪ 待完善
◦ 对 nil 的检查
▪ 仅在有业务逻辑需求时检查nil,而非为了防止崩溃
▪ 向 nil 发送消息不会导致系统崩溃,Objective-C运行时负责处理。◦ BOOL陷阱
▪ 将int值转换为BOOL时应特别小心。避免直接和YES比较
▪ Objective-C中,BOOL被定义为unsigned char,这意味着除了 YES(1) 和NO(0)外它
还可以是其他值。禁止将int直接转换(cast or convert)为BOOL。
▪ 常见的错误包括:将数组的大小、指针值或位运算符的结果转换(cast or convert)为
BOOL,因为该BOOL值的结果取决于整型值的最后一位
▪ 将整型值转换为BOOL的方法:使用三元运算符返回YES / NO,或使用位运算符(&&,||,!)
▪ BOOL、_Bool和bool之间的转换是安全的,但是BOOL和Boolean间的转换不是安全的,所以
将Boolean看成整型值。
▪ 在Objective-C中,只允许使用BOOL
▪ 如:
// 禁止
- (BOOL)isBold {
return [self fontTraits] & NSFontBoldTrait;
}
- (BOOL)isValid {
return [self stringValue];
}
// 对头
- (BOOL)isBold {
return ([self fontTraits] & NSFontBoldTrait) ? YES : NO;
}
- (BOOL)isValid {
return [self stringValue] != nil;
}
- (BOOL)isEnabled {
return [self isValid] && [self isBold];
}
▪ 禁止直接将BOOL和YES/NO比较,如:// 禁止
BOOL great = [foo isGreat];
if (great == YES)
...
// 对头
BOOL great = [foo isGreat];if (great)
...
◦ 属性
▪ 命名:与去掉“_”前缀的成员变量相同,使用@synthesize将二者联系起来。如:
// abcd.h
@interface MyClass : NSObject {
@private
NSString *_name;
}
@property (copy, nonatomic) NSString *name;
@end
// abcd.m
@implementation MyClass
@synthesize name = _name;
@end
▪ 位置:属性的声明紧随成员变量块之后,中间空一行,无缩进。如上例所示▪ 严把权限:对不需要外部修改的属性使用readonly
▪ NSString使用copy而非retain
▪ CFType使用@dynamic, 禁止使用@synthesize
▪ 除非必须,使用nonatomic• Cocoa Pattern
◦ Delegate Pattern(委托)
▪ delegate对象使用assign,禁止使用retain。因为retain会导致循环索引导致内存泄露,
并且此类型的内存泄露无法被Instrument发现,极难调试
▪ 成员变量命名为_delegate,属性名为delegate
◦ Model/View/Controller▪ Model和View分离
▪ 不多解释
▪ Controller独立于View和Controller
▪ 不要在与view相关的类中添加过多的业务逻辑代码,这让代码的可重用性很差
▪ Controller负责业务逻辑代码,且Controller的代码与view尽量无关
▪ 使用@protocal 定义回调APIs,如果并非所有方法都是必须的,使用@optional标示
•其他
◦ init方法和dealloc方法是是最常用的方法,所以将他们放在类实现的开始位置◦ 使用空格将相同的变量、属性对齐,使用换行分组
《算法竞赛入门经典——训练指南》
基本信息
作者: 刘汝佳 陈锋 [作译者介绍]
丛书名: 算法艺术与信息学竞赛
出版社:清华大学出版社
ISBN:9787302291077
上架时间:2012-10-16
出版日期:2012 年10月
开本:16开
页码:1
版次:1-1
所属分类: 计算机 > 计算机科学理论与基础知识 > 计算理论 > 算法
更多关于 》》》《算法竞赛入门经典——训练指南》
内容简介
书籍
计算机书籍
《算法竞赛入门经典——训练指南》是《算法竞赛入门经典》的重要补充,旨在补充原书中没有涉及或者讲解得不够详细的内容,从而构建一个较完整的知识体系,并且用大量有针对性的题目,让抽象复杂的算法和数学具体化、实用化。
《算法竞赛入门经典——训练指南》共6章,分别为算法设计基础、数学基础、实用数据结构、几何问题、图论算法与模型和更多算法专题,全书通过近200道例题深入浅出地介绍了上述领域的各个知识点、经典思维方式以及程序实现的常见方法和技巧,并在章末和附录中给出了丰富的分类习题,供读者查漏补缺和强化学习效果。
《算法竞赛入门经典——训练指南》题目多选自近年来acm/icpc区域赛和总决赛真题,内容全面,信息量大,覆盖了常见算法竞赛中的大多数细分知识点。书中还给出了所有重要的经典算法的完整程序,以及重要例题的核心代码,既适合选手自学,也方便教练组织学习和训练。
目录
《算法竞赛入门经典——训练指南》
第1章 算法设计基础 1
1.1 思维的体操 1
1.2 问题求解常见策略 15
1.3 高效算法设计举例 39
1.4 动态规划专题 60
1.5 小结与习题 77
第2章 数学基础 103
2.1 基本计数方法 103
2.2 递推关系 109
2.3 数论 119
2.3.1 基本概念 119
2.3.2 模方程 126
2.4 组合游戏 132
2.5 概率与数学期望 139
2.6 置换及其应用 144
2.7 矩阵和线性方程组 151
2.8 数值方法简介 163
2.9 小结与习题 170
第3章 实用数据结构 186
3.1 基础数据结构回顾 186
3.1.1 抽象数据类型(adt) 186
3.1.2 优先队列 188
3.1.3 并查集 191
3.2 区间信息的维护与查询 194
3.2.1 二叉索引树(树状数组) 194
3.2.2 rmq问题 197
3.2.3 线段树(1):点修改 199
3.2.4 线段树(2):区间修改 202
3.3 字符串(1) 208
3.3.1 trie 208
3.3.2 kmp算法 211
3.3.3 aho-corasick自动机 214
3.4 字符串(2) 219
3.4.1 后缀数组 219
3.4.2 最长公共前缀(lcp) 222
3.4.3 基于哈希值的lcp算法 224
3.5 排序二叉树 227
3.5.1 基本概念 227
3.5.2 用treap实现名次树 230
3.5.3 用伸展树实现可分裂与合并的序列 239
3.6 小结与习题 244
第4章 几何问题 254
4.1 二维几何基础 254
4.1.1 基本运算 255
4.1.2 点和直线 256
4.1.3 多边形 258
4.1.4 例题选讲 259
4.1.5 二维几何小结 263
4.2 与圆和球有关的计算问题 264
4.2.1 圆的相关计算 264
4.2.2 球面相关问题 269
4.3 二维几何常用算法 270
4.3.1 点在多边形内判定 270
4.3.2 凸包 271
4.3.3 半平面交 276
4.3.4 平面区域 282
4.4 三维几何基础 286
4.4.1 三维点积 287
4.4.2 三维叉积 288
4.4.3 三维凸包 290
4.4.4 例题选讲 292
4.4.5 三维几何小结 295
4.5 小结与习题 296
第5章 图论算法与模型 307
5.1 基础题目选讲 307
5.2 深度优先遍历 310
5.2.1 无向图的割顶和桥 312
5.2.2 无向图的双连通分量 314
5.2.3 有向图的强连通分量 319
5.2.4 2-sat问题 323
5.3 最短路问题 327
5.3.1 再谈dijkstra算法 327
5.3.2 再谈bellman-ford算法 332
5.3.3 例题选讲 335
5.4 生成树相关问题 343
5.5 二分图匹配 347
5.5.1 二分图最大匹配 347
5.5.2 二分图最佳完美匹配 348
5.5.3 稳定婚姻问题 352
5.5.4 常见模型 355
5.6 网络流问题 357
5.6.1 最短增广路算法 358
5.6.2 最小费用最大流算法 363
5.6.3 建模与模型变换 365
5.6.4 例题选讲 368
5.7 小结与习题 372
第6章 更多算法专题 383
6.1 轮廓线动态规划 383
6.2 嵌套和分块数据结构 389
6.3 暴力法专题 395
6.3.1 路径寻找问题 395
6.3.2 对抗搜索 400
6.3.3 精确覆盖问题和dlx算法 406
6.4 几何专题 412
6.4.1 仿射变换与矩阵 412
6.4.2 离散化和扫描法 414
6.4.3 运动规划 423
6.5 数学专题 425
6.5.1 小专题集锦 425
6.5.2 快速傅里叶变换(fft) 428
6.5.3 线性规划 430
6.6 浅谈代码设计与静态查错 431
6.6.1 简单的bash 431
6.6.2 《仙剑奇侠传四》之最后的战役 440
6.7 小结与习题 447
附录a 训练指南:使用uva/la题库 481
a.1 uva在线比赛推荐 481
a.2 la套题(acm/icpc真题)推荐 482
a.3 uva在线比赛单题推荐 483
附录b java、c#和python语言简介 505
b.1 java 505
b.2 c# 507
b.3 python 509
本图书信息来源:中国互动出版网
我们建立一个Service:
package com.andy
import android.app.Service;//引入相关包
import android.content.BroadcastReceiver;//引入相关包
import android.content.Context;//引入相关包
import android.content.Intent;//引入相关包
import android.content.IntentFilter;//引入相关包
import android.os.IBinder;//引入相关包
//继承自Service的子类
public class MyService extends Service{
CommandReceiver cmdReceiver;
boolean flag;
@Override
public void onCreate() {//重写onCreate方法
flag = true;
cmdReceiver = new CommandReceiver();
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {//重写onBind方法
// TODO Auto-generated method stub
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {//重写onStartCommand方法
IntentFilter filter = new IntentFilter();//创建IntentFilter对象
filter.addAction("wyf.wpf.MyService");
registerReceiver(cmdReceiver, filter);//注册Broadcast Receiver
doJob();//调用方法启动线程
return super.onStartCommand(intent, flags, startId);
}
//方法:
public void doJob(){
new Thread(){
public void run(){
while(flag){
try{//睡眠一段时间
Thread.sleep(1000);
}
catch(Exception e){
e.printStackTrace();
}
Intent intent = new Intent();//创建Intent对象
intent.setAction("wyf.wpf.Sample_3_6");
intent.putExtra("data", Math.random());
sendBroadcast(intent);//发送广播
}
}
}.start();
}
private class CommandReceiver extends BroadcastReceiver{//继承自BroadcastReceiver的子类
@Override
public void onReceive(Context context, Intent intent) {//重写onReceive方法
int cmd = intent.getIntExtra("cmd", -1);//获取Extra信息
if(cmd == Sample_3_6.CMD_STOP_SERVICE){//如果发来的消息是停止服务
flag = false;//停止线程
stopSelf();//停止服务
}
}
}
@Override
public void onDestroy() {//重写onDestroy方法
this.unregisterReceiver(cmdReceiver);//取消注册的CommandReceiver
super.onDestroy();
}
}
建立一个activity
package com.andy;//声明包语句
import android.app.Activity;//引入相关包
import android.content.BroadcastReceiver;//引入相关包
import android.content.Context;//引入相关包
import android.content.Intent;//引入相关包
import android.content.IntentFilter;//引入相关包
import android.os.Bundle;//引入相关包
import android.view.View;//引入相关包
import android.view.View.OnClickListener;//引入相关包
import android.widget.Button;//引入相关包
import android.widget.TextView;//引入相关包
//继承自Activity的子类
public class Sample_3_6 extends Activity {
public static final int CMD_STOP_SERVICE = 0;
Button btnStart;//开始服务Button对象应用
Button btnStop;//停止服务Button对象应用
TextView tv;//TextView对象应用
DataReceiver dataReceiver;//BroadcastReceiver对象
@Override
public void onCreate(Bundle savedInstanceState) {//重写onCreate方法
super.onCreate(savedInstanceState);
setContentView(R.layout.main);//设置显示的屏幕
btnStart = (Button)findViewById(R.id.btnStart);
btnStop = (Button)findViewById(R.id.btnStop);
tv = (TextView)findViewById(R.id.tv);
btnStart.setOnClickListener(new OnClickListener() {//为按钮添加点击事件监听
@Override
public void onClick(View v) {//重写onClick方法
Intent myIntent = new Intent(Sample_3_6.this, wyf.wpf.MyService.class);
Sample_3_6.this.startService(myIntent);//发送Intent启动Service
}
});
btnStop.setOnClickListener(new OnClickListener() {//为按钮添加点击事件监听
@Override
public void onClick(View v) {//重写onClick方法
Intent myIntent = new Intent();//创建Intent对象
myIntent.setAction("wyf.wpf.MyService");
myIntent.putExtra("cmd", CMD_STOP_SERVICE);
sendBroadcast(myIntent);//发送广播
}
});
}
private class DataReceiver extends BroadcastReceiver{//继承自BroadcastReceiver的子类
@Override
public void onReceive(Context context, Intent intent) {//重写onReceive方法
double data = intent.getDoubleExtra("data", 0);
tv.setText("Service的数据为:"+data);
}
}
@Override
protected void onStart() {//重写onStart方法
dataReceiver = new DataReceiver();
IntentFilter filter = new IntentFilter();//创建IntentFilter对象
filter.addAction("wyf.wpf.Sample_3_6");
registerReceiver(dataReceiver, filter);//注册Broadcast Receiver
super.onStart();
}
@Override
protected void onStop() {//重写onStop方法
unregisterReceiver(dataReceiver);//取消注册Broadcast Receiver
super.onStop();
}
}