精华内容
下载资源
问答
  • 大话数据结构

    2019-01-10 16:35:22
    项目经理看完代码后拍着桌子对他说:“你数据结构是怎么学的?” 1.3数据结构起源 4 1.4基本概念和术语 5 正所谓“巧妇难为无米之炊”,再强大的计算机,也要有“米”下锅才可以干活,否则就是一堆破铜烂铁。这个...
  • golang Map和指针优化

    2019-12-19 16:27:19
    小编不啰嗦,直接上代码: 执行结果: 这里的内存分配容量和次数都为0,因为此次定义的数据量较小,...原因:值传递,传入过去会分配两个内存空间意思是内存会分配两个容量存储。 而直接使用指针的话,可以直接...

    小编不啰嗦,直接上代码:
    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    这里的内存分配容量和次数都为0,因为此次定义的数据量较小,直接忽略不计。

    结果:带指针的结构明显执行速度比值传递快。
    为什么会发生这样的情况呢,而且在我以前的文章中也能找到,频繁的带入指针,
    还会影响到Gc回收,造成压力,那么在此处,为何性能快了这么多。

    原因:值传递,传入过去会分配两个内存空间,意思是内存会分配两个容量存储。
    而直接使用指针的话,可以直接指向之前的地址,而无需分配内存了,这样能极大地加快效率。
    这个时候就需要区分定义:
    go自带类型,使用值传递,不为不必要的性能去造成gc压力。
    自定义类型,使用指针,尤其是大型结构。

    初始化提示。
    在使用make等允许初始化容量的话,建议根据这个容量的大小,直接对应分配具体的大小,这样可以减少内存分配,而且数组等一些类型都是以double形式进行新增内存容量的,这个时候,这样的操作就非常有必要了。
    这个初始化也做了实现,自己去做吧,我就不提供代码了。
    有不解之处,或者有建议的话,可以详细交流。

    展开全文
  • 大话数据结构 程杰

    2018-09-01 10:06:43
    项目经理看完代码后拍着桌子对他说:“你数据结构是怎么学的?” 1.3数据结构起源 4 1.4基本概念和术语 5 正所谓“巧妇难为无米之炊”,再强大的计算机,也要有“米”下锅才可以干活,否则就是一堆破铜烂铁。这个...
  • 项目经理看完代码后拍着桌子对他说:“你数据结构是怎么学的?” 1.3数据结构起源 4 1.4基本概念和术语 5 正所谓“巧妇难为无米之炊”,再强大的计算机,也要有“米”下锅才可以干活,否则就是一堆破铜烂铁。这个...
  • 大话数据结构-程杰

    2014-07-13 23:45:52
    项目经理看完代码后拍着桌子对他说:"你数据结构是怎么学的?" 1.3 数据结构起源 4 1.4 基本概念和术语 5 正所谓"巧妇难为无米之炊",再强大的计算机,也要有"米"下锅才可以干活,否则就是一堆破铜烂铁。这个"米...
  • 项目经理看完代码后拍着桌子对他说:"你数据结构是怎么学的?" 1.3 数据结构起源 4 1.4 基本概念和术语 5 正所谓"巧妇难为无米之炊",再强大的计算机,也要有"米"下锅才可以干活,否则就是一堆破铜烂铁。这个...
  • 项目经理看完代码后拍着桌子对他说:“你数据结构是怎么学的?” 1.3数据结构起源 4 1.4基本概念和术语 5 正所谓“巧妇难为无米之炊”,再强大的计算机,也要有“米”下锅才可以干活,否则就是一堆破铜烂铁。这个...
  •  这很多人追求的目标,它的意思是,在Oracle数据库中,通过调整性能参数的值,就可以让数据库运转得飞快。  实际上这不过句玩笑,它本身一句反话,却让很多人误入歧途。我看到很多人,包括一些DBA,凡涉及...
  • 并利用具体的例子来全面介绍每个特性,不仅讨论了各个特性是什么,还说明了它是如何工作的,如何使用这个特性来开发软件,以及有关的常见陷阱。  本书面向所有oracle 数据库应用开发人员和dba。 作译者 作者  ...
  • 它的优点:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高,但是我们时间空间这两个东西可以相互优化的,什么意思呢,也就是说,你时间复杂度降低了,但是你却增加了...

    一、字典树概念:

    又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高,但是我们时间空间这两个东西可以相互优化的,什么意思呢,也就是说,你时间复杂度降低了,但是你却增加了内存消耗,也就是所说的空间换时间。

    二、字典树的优缺点

    优点

    1. 插入和查询的效率很高,均是O(m),其中 m 是待插入/查询的 字符串长度

      • 关于查询,有人会说hash表时间复杂度是O(1)不是更快?但是哈希搜索的效率取决于哈希函数的好坏,若一个坏的hash函数导致了很多冲突,效率不一定比Trie树高。
    2. Trie树中不同的关键字不会产生冲突。

    3. Trie树中只有在允许一个关键字关联多个值的情况下才有类似hash碰撞发生。

    4. Trie树不用求hash值,对短字符串有更快的速度。通常,求hash值也是需要遍历字符串的(与hash函数相关)

    5. Trie树可以对关键字 按照字典序排序 (先序遍历)。

      • 字典排序(lexicographical order)是一种对于随机变量形成序列的排序方法。其方法是,按照字母顺序,或者数字小大顺序,由小到大的形成序列。
    6. 每一颗Trie树都可以被看做一个简单版的确定有限状态的自动机(DFA,deterministic finite automation),也就是说,对于一个任意给定属于该自动机的状态(①)和一个属于该自动机字母表的字符(②),都可以根据给定的转移函数(③)转到下一个状态。其中:

      • ① 对于Trie树的每一个节点都确定一个自动机的状态。
      • ② 给定一个属于该自动机字母表的字符,在图中可以看到根据不同字符形成的分支;
      • ③ 从当前节点进入下一层次节点的过程进过状态转移函数得出。

      核心思想是:空间换时间,利用字符串的公共前缀来减少无谓的字符串比较以达到提高查询效率的目的。

    缺点

    1. 当hash函数很好时,Trie树的查找效率低于哈希搜索。

    2. 空间消耗大。
    给你一些单词inn、int、ate、age、adv、ant,现在你来建立一颗字典树。

    二、建立字典树步骤:

    1.定义指向根节点的指针P(建树过程实际上就是建立根节点)

    2.从字符串开始下标到结束(0-len)我们依次将字符做出节点。方法是:将字母s[i]由字典序化为数字id,当指针P指向的下一个next[id]为空时,将其单词计数初始化为0,从0-maxn初始化P指向的所有节点为NULL(一棵字典树很明显有很多棵子树),同时修改指针P指向next[id],如果要统计前缀,将计数节点++即可,如果统计单词,则是这个单词用来建完树之后计数节点再++,大概就是这样了,具体我们见代码。

    下面我们以HDU1521(统计前缀)为例
    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1251
    指针代码:(C++提交可以通过,G++MLE,听大佬们说是G++在申请指针内存的同时也会申请一个指针对应类型大小的内存,这样消耗内存可能就是原来的两倍了)

    #include<stdio.h>
    #include<iostream>
    using namespace std;
    const
    int
    maxn=26;
    struct
    Trie
    {

         int
    cnt=0;//计数(前缀或者单词)
         struct
    Trie *next[maxn];//指向各个子树的指针
         Trie
    ()//写成构造函数在new时候自动调用
         {

              cnt
    =0;
              for
    (int
    i=0;i<maxn;i++) next[i]=NULL;
         }
         ~
    Trie(){}//析构函数
    };

    Trie root
    ;//根节点
    void
    Insert(string s)
    {

         Trie
    *p=&root;//指向根节点的指针
         for
    (int
    i=0;i<s.size();i++)
         {

              int
    id=s[i]-'a';//将字母数字化
              if
    (
    p->next[id]==NULL)//如果之前没有指针指向这个字符,则为该字符所在节点分配内存
              {

                   p
    ->next[id]=new Trie;
              }

              p
    =p->next[id];修改指针p指向当前字符
              p
    ->cnt++;//统计前缀
         }
    //p->cnt++;统计单词
    }

    int
    Search(string s)
    {

         Trie
    *p=&root;
         for
    (int
    i=0;i<s.size();i++)
         {

              int
    id=s[i]-'a';
              if
    (
    p->next[id]==NULL) return 0;//如果没有该单词/该单词为前缀的单词,则表示没找到
              p
    =p->next[id];//修改指正继续往下找
         }

         return
    p->cnt;//返回统计单词/前缀的数量
    }

    int
    main()
    {

         char
    s[11];
         while
    (
    gets(s))
         {

              if
    (
    s[0]==NULL) break;//gets读入空行之后,自动转换为NULL
              Insert
    (s);
         }

         while
    (
    gets(s))
         {

              printf
    ("%d\n",Search(s));
         }

         return
    0;
    }

    数组代码:

    #include<bits/stdc++.h>
    using namespace std;
    const
    int
    maxn=1e6+5;
    int
    trie[maxn][26];//字符位置
    int
    num[maxn];//计数
    int
    pos=1;
    void
    Insert(string s)
    {

         int
    p=0;//节点位置
         for
    (int
    i=0;s[i];i++)
         {

              int
    id=s[i]-'a';
              if
    (
    trie[p][id]==0) trie[p][id]=pos++;//如过没有p到id的前缀,则为节点编号
              p
    =trie[p][id];//修改位置
              num
    [p]++;//前缀数量
         }
    //num[p]++;单词数量++
    }

    int
    Search(string s)
    {

         int
    p=0;
         for
    (int
    i=0;s[i];i++)
         {

              int
    id=s[i]-'a';
              if
    (
    trie[p][id]==0) return 0;//没有找到p到id的前缀
              p
    =trie[p][id];//继续向下找
         }

         return
    num[p];
    }

    int
    main()
    {

         char
    s[12];
         /*
         这里输入主要是判断空行,因为cin、scanf输入时候检测空格自动停止读取
         也可以用cin.getline(s,12)读入,然后看看s长度是否为0
         */

         while
    (
    gets(s))
         {

              if
    (
    s[0]==NULL) break;
              Insert
    (s);
         }

         while
    (
    gets(s)) printf("%d\n",Search(s));
         return
    0;
    }

    很明显数组模拟是优于指针写法的

    、字典树的优缺点

    优点

    1. 插入和查询的效率很高,均是O(m),其中 m 是待插入/查询的 字符串长度

      • 关于查询,有人会说hash表时间复杂度是O(1)不是更快?但是哈希搜索的效率取决于哈希函数的好坏,若一个坏的hash函数导致了很多冲突,效率不一定比Trie树高。
    2. Trie树中不同的关键字不会产生冲突。

    3. Trie树中只有在允许一个关键字关联多个值的情况下才有类似hash碰撞发生。

    4. Trie树不用求hash值,对短字符串有更快的速度。通常,求hash值也是需要遍历字符串的(与hash函数相关)

    5. Trie树可以对关键字 按照字典序排序 (先序遍历)。

      • 字典排序(lexicographical order)是一种对于随机变量形成序列的排序方法。其方法是,按照字母顺序,或者数字小大顺序,由小到大的形成序列。
    6. 每一颗Trie树都可以被看做一个简单版的确定有限状态的自动机(DFA,deterministic finite automation),也就是说,对于一个任意给定属于该自动机的状态(①)和一个属于该自动机字母表的字符(②),都可以根据给定的转移函数(③)转到下一个状态。其中:

      • ① 对于Trie树的每一个节点都确定一个自动机的状态。
      • ② 给定一个属于该自动机字母表的字符,在图中可以看到根据不同字符形成的分支;
      • ③ 从当前节点进入下一层次节点的过程进过状态转移函数得出。

      核心思想是:空间换时间,利用字符串的公共前缀来减少无谓的字符串比较以达到提高查询效率的目的。

    缺点

    1. 当hash函数很好时,Trie树的查找效率低于哈希搜索。

    2. 空间消耗大。

    、Trie树的应用

    1. 字符串检索

      检索、查询功能是Trie树最原始功能,思路就是从根节点开始一个一个字符进行比较。

      • 如果沿路比较,发现不同的字符,则表示该字符串在集合中不存在。

      • 如果所有的字符全部比较并且完全相同,还需要判断最后一个节点标识位(标记该节点是否为一个关键字)。

    2. 词频统计
      Trie树常被搜索引擎用于文本词频统计。

      思路:为了实现词频统计,我们修改了节点结构,用一个整型变量count来计数。对每一个关键字执行插入操作,若已存在,计数加1,若不存在,插入后count置 1。
      (1. 2. 都可以用hash table做)

    3. 字符串排序
      Trie树可以对大量字符串按字典序进行排序,思路也很简单:遍历一次所有关键字,将它们全部插入trie树,树的每个结点的所有儿子很显然地按照字母表排序,然后先序遍历输出Trie树中所有关键字即可。

    4. 前缀匹配
      例如:找出一个字符串集合中所有以ab开头的字符串。我们只需要用所有字符串构造一个trie树,然后输出以a->b->开头的路径上的关键字即可。 trie树前缀匹配常用于搜索提示。如当输入一个网址,可以自动搜索出可能的选择。当没有完全匹配的搜索结果,可以返回前缀最相似的可能。

    5. 作为辅助结构
      如后缀树,AC自动机
      有穷自动机 参考资料:http://blog.csdn.net/yukuninfoaxiom/article/details/6057736

    6. 与哈希表相比
      优点:

      • trie数据查找与不完美哈希表(链表实现)在最坏情况下更快;对于trie树,最差为O(m),m为查找字符串的长度;对于不完美哈希表,会有键值冲突(不同键哈希相同),最坏为O(N),N为全部字符产生的个数。典型情况是O(m)用于哈希计算,O(1)用于数据查找。

      • trie中不同键没有冲突

      • trie的桶与哈希表用于存储键冲突的桶类似,仅在单个键与多个值关联时需要

      • 当更多的键加入到trie中,无需提供hash方法或改变hash方法

      • trie通过键为条目提供字母顺序
        缺点:

      • trie数据查找在某些情况下(磁盘或随机访问时间远远高于主存)比哈希表慢

      • 当键值为某些类型(如浮点型),前缀链很长且前缀不是特别有意义。

      • 一些trie会比hash表更消耗内存。对于trie,每个字符串的每个字符都要分配内存;对于大多数hash,只需要为整个条目分配一块内存。

    7. 与二叉搜索树相比

      二叉搜索树,又称二叉排序树,它满足:

      • 任意节点如果左子树不为空,左子树所有节点的值都小于根节点的值;

      • 任意节点如果右子树不为空,右子树所有节点的值都大于根节点的值;

      • 左右子树也都是二叉搜索树;

      • 所有节点的值都不相同。

      其实二叉搜索树的优势已经在与查找、插入的时间复杂度上了,通常只有O(log n),很多集合都是通过它来实现的。在进行插入的时候,实质上是给树添加新的叶子节点,避免了节点移动,搜索、插入和删除的复杂度等于树的高度,属于O(log n),最坏情况下整棵树所有的节点都只有一个子节点,完全变成一个线性表,复杂度是O(n)。

      Trie树在最坏情况下查找要快过二叉搜索树,如果搜索字符串长度用m来表示的话,它只有O(m),通常情况(树的节点个数要远大于搜索字符串的长度)下要远小于O(n)。

    1. 后面部分摘自:https://blog.csdn.net/hihozoo/article/details/51248823

    展开全文
  • 面试的那些事(1)

    2012-02-16 09:45:00
    自己当时可能没有理解出什么意思,回答得不尽如意 上网查了查资料,发觉网上的答案众多,有点笼统.现总结一下. 1.建立相关聚合索引(查询字段用得较多) 2.在数据库上面X表的某时间字段上进行分文件,分区,优化数据库...

    前几日面试一家公司问到海量数据的问题.自己当时可能没有理解出什么意思,回答得不尽如意

    上网查了查资料,发觉网上的答案众多,有点笼统.现总结一下.

    1.建立相关聚合索引(查询字段用得较多)

    2.在数据库上面X表的某时间字段上进行分文件,分区,优化数据库结构

    3.至少也得具备常识性的数据库知道,如char比varchar查询快,char占用空间要varchar大(这个当然是以char没有填充满的情况)

    4.建立数据仓库(Data Warehouse),怎么建那可能要似数据库情况而定.

     

    列出相关文章:

    1.海量数据库解决方案2011050601

    转载于:https://www.cnblogs.com/kingkoo/archive/2012/02/16/2353605.html

    展开全文
  • 2.26 一些结构声明中的这些冒号和数字是什么意思? 2.27 为什么人们那么喜欢用显式的掩码和位操作而不直接声明位域? 第3章 表达式 求值顺序 3.1 为什么这样的代码不行?a[i]=i++; 3.2 使用我的编译器,下面的...
  • 4.1.5 用过哪些Map类,都有什么区别,HashMap是线程安全的吗,并发下使用的Map是什么,他们内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等。 4.1.6 JAVA8的ConcurrentHashMap为什么放弃了分段锁,有...
  • 2.26 一些结构声明中的这些冒号和数字是什么意思? 31 2.27 为什么人们那么喜欢用显式的掩码和位操作而不直接声明位域? 32 第3章 表达式 33 求值顺序 33 3.1 为什么这样的代码不行?a[i]= i++; 33 3.2 ...
  • 《你必须知道的495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    2.26 一些结构声明中的这些冒号和数字是什么意思? 31 2.27 为什么人们那么喜欢用显式的掩码和位操作而不直接声明位域? 32 第3章 表达式 33 求值顺序 33 3.1 为什么这样的代码不行?a[i]= i++; 33 3.2 ...
  • o 2.4 extern 在函数声明中是什么意思? o 2.5 关键字 auto 到底有什么用途? o 2.6 我似乎不能成功定义一个链表。我试过 typedef struct { char *item; NODEPTR next; } *NODEPTR; 但是编译器报了错误信息。难道...
  • 你必须知道的495个C语言问题(PDF)

    热门讨论 2009-09-15 10:25:47
    1.4 extern 在函数声明中是什么意思? . . . . . . . . . . . . . . . . . 2 1.5 关键字auto 到底有什么用途? . . . . . . . . . . . . . . . . . . . 2 1.6 我似乎不能成功定义一个链表。我试过typedef struct f ...
  • 27、GC是什么? 为什么要有GC?  GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象...
  • Teahouse WordPress主题

    2014-07-16 19:51:59
    12.因为考虑到文章的特色图较大,所以增加了利用自定义栏目的方式插入外链图片,节省空间之余还可以优化加载速度。这个和插入音乐外链同一做法,首先写文章时选择类型为“标准”,然后勾选“显示选项”里面的...
  • php高级开发教程说明

    2008-11-27 11:39:22
    什么意思?)在此处讨论中并不重要。重要的:形式分析的结果越好,逻辑分析就越容易、 越快、越好。 逻辑分析能补偿形式分析中失去的信息,但仅仅在一个有限的程度上补偿。 你也许能读懂前面的这个句子,但要...
  • 14.1 什么是事务 386 14.2 事务的ACID属性 387 14.3 事务隔离级别 388 14.4 多版本读一致性 390 14.5 事务控制语句 391 14.5.1 Commit(提交) 391 14.5.2 Savepoint(保存点) 391 14.5.3 Rollback(回滚) 391 ...
  • 写这个app研究了大量地Android源码,结构体系,弄了几天真的煞费苦心, 说实话对我这个大三狗的Android个人开发经验提升蛮大的。 另外本人还发现了Android一个有趣的漏洞,在自动解锁提到, 可以对这个漏洞进行一...
  • 14.1 什么是事务 386 14.2 事务的ACID属性 387 14.3 事务隔离级别 388 14.4 多版本读一致性 390 14.5 事务控制语句 391 14.5.1 Commit(提交) 391 14.5.2 Savepoint(保存点) 391 14.5.3 Rollback(回滚) 391 ...
  • c语言编写单片机技巧

    2009-04-19 12:15:17
    C语言一种结构化程序设计语言,它支持当前程序设计中广泛采用的由顶向下结构化程序设计技术。此外,C语言程序具有完善的模块程序结构,从而为软件开发中采用模块化程序设计方法提供了有力的保障。因此,使用C语言...
  • java 面试题 总结

    2009-09-16 08:45:34
    24、GC是什么? 为什么要有GC?  GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象...
  • 10.1 SQL是什么 10.2 在数据库中插入数据 10.3 从数据库中获取数据 10.3.1 获取满足特定条件的数据 10.3.2 从多个表中获取数据 10.3.3 以特定的顺序获取数据 10.3.4 分组与合计数据 10.3.5 选择要返回的行 ...
  • </li><li>这个项目带给你的成长是什么,当然别说让我学会了某某 API 这种没价值的内容。</li></ol> 另外项目这块还要结合着简历来说,因为面试官问你项目肯定是从简历上得来的问题,下文中会写到...
  • 会计理论考试题

    2012-03-07 21:04:40
    28.Windows98中的文件系统结构是___C__形状。 A、网状 B、层次 C、树形 D、链状 29.显示卡速度对Windows98的系统性能影响的因素有___A____。 A、Windows98的GUI特点 B、背景图案 C、屏幕保护程序 D、画笔 30.下列...

空空如也

空空如也

1 2
收藏数 31
精华内容 12
关键字:

优化空间结构是什么意思