数据结构与算法总结——字符串算法

字符串排序

  • 低位优先

    • 从最右面开始排序,适合所有字符串长度一样的情况

    • 临时数组count大小为全部键的数量加1

      • 比如ASCII码全部键的数量为128
      • 加1是因为使用字符串某一位字符累加count数组时,不是累加对应的位置,而是加一位
        • 原因是当第二遍累加后,count数组的含义为以该字符为键的字符串第一次出现在原数组中的位置,这原本应该是前面的字符串数量加上一,又因为位置从0开始计数,所以就是前面字符串的数量
        • 因为计算公式为count[r] += count[r - 1],所以位置r应该是键r-1字符串的数量
    • 这是一种线性时间算法

      • 由于全部键数R一般远小于待排序字符串数N,因此总时间可以大约正比于WN
        • W为字符串宽度
    • 相关C++知识点

      • 临时数组初始化预留空间时必须使用resize而不是reserve,否则只是预留了空间而未初始化元素,只能使用insert或者push_back添加数组,不可使用下标
      • vector<string> 类型变量不可使用列表初始化,因为string不是const char*,只能先列表初始化string数组然后用迭代器初始化
      //错误
      vector<string> v;
      v.reserve(7);
      v[1] = "Smith";
      
      //正确
      vector<string> v;
      v.resize(7);
      v[1] = "Smith";
      
      //错误
      vector<string> v = {"armli", "jones", "smith", "white", "brown", "jacks", "ponie"};
      
      //正确
      string s[] = {"armli", "jones", "smith", "white", "brown", "jacks", "ponie"};
      vector<string> v(s, s + 7);
      
  • 高位优先

    • 这篇博客有十分详细的解释 https://blog.csdn.net/cook2eat/article/details/54353540
    • 稳定排序算法
    • 可用来排序 长度不一的字符串,且此时速度快于低位优先
    • 随机字符串为亚线性时间,最坏为线性时间
      • 当待排序的字符串们有较长的公共部分时,递归次数较多,同时要为count数组分配的额外空间也较多
      • 此时应该使用三相字符串快速排序
    • 递归编写
      • 低位优先无法用递归写,因为从右往左每一次迭代要排序的数据规模不变
      • 高位优先可以使用递归,因为高位的大小可以确定相对大小,所以每次迭代数据规模可以缩小
    • 由于字符串长度不一,要使用一个函数来替代下标操作符,使得大于该字符串长度的位返回-1,而不是报错
    • 同时临时数组要开RANGE + 2长度
    • 可以在子字符串小于一定长度时切换到插入排序
  • 三相字符串快速排序

    • 当存在许多相等的键或者相等前缀的时候,使用该方法比高位优先要快
      • 隐含的适用场景为键的取值范围较小时(此时容易出现等键)
      • 例如网址排序
    • 同时该方法还有一个优势就是不需要额外空间
    • 缺点在于不是稳定排序

在这里插入图片描述

字典树

  • 字典树共性
    • 每次查找命中所需要的时间与被查找的键长成正比
    • 查找未命中则只要检查几个字符
    • 用处
      • 搜索引擎的关键词自动补充
  • R向字典树
    • R叉树
      • R为字符集合中的字符数,例如ASCII码的R = 128
      • R越大则消耗的空间越大
    • 适用于键较小且字符集较小的情况
    • 树的形状与茶树顺序无关
  • 3向字典树
    • 3叉树
    • 与二叉搜索树一样,树的形状与插入字符串以及插入顺序有关
      • 适用于键的首字母分布均匀的情况
    • 使用的内存空间小于R向字典树,但是查找速度会慢一点

在这里插入图片描述

具体实现代码见:https://github.com/wuwentao1998/Data-Structures-and-Algorithms

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值