字符串
最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:
输入: ["flower","flow","flight"]
输出: "fl"
示例 2:
输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
分析:
青蛙每次只会跳1级或2级,则跳n级必定是所有的1级和2级之和
设f(0)=1
跳上1级只有1种跳法(0->1) => f(1)=1
跳上2级有2种跳法(0->1->2,0->2)=> f(2)=f(1)+f(0) => f(2)=2
跳上3级有3种跳法(0->1->2->3,0->1->3,0->2->3)=> f(3)=f(2)+f(1)
跳上4级有5种跳法(0->1->2->3->4,0->1->2->4,0->1->3->4,0->2->3->4,0->2->4)=> f(4)=f(3)+f(2)
...
跳上n级有:f(n)=f(n-1)+f(n-2)
结果是斐波那契数列
1 | int fibon(int n) { |
1 | void BubbleSort(int a[], int n) { |
Block:带有自动变量的匿名函数。
匿名函数:没有函数名的函数,一对{}包裹的内容是匿名函数的作用域。
自动变量:栈上声明的一个变量不是静态变量和全局变量,是不可以在这个栈内声明的匿名函数中使用的,但在Block中却可以。
1 | @interface NSObject <NSObject> { |
实际上是一个对象,这个对象管理了其需要处理的事件和消息.
macOS/iOS系统中,提供了两个这样的对象:NSRunLoop 和 CFRunLoopRef。
CFRunLoopRef 是在 CoreFoundation 框架内的,它提供了纯 C 函数的 API,所有这些 API 都是线程安全的(CFSpinlock/CFSpinUnlock)。
1 | struct __CFRunLoop { |
NSRunLoop 是基于 CFRunLoopRef 的封装,提供了面向对象的 API,但是这些 API 不是线程安全的。
CFRunLoopRef 的代码是开源的,你可以在这里 下载到整个 CoreFoundation 的源码来查看。
初学 Objective-C 时把[receiver message]当成简单的方法调用,而无视了“发送消息”这句话的深刻含义。其实[receiver message]会被编译器转化为:
1 | objc_msgSend(receiver, selector) |
如果消息含有参数,则为:
1 | objc_msgSend(receiver, selector, arg1, arg2, ...) |
如果消息的接收者能够找到对应的selector,那么就相当于直接执行了接收者这个对象的特定方法;否则,消息要么被转发,或是临时向接收者动态添加这个selector对应的实现内容,要么就干脆玩完崩溃掉。
现在可以看出[receiver message]真的不是一个简简单单的方法调用。因为这只是在编译阶段确定了要向接收者发送message这条消息,而receive将要如何响应这条消息,那就要看运行时发生的情况来决定了。
Objective-C 的 Runtime 铸就了它动态语言的特性,这些深层次的知识虽然平时写代码用的少一些,但是却是每个 Objective-C程序员需要了解的。