美文网首页
数据结构随想(一)

数据结构随想(一)

作者: Cipolee | 来源:发表于2019-03-02 17:05 被阅读0次
                  #原创                
    

    之前老是对牛顿的“站在巨人肩膀上”有点误解,咱不否认牛顿在数学,物理上的才华与对人类的贡献,因为牛顿啥人品咱也都知道,误解他在所难免。现在发现杨绛先生的“你的问题主要在于读书不多而想得太多”愈发正确,书是人们智慧的载体,天才的存在使得书更有价值。多读书,站在巨人的肩膀上是有意义的,与其活在自己的世界里踽踽独行,不如包容的心态学习前人的经验。曾一直思考,其实岁月悠悠,哦,shit,大爷直接过来把自习室灯关了,我就一人还在这黑灯瞎火的抒情,咳咳,继续,说那儿了,,,,,(此处卡顿30s)哦,你思考的问题早有人为你思考过了,多看书是快速生长的一种方法,不用摸着石头过河了嘛!

    废话不多说,看题,非计算机学生慎看。

    编码工作常被运用于密文或压缩传输。这里我们用一种最简单的编码方式进行编码:把一些有规律的单词编成数宇。
    字母表中共有26个字母{a,b,…,z},这些特殊的单词长度不超过6且字母按升序排列。把所有这样的单词放在一起,按字典顺序排列,一个单词的编码就对应着它在字典中的位置。
    例如:
    a→1 b→2 z→26 ab→27 ac→28
    你的任务就是对于所给的单词,求出它的编码。
    输入输出格式
    输入格式:
    仅一行,被编码的单词。
    输出格式:
    仅一行,对应的编码。如果单词不在字母表中,输出0。
    输入样例 :ab 输出样例:27

    该题目来源于洛谷,洛谷平台未标注出题作者


    OK,进入正题,首先搞清升序与非递减的区别,即按字典序升序就保证了该编码制度下没有相同的字母。

    所以a->1,b->2,c->3, ,z->26,aa->27,ab->28, , ,ba->53是错误的,也就是说不能看成由a~z组成的26进制编码成10进制,对吧?

    Alright,发动你聪明的小脑瓜,抽象出该题背后的数据结构,想想它长什么样子了。

    那些对“数据结构”概念一脸迷茫的孩子,可以继续阅读,牛犇可以略过。

    数组结构的核心技术是分解和抽象。

    首先对数据进行分解和抽象,通过分解划分出数据的层次(数据-数据元素-数据项);再经过抽象,舍弃数据元素的具体内容,得到数据的逻辑结构。

    其次是处理的分解和抽象,通过分解将需求划分成各个功能;再经过抽象舍弃实现细节得到算法。

    好吧,我也不罗嗦了,你肯定想掌握数据结构最重要的东西吧。

    逻辑结构是你学数据结构必须掌握的,否则,嘿嘿嘿,你可能要叨念"Data structure fucks me"或者"Life sucks because of data structure "了。

    逻辑结构分为线性结构和非线性结构。

    线性结构元素之间的关系是一对一对的,如线性表,向量,栈(重要),队列(重要),优先队列,字典等。

    非线性结构可能是一对多,即树(真重要),多对多,即图(真重要)本人觉得数据结构的博大精深从这儿开始就体现出来了。

    /这是我的第一篇简书:-),还可以去gitee.com/cipolee/

    下面是我理解的该题背后的结构。

    理科男灵魂画师一个,不会画图,呜呜呜,,

    哎哎哎,对了,这才叫抽象嘛,嘿嘿嘿,逻辑结构要的就是抽象。

    image

    咳咳咳,前方高能。

    每种逻辑结构背后都有,查找,遍历,插入,建立,删除。如果继续抽象,遍历属于查找,建立属于插入。

    这个题不就是让你找到编码规律后为单词编码(第一步),存起来(第二步),然后给你个单词你往存起来的地方查找,找到你就能输出答案了,就这么easy。

    第一步,编码规律你已经知道,就是上面的树,可以用DFS把树的每一条枝子(路径)即一个单词搜索一遍得到编码结果。

    第二步,存起来,用什么存容易查找呢,还能代码容易实现,时间复杂度还低?

    ummm,如果你够懒你会说我啥也不想用,就想给我单词我就能把编码输出。对!你这个想法很聪明,这时你会发现你需要一个由单词到数字的映射。用map存!

    所有大的问题都解决,开始写代码,代码中出现的细节在代码里注释。

    
    #include<iostream>
    
    #include<map>
    
    using namespace std;
    
    map<string,int>M;//可以理解有一个M对象它从string字符串映射到一个整数及答案。
    
    int cnt=1;
    
    //cnt是计数器,初始a为1。
    
    string all,one;
    
    //all是为了给各个单词存编码而生成的所有种类的字符串(枚举的思想),而one是你要输入的字符串。
    
    void DFS(int length,int k)//length是单词长度,k深搜的层数
    
    {
    
    if(k>length)//深搜边界
    
    {
    
    M[all]=cnt++;
    
    return ;
    
    }
    
    char i,j;
    
    if(k==1)
    
    j='a';
    
    else
    
    j=all[k-2]+1;//k-2=k-1(回到上一层)-1(数组从0开始编号,找到上一个字母)+1(保证升序,大一个)
    
    for(i=j;i<='z';i++)
    
    {
    
    all[k-1]=i;
    
    DFS(len,k+1);
    
    //为什么它就能按深搜的那个过程走一遍,你看执行到边界return,就回溯到上一层,上一层按顺序往后执行,然
    
    //后依此类推
    
    }
    
    int main()
    
    {
    
    int n;//单词字母个数。
    
    for(n=1;n<=6;n++)
    
    {
    
    all.clear();
    
    all.resize(n);
    
    DFS(n,1);
    
    }
    
    cin>>one;
    
    cout<<M[one]<<endl;
    
    return 0;
    
    }
    

    其实仔细思考DFS(depth first search深度优先搜索)和BFS(breadth first search广度优先搜索),就会发现其中的哲学思想,一个是一下子走到底,不到黄河不死心,玩深度;一个是先把最近的先走一遍,再往下走,重广度。

    而栈,先进后出,队列,先进先出。这先进先出,先进后出所反映的思想在算法甚至在生活中也普遍存在。如果深度理解,你会发现DFS是栈的操作,BFS是队列的操作。

    是不是发现这几行代码比一篇网络小说的信息量大多了。

    新时代大学生,在每日巨大的信息冲击下,很难接受文艺的辞藻华丽的诗词,从接受信息获得快感的阈值越来越高,为此他们会浏览更多的信息,为此不浪费碎片的时间去看快手,抖音,在花花绿绿的信息流中接受须臾的感官刺激,垃圾信息害人太惨,代码中都是智慧的结晶,不仅包含的信息多,质量还高。

    多读书不愿意?多读代码就好了。

    image

    相关文章

      网友评论

          本文标题:数据结构随想(一)

          本文链接:https://www.haomeiwen.com/subject/ykcyuqtx.html