Xcode 4 关闭代码符号索引

随着工程不断变大,Xcode消耗的资源越来越多,主要是Xcode代码补全等功能需要对项目中所有的符号进行索引。在终端中运行下面的命令可以关闭索引功能,当然一些依赖它的功能也会受到影响。

defaults write com.apple.dt.XCode IDEIndexDisable 1

zziplib简单应用

在iPhone上实现了一个简单的http服务器,希望能够将html文档或图片等传到iPhone上以便随时查看。用户可以通过iTunes将文件传到应用沙盒的Documents下面,但iTunes传输只能传文件,无法传目录结构。于是想到将文件打包成zip文件传到沙盒里。本想zip文件应该用zlib就可以搞定的,结果Google了一番,好像不行。于是找到了这个zziplib,实现了根据访问路径自动从zip文件读取对应文件输出,下面是相关代码:

std::size_t second_slash_pos = request_path.find_first_of("/", 1);
if (second_slash_pos == std::string::npos) {
    printf("%s file not found\n",request_path.c_str());
    return;
}
std::string first_component_name = request_path.substr(0,second_slash_pos);
std::string zip_path = doc_root_ + first_component_name + ".zip";  //根据请求路径计算对应zip文件路径
ZZIP_DIR* dir = zzip_dir_open((char *)zip_path.c_str(),NULL);  //打开zip文件
if (dir) {
    std::string path = request_path.substr(second_slash_pos+1); //得到请求文件对应的zip文件里面的路径
    if (path == "") {
        path="index.html";
    }
    ZZIP_FILE* fp = zzip_file_open(dir,(char *)path.c_str(),NULL);  //打开请求的文件
    if (fp) {
        char buf[512];
        zzip_ssize_t len;
        while((len = zzip_file_read(fp,buf, 512))) {  //读取文件流到缓冲区
            rep.content.append(buf, len);  //将缓冲区内容添加到输出
        }
        zzip_file_close(fp);
    }else{
        zzip_dir_close(dir);
        printf("%s file not found\n",request_path.c_str());
        return;
    }
    zzip_dir_close(dir);
}else{
    printf("%s file not found\n",request_path.c_str());
    return;
}

此外,zzip还提供磁盘和内存盘映射的接口,以下代码使用内存盘映射实现相同的功能:

std::size_t second_slash_pos = request_path.find_first_of("/", 1);
if (second_slash_pos == std::string::npos) {
    printf("%s file not found\n",request_path.c_str());
    return;
}
std::string first_component_name = request_path.substr(0,second_slash_pos);
std::string zip_path = doc_root_ + first_component_name + ".zip";  //根据请求路径计算对应zip文件路径
ZZIP_MEM_DISK *disk = zzip_mem_disk_open((char *)zip_path.c_str());
if (disk) {
    std::string path = request_path.substr(second_slash_pos+1);
    if (path == "") {
        path="index.html";
    }
    ZZIP_DISK_FILE* fp = zzip_mem_disk_fopen(disk,(char *)path.c_str());
    if (fp) {
        char buf[512];
        zzip_ssize_t len;
        while((len = zzip_mem_disk_fread(buf, 1, 512,fp))) {
            rep.content.append(buf, len);
        }
        zzip_mem_disk_fclose(fp);
    }else{
        zzip_mem_disk_close(disk);
        printf("%s file not found\n",request_path.c_str());
        return;
    }
    zzip_mem_disk_close(disk);
}else{
    printf("%s file not found\n",request_path.c_str());
    return;
}

使用内存盘映射可以提高程序性能,但是需要消耗大量内存,在iPhone上不适用。

找零算法(2)

This entry is part 2 of 2 in the series 找零算法

找零算法(1)中,笔者给出了问题的思路和相应的实现代码,但是不能完整地解决问题。文中也提到了特例情况。本文将进一步解决此问题。
对于第一个问题,显然不能再用贪心法一次找到最优解,需要对找到的解进行测试是否刚好满足。这次笔者采用了与上篇文中第二个问题类似的算法,只是返回的值是硬币数量而不是方法数量。具体代码:

