【技术文档】《编程珠玑》Jon Bentley·第2章 啊哈!算法

前两天在阿里面试,面试官问我看过什么书?是否看过《编程之美》、《编程珠玑》?去年的这个时候接触过两本书,之所以说是接触过而不是看过,是因为当时看的是英文版,看了几页就没再坚持看下去,现在借了本中文版的《编程珠玑》,希望能利用找工作的这段时间好好看一看。


看了前两章,感觉这上面的算法不是很深奥,而是设的很巧妙。作者对于同一个问题,能从不同的角度、不同的深度去挖掘,比如这个问题:将一个n元数组向左移动i个位置。作者给出了五种解法,我用C++实现了其中的四种算法,四种算法的实现如下:


/* 方法一:将数组的前num项复制到一个临时数组b中,再将a中剩余元素左移num位,最后将b复制到a的后num位中 */

#include <iostream>
using namespace std;

int main()
{
    int a[10]={0,1,2,3,4,5,6,7,8,9};
    int num=3;

    int b[num];
    for(int i=0;i<num;i++)
        b[i]=a[i];
    for(int i=num;i<10;i++)
        a[i-num]=a[i];
    for(int i=0;i<num;i++)
        a[10-num+i]=b[i];
    
    for(int i=0;i<10;i++)
        cout<<a[i]<<" ";
    return 0;
}


/* 方法二:实现将数组元素左移一位,然后循环num次即可 */

#include <iostream>
using namespace std;

int main()
{
    int a[10]={0,1,2,3,4,5,6,7,8,9};
    int num=3;

    int count=num;
    while(count--)
    { //实现数组元素左移一位
        int t=a[0];
        for(int i=1;i<10;i++)
            a[i-1]=a[i];
        a[10-1]=t;
    }
    
    for(int i=0;i<10;i++)
        cout<<a[i]<<" ";
    return 0;
}



/* 方法三:将0,num,2*num,……作为一组,执行左移一位,对1,2,……,num-1组的元素做同样的处理 */

#include <iostream>
using namespace std;

int main()
{
    int a[10]={0,1,2,3,4,5,6,7,8,9};
    int num=3;
 
    for(int i=0;i<num;i++)
    {
        int t=a[i];
        int j;
        for(j=i+num;j<10;j+=num)
            a[j-num]=a[j];
        a[j-num]=t;
    }
    
    for(int i=0;i<10;i++)
        cout<<a[i]<<" ";
    return 0;
}


/* 方法四:我们将问题看做是把数组ab转换成ba,通过数学中的求逆运算,我们可以通过对ab几次求逆最终得到ba,求逆过程为:ab->a'b->a'b'->(a'b')'=ba */

#include <iostream>
using namespace std;

int main()
{//将数组a中第i项到j项进行倒置(求逆),即第i项与第j项互换,第i+1项与第j-1项互换,……
    int a[10]={0,1,2,3,4,5,6,7,8,9};
    int num=3;

    void reverse(int *a,int i,int j);
    reverse(a,0,num-1);
    reverse(a,num,10-1);
    reverse(a,0,10-1);
    
    for(int i=0;i<10;i++)
        cout<<a[i]<<" ";
    return 0;
}

void reverse(int *a,int i,int j)
{
    int t;
    while(i<j)
    {
        t=a[i];
        a[i]=a[j];
        a[j]=t;
        i++;
        j--;
    }
}

越好的算法,不是越高深的,而是使问题看起来更简单的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值