int a[]={50,20,10,5,2};
int minCountOfCoins(int n,int index){
    if(n==0) return 0;
    if (index==5) {
        return -1;    //无法找到正好满足的解
    }
    int num = a[index];    //当前计算的面值
    ++index;
    int count = n/num;     //当前面值最大数量
    int v = n%num;         //还剩下的无法用当前面值找开的钱数
    int result = 0;
    int i;
    for(i = 0;i<=count;++i){
        if((result=minCountOfCoins(v+num*i, index)) >= 0)
            break;
    }
    if (result<0) {       //没有满足的找零方式
        if (count==0) {   //没有更多的方式了
            return 0;
        }
        return -1;        //返回-1表示当前方式无法找到满足的找零方式,还可以继续测试其它方式
    }

    return result+count-i;   //返回钱的张数
}

第二个问题虽然也有问题,但无需大的改变,只需要调整一下边界检测条件。具体代码:

int a[]={50,20,10,5,2};
int kindOfMethod(int n, int index){
    if(n==0) return 1;
    if (index==5) {
        return 0;     //此方式不能满足条件
    }
    int num = a[index];
    ++index;
    int count = n/num;
    int v = n%num;
    int result = 0;
    int i;
    for(i = 0;i<=count;++i){
        result += kindOfMethod(v+num*i, index);
    }
    return result;
}

至此找零算法已经完成,对于钱币的找零不会有什么错误的地方了,但是对于一些更一般化的东西,假设存在1,2,6,7,10几种硬币,要找13个单位的零钱,按照这里的算法最少硬币数量的结果就会是3,而我们一眼就能看出应该是2。所以读者如果有兴趣,可以尝试更进一步解决此类问题。

找零算法(1)

This entry is part 1 of 2 in the series 找零算法

问题描述:现存在一堆面值为 V1、V2、V3 … 个单位的零钱,需要找出总值为N个单位的零钱。假设这一堆面值分别为 1、2、5、10、20 元,需要找出总值 N为 63 元的零钱。
1、求满足条件的最小硬币数量。
2、求有多少种找法满足条件。

对于第一个问题,最容易想到的是贪心解法:
要找N元钱,先拿N除最大零钱面值,取整就是所找的最大面值零钱的个数,取模得出余数重新赋给N。重复操作直到除最小面值结束。具体代码:

int a[]={20,10,5,2,1};
int minCountOfCoins(int n){
    int count = 0;
    int i;
    for (i=0; i<5; ++i) {
        count += n/a[i];
        n %= a[i];
    }
    return count;
}

对于第二个问题,可以采用动态规划
先对问题进行拆解,要用V1、V2、V3 ... Vn组成N可以拆解成
N/MAX(V)个最大面值的零钱 和 V1、V2、V3 ... Vn-1组成N%MAX(V)之和
上面只是一种拆解方法,其它的拆解方法可以是
N/MAX(V)-i个最大面值的零钱 和 V1、V2、V3 ... Vn-1组成N%MAX(V)+MAX(V)*i之和
当然现在是求方法数,所以结果就是这些拆解方法的数量,而每一个拆解方法又是由它的子问题的拆解方式算出。具体代码:

int a[]={20,10,5,2,1};
int kindOfMethod(int n, int index){
    if(index==4) return 1;
    if(n==0) return 1;
    int num = a[index];
    ++index;
    int count = n/num;
    int v = n%num;
    int result = 0;
    int i;
    for(i = 0;i<=count;++i){
        result += kindOfMethod(v+num*i, index);
    }
    return result;
}

上面的算法对于一些特殊情况会有问题,如零钱中只有2、5、10、20这几种面值,再要找出63元的零钱就有问题了。留作下次分析。