精华内容
下载资源
问答
  • 哈夫曼编码字符串

    千次阅读 2018-09-11 15:32:08
    详细图解哈夫曼Huffman编码树 1 引言  哈夫曼(Huffman)编码算法是基于二叉树构建编码压缩结构的,它是数据压缩中...

    详细图解哈夫曼Huffman编码树

    1 引言

      哈夫曼(Huffman)编码算法是基于二叉树构建编码压缩结构的,它是数据压缩中经典的一种算法。算法根据文本字符出现的频率,重新对字符进行编码。因为为了缩短编码的长度,我们自然希望频率越高的词,编码越短,这样最终才能最大化压缩存储文本数据的空间。
      假设现在我们要对下面这句歌词“we will we will r u”进行压缩。我们可以想象,如果是使用ASCII码对这句话编码结果则为:119 101 32 119 105 108 108 32 119 101 32 119 105 108 108 32 114 32 117(十进制表示)。我们可以看出需要19个字节,也就是至少需要152位的内存空间去存储这些数据。
      很显然直接ASCII码编码是很浪费空间的,Unicode就更不用说了,下面我们先来统计一下这句话中每个字符出现的频率。如下表,按频率高低已排序:


    这里写图片描述

    2 哈夫曼二叉树构建

    2.1 初始队列

      那么我们按出现频率高低将其放入一个优先级队列中,从左到右依次为频率逐渐增加。


    这里写图片描述

      下面我们需要将这个队列转换成哈夫曼二叉树,哈夫曼二叉树是一颗带权重的二叉树,权重是由队列中每个字符出现的次数所决定的。并且哈夫曼二叉树始终保证权重越大的字符出现在越高的地方。

    2.2 第一步合并

      首先我们从左到右进行合并,依次构建二叉树。第一步取前两个字符u和r来构造初始二叉树,第一个字符作为左节点,第二个元素作为右节点,然后两个元素相加作为新空元素,并且两者权重相加作为新元素的权重。


    这里写图片描述

      同理,新元素可以和字符i再合并,如下:

    这里写图片描述

    2.3 重新调整队列

      上图新元素权重相加后结果是变大了,需要对权重进行重新排序。


    这里写图片描述

      然后再依次从左到右合并,每合并一次则进行一次队列重新排序调整。如下:

    这里写图片描述

      经过多步操作之后,得到以下的哈夫曼二叉树结构,也就是一个带有权重的二叉树:

    这里写图片描述

    2.4 哈夫曼编码

      有了上面带权重的二叉树之后,我们就可以进行编码了。我们把二叉树分支中左边的支路编码为0,右边分支表示为1,如下图:


    这里写图片描述

      这样依次遍历这颗二叉树就可以获取得到所有字符的编码了。例如:‘ ’的编码为10,‘l’的编码为00,‘u’的编码为11100等等。经过这个编码设置之后我们可以发现,出现频率越高的字符越会在上层,这样它的编码越短;出现频率越低的字符越会在下层,编码越短。经过这样的设计,最终整个文本存储空间才会最大化的缩减。
      最终我们可以得到下面这张编码表:

    这里写图片描述

    2.5 字符串编码

      有了上面的编码表之后,”we will we will r u”这句重新进行编码就可以得到很大的压缩,编码表示为:01 110 10 01 1111 00 00 10 01 110 10 01 1111 00 00 10 11101 10 11100。这样最终我们只需50位内存,比原ASCII码表示节约了2/3空间,效果还是很理想的。当然现实中不是简单这样表示的,还需要考虑很多问题。

    3 补充

      我们需要弄明白哈夫曼二叉树概念,它是带权路径达到最小的二叉树,也叫最优二叉树。它不一定是完全二叉树,也不一定是平衡二叉树,它们描述的完全不是一件事情,完全没有概念上的重叠关系。

    展开全文
  • 编码字符串,使得总长度最短

    千次阅读 2019-08-01 11:49:24
    字符串“liulishuo”,我们需要对该字符串每个字符编码,使得编码后的字符串总长度最小。 我们可以通过哈夫曼树来对字符编码,累积树中非叶子节点的和即为所求总长度。 总长度也等于词频1字符长度1+词频2字符长度2+...

    字符串“liulishuo”,我们需要对该字符串每个字符编码,使得编码后的字符串总长度最小。
    我们可以通过哈夫曼树来对字符编码,累积树中非叶子节点的和即为所求总长度。
    总长度也等于词频1字符长度1+词频2字符长度2+…

    /*
    liulishuo
    23
    
    对字符串编码,使得编码后的总长度最短;
    哈夫曼编码,总长度=字符长度1*频数1+字符长度2*频数2
    利用最小堆找最小元素
    */
    int MinLength(string str)
    {
    	// 统计词频
    	unordered_map<char, int> m;
    	for (char ch : str)
    	{
    		m[ch]++;
    	}
    
    	priority_queue<int,vector<int>,greater<int>> q;
    	unordered_map<char, int>::iterator it = m.begin();
    	int count = 0;
    	//通过词频构建优先队列
    	for (it; it != m.end(); it++)
    	{
    		q.push(it->second);
    		count++;
    	}
    	int res = 0;
    	//cout << count << endl;
    
    	// 总长度也可以通过累积哈夫曼树非叶子节点的和得到,其中非叶子节点数=字符数-1
    	while (count-->1)
    	{
    		int q1 = q.top();
    		q.pop();
    		int q2 = q.top();
    		q.pop();
    		q.push(q1 + q2);
    		//cout << q1 + q2 << endl;
    		res += q1 + q2;
    	}
    	return res;
    }
    

    参考:https://blog.csdn.net/u011391629/article/details/72971601

    展开全文
  • 字符串压缩编码

    2019-06-14 17:37:42
    参考文章: ... 自己编写的代码:` ... public class ...------还有一个输入的字符串不是按顺序的,想了一个办法:再和全部的比较完之后删除这个字符串(没时间写了) 如果有人写出来了,跟我讲一下哈。

    参考文章:https://www.cnblogs.com/liuzhuqing/p/7480443.html
    自己编写的代码:`
    package com.company;

    public class TestStringToReduce {

        public  static  String StringToReduce(String str){
            StringBuffer result = new StringBuffer();
            char c1 = str.charAt(0);
            int sum = 1;
    
            for (int i=1;i<str.length();i++){
                char c2 = str.charAt(i);
                    if (c2==c1){
                        sum = sum +1;
                        continue;
                    }
                    result.append(c1).append(sum);
                    c1 = c2;
                    sum = 1;
                }
              result.append(c1).append(sum);
            return result.toString();
        }
    
    public static void main(String[] args) {
    
       System.out.println(StringToReduce("aaaabbxvvv"));
    }
    

    }
    `关于 static修饰符何时使用:不需要NEW时加static,需要new后再调用不加static。

    ------还有一个输入的字符串不是按顺序的,想了一个办法:再和全部的比较完之后删除这个字符串(没时间写了)
    如果有人写出来了,跟我讲一下哈。

    展开全文
  • 最近学习韩顺平老师主讲的“图解java 数据结构与算法”的哈夫曼编码这一章节时,在编码实现上遇到了些许问题,本文主要记述一下问题及自己的解决方案,如有更优解还请指点

    最近学习韩顺平老师主讲的“图解java 数据结构与算法”的哈夫曼编码这一章节时,在编码实现上遇到了些许问题,本文主要记述一下问题及自己的解决方案,如有更优解还请指点。

    目录

    一、压缩的思路

    二、解压缩的思路

    三、代码实现遇到的问题

    四、解决方案

    五、代码


     

    一、压缩的思路

    1. 将数据先转换成byte数组;
    2. 在对该数组进行遍历,将每个byte元素转换成哈夫曼编码的字符串并拼接到StringBuilder中;
    3. 对哈夫曼编码进行遍历,每8位(也就是一个字节)转换成byte类型,最终转存为压缩后的byte数组。

     

    二、解压缩的思路

    1. 逐个遍历压缩后的byte数组的元素;
    2. 对每个元素(byte数值),先与256(1 0000 0000)进行按位或补齐高位,转换为二进制字符串后截取末8位得到哈夫曼编码字符串并拼接至StringBuilder;
    3. 解码,将哈夫曼编码表map进行反转,由“压缩前的byte数值为key,哈夫曼编码字符串为value”转为“哈夫曼编码字符串为key,压缩前的byte数值为value”,根据这个map将读取哈夫曼编码StringBuilder并还原为压缩前的byte数值。

     

    三、代码实现遇到的问题

    1. 需要压缩的数据经过哈夫曼编码得到的编码字符串在长度上不一定能被8整除,而在压缩存储时,每8个编码字符转换为1个byte的数据存入byte数组,通常情况下数组内最后一个元素都是长度不满8位的编码转换所得;
    2. 韩老师的代码中,对于长度为n的压缩数组,前n-1个元素按照解压缩思路中的第2步进行解码,而最后一个元素则是不补位、直接转为数值直接拼接到编码字符串;
    3. 但是在实际运行时存在问题:假设哈夫曼编码串末尾的编码为“001”,存到byte数组时的值为1,而在解压缩时由于是压缩后byte数组的最后一个元素,直接转为字符串编码“1”,显然这不是我们想要的“001”。在之后根据编码还原数据会造成编码失配,如下图所示

     

    四、解决方案

    矛盾所在就是如何处理对末尾不满8位的编码,自己想了一个笨办法:

    若哈夫曼编码的长度不能被8整除,则对于将未满8位的编码暂存到静态变量中,在解码还原时再添加至还原内容的末尾处(也可以记录末尾编码的长度,根据此长度对补位后的字符串进行截取)。运行结果如下:

     

    五、代码

    哈夫曼编码

    import java.util.*;
    
    /**
     * 哈夫曼编码
     */
    public class HuffmanCode {
    
        public static void main(String[] args) {
            // 字符串转为byte数组
            String content = "hey,do you like java as much as i like";
            System.out.printf("原始长度为 %d\n", content.length());
            byte[] bytes = content.getBytes();
            // 哈夫曼压缩
            byte[] huffmanCodes = huffmanCompress(bytes);
            // 哈夫曼解压缩
            byte[] decodeResult = decompress(codeTable, huffmanCodes);
            System.out.println(new String(decodeResult));
        }
    
    
        /**
         * 编码表
         */
        private static Map<Byte, String> codeTable;
    
        /**
         * 暂存可能不足一个字节的字符编码
         */
        private static String lastByte = "";
    
        /**
         * 将原始byte数组进行哈夫曼压缩
         *
         * @param bytes 原始数组
         * @return 经过哈夫曼压缩的byte数组
         */
        public static byte[] huffmanCompress(byte[] bytes) {
            // step1 根据序列构建哈夫曼树
            List<HuffmanTreeNode> nodeList = getNodes(bytes);
            HuffmanTreeNode root = HuffmanTree.createHuffTree(nodeList);
            // step2 获取哈夫曼编码表
            codeTable = HuffmanTree.getCodingTable(root);
            // step3 根据编码表压缩byte数组
            return transfer(bytes, codeTable);
        }
    
    
        /**
         * 将byte数组转为哈夫曼树结点的list
         *
         * @param bytes byte数组
         * @return 结点list
         */
        private static List<HuffmanTreeNode> getNodes(byte[] bytes) {
            // 字符与出现次数(即哈夫曼树的权)的映射
            Map<Byte, Integer> map = new HashMap<>(32);
            // 遍历bytes,将字符与其出现次数放入map
            for (byte b : bytes) {
                map.merge(b, 1, Integer::sum);
            }
    
            // 把map中的键值对转换成node加入到list中
            List<HuffmanTreeNode> nodeList = new ArrayList<>();
            for (Map.Entry<Byte, Integer> entry : map.entrySet()) {
                nodeList.add(new HuffmanTreeNode(entry.getKey(), entry.getValue()));
            }
            return nodeList;
        }
    
    
        /**
         * 将原始byte数组根据编码表转换为哈夫曼编码
         *
         * @param codeTable 编码表
         * @param origin    原始数组
         * @return 哈夫曼编码后的byte数组
         */
        private static byte[] transfer(byte[] origin, Map<Byte, String> codeTable) {
            System.out.println(Arrays.toString(origin));
            // 将原数组转换成Huffman编码字符
            StringBuilder huffmanStr = new StringBuilder();
            for (byte item : origin) {
                huffmanStr.append(codeTable.get(item));
            }
            // 压缩数组的长度
            int len = huffmanStr.length() / 8;
            if (huffmanStr.length() % 8 != 0) {
                // 编码长度不能被8整除,保存多余的不足8位的部分
                lastByte = huffmanStr.substring(len * 8);
            }
            System.out.printf("lastByte = %s\n", lastByte);
            // 压缩存储的byte数组
            byte[] huffmanCode = new byte[len];
            for (int i = 0; i < huffmanCode.length; i++) {
                huffmanCode[i] = (byte) Integer.parseInt(huffmanStr.substring(i * 8, i * 8 + 8), 2);
            }
            System.out.printf("压缩后的长度为 %d\n", "".equals(lastByte) ? len : len + 1);
            return huffmanCode;
        }
    
    
        /**
         * 封装解压缩的方法
         *
         * @param bytes 经过压缩的byte数组
         * @return 解压后的byte数组
         */
        public static byte[] decompress(byte[] bytes) {
            return decompress(codeTable, bytes);
        }
    
    
        /**
         * 将一个byte转为二进制字符串
         *
         * @param b 一个byte
         * @return b对应的二进制字符串(补码)
         */
        private static String byteToString(byte b) {
            // 使用int暂存b
            int temp = b;
            // 补高位,和256(1 0000 0000)进行按位或
            temp |= 256;
            String str = Integer.toBinaryString(temp);
            return str.substring(str.length() - 8);
        }
    
    
        /**
         * 对压缩数据进行解码
         *
         * @param codeTable   编码表
         * @param huffmanCode 压缩的数组
         * @return 原字符串对应的byte数组
         */
        private static byte[] decompress(Map<Byte, String> codeTable, byte[] huffmanCode) {
            System.out.println(Arrays.toString(huffmanCode));
            // 先得到压缩数组对应的编码字符串
            StringBuilder stringBuilder = new StringBuilder();
            for (byte value : huffmanCode) {
                stringBuilder.append(byteToString(value));
            }
            stringBuilder.append(lastByte);
            // 把字符串按编码表进行解码(先将编码表反转,根据编码找原数值)
            Map<String, Byte> map = new HashMap<>(32);
            for (Map.Entry<Byte, String> entry : codeTable.entrySet()) {
                map.put(entry.getValue(), entry.getKey());
            }
            // 扫描StringBuilder
            List<Byte> byteList = new ArrayList<>();
            /*
             * 此处i借助count这个增量来移动
             * 若在每一轮循环时i++会导致漏扫描字符
             */
            for (int i = 0; i < stringBuilder.length(); ) {
                int count = 1;
                Byte b;
                while (true) {
                    String str = stringBuilder.substring(i, i + count);
                    b = map.get(str);
                    if (b != null) {
                        byteList.add(b);
                        i += count;
                        break;
                    }
                    count++;
                }
            }
            // 将list赋值给array
            byte[] bytes = new byte[byteList.size()];
            for (int i = 0; i < bytes.length; i++) {
                bytes[i] = byteList.get(i);
            }
            return bytes;
        }
    }

    哈夫曼树

    import java.util.*;
    
    /**
     * 哈夫曼树
     */
    public class HuffmanTree {
    
        public static void main(String[] args) {
            int[] array = {13, 7, 8, 3, 29, 6, 1};
            // 获取哈夫曼树的根
            HuffmanTreeNode root = createHuffTree(arrToList(array));
            // 先序遍历此哈夫曼树
            preOrder(root);
        }
    
    
        /**
         * 权值数组转为哈夫曼树
         *
         * @param arr 权值的数组
         * @return 结点list
         */
        public static List<HuffmanTreeNode> arrToList(int[] arr) {
            List<HuffmanTreeNode> nodes = new ArrayList<>();
            for (int value : arr) {
                nodes.add(new HuffmanTreeNode(value));
            }
            return nodes;
        }
    
    
        /**
         * 创建哈夫曼树
         *
         * @param nodes 结点list
         * @return 创建的哈夫曼树的根
         */
        public static HuffmanTreeNode createHuffTree(List<HuffmanTreeNode> nodes) {
    
            /* 步骤如下:
             * (1)对序列进行排序(升序)
             * (2)从结点序列中取出头两个结点(权最小的两个)
             * (3)两个结点权相加作为新节点的权,新节点加入序列中
             * (4)重复(1)(2)(3)直至nodes中仅剩一个结点,即序列中的元素都已加入到哈夫曼树中
             */
            while (nodes.size() > 1) {
                // 排序(从小到大)
                Collections.sort(nodes);
    
                // 取出权最小的两个结点,权之和赋给新结点
                HuffmanTreeNode left = nodes.get(0);
                HuffmanTreeNode right = nodes.get(1);
                HuffmanTreeNode parent = new HuffmanTreeNode(left.getWeight() + right.getWeight());
                parent.setLeft(left);
                parent.setRight(right);
                // 将用到的两个子节点去除
                nodes.remove(left);
                nodes.remove(right);
                nodes.add(parent);
            }
    
            // 最后nodes中仅剩的结点即为哈夫曼树的根
            return nodes.get(0);
        }
    
    
        /**
         * 先序遍历
         *
         * @param root 根结点
         */
        public static void preOrder(HuffmanTreeNode root) {
            if (root == null) {
                System.out.println("树为空");
            } else {
                root.preOrder();
            }
        }
    
    
        /**
         * 字符与编码的映射
         */
        public static Map<Byte, String> codeMap = new HashMap<>(32);
    
    
        /**
         * 重载方法,根据根结点获取哈夫曼树的编码表
         *
         * @param root 根结点
         * @return 字符与编码的映射
         */
        public static Map<Byte, String> getCodingTable(HuffmanTreeNode root) {
            // 从根节点开始,递归遍历哈夫曼树,将叶子结点的哈夫曼编码存入映射
            getCodingTable(root, "", new StringBuilder());
            return codeMap;
        }
    
    
        /**
         * 获取节点的哈夫曼编码并存入映射
         *
         * @param node     当前结点
         * @param path     路径(向左 0;向右 1)
         * @param lastCode 父结点的编码
         */
        private static void getCodingTable(HuffmanTreeNode node, String path, StringBuilder lastCode) {
            if (node != null) {
                // 父结点的编码 + 路径 = 当前结点的哈夫曼编码
                StringBuilder curCode = new StringBuilder(lastCode);
                curCode.append(path);
                if (node.getData() == null) {
                    // 非叶子结点,向左向右递归
                    getCodingTable(node.getLeft(), "0", curCode);
                    getCodingTable(node.getRight(), "1", curCode);
                } else {
                    // 叶子结点,data域作为键,编码作为value存入映射,回溯
                    codeMap.put(node.getData(), curCode.toString());
                }
            }
        }
    }
    

    哈夫曼树结点

    /**
     * 哈夫曼树结点
     */
    public class HuffmanTreeNode implements Comparable<HuffmanTreeNode> {
    
        /**
         * 数据域
         */
        private Byte data;
    
        /**
         * 结点权值
         */
        private Integer weight;
    
        /**
         * 左子节点
         */
        private HuffmanTreeNode left;
    
        /**
         * 右子节点
         */
        private HuffmanTreeNode right;
    
        public Integer getWeight() {
            return weight;
        }
    
        public void setWeight(Integer weight) {
            this.weight = weight;
        }
    
        public HuffmanTreeNode getLeft() {
            return left;
        }
    
        public void setLeft(HuffmanTreeNode left) {
            this.left = left;
        }
    
        public HuffmanTreeNode getRight() {
            return right;
        }
    
        public void setRight(HuffmanTreeNode right) {
            this.right = right;
        }
    
        public Byte getData() {
            return data;
        }
    
        public void setData(Byte data) {
            this.data = data;
        }
    
        public HuffmanTreeNode(Integer value) {
            weight = value;
        }
    
        public HuffmanTreeNode(Byte data, Integer value) {
            this.weight = value;
            this.data = data;
        }
    
        @Override
        public String toString() {
            return "Node[" +
                    "data=" + (data == null ? null : (char) data.byteValue()) +
                    ", weight=" + weight +
                    ']';
        }
    
        /**
         * 重写Comparable接口,比较结点关键字的大小
         *
         * @param node
         * @descriptions:
         *   (1) 重写的compareTo关系到Collections.sort()如何排序
         *   (2) 若为【当前对象属性 - 传入对象属性】,则为升序
         *   (3) 若为【传入对象属性 - 当前对象属性】,则为降序
         * @return
         */
        @Override
        public int compareTo(HuffmanTreeNode node) {
            return this.weight - node.weight;
        }
    
    
        /**
         * 先序遍历
         */
        public void preOrder() {
            // 访问当前结点
            System.out.println(this.toString());
            // 遍历左子树
            if (this.getLeft() != null) {
                this.getLeft().preOrder();
            }
            // 遍历右子树
            if (this.getRight() != null) {
                this.getRight().preOrder();
            }
        }
    }
    

     

    展开全文
  • 什么是动态字符串,我们嘴边常挂的SDS就是动态字符串,在Redis里是一种数据编码方式,会用在Redis的String类型的数据对象里。 SDS的数据结构 SDS的数据结构如下,包含三部分属性,len、free以及buf数组,用来描述一...
  • 《C语言-哈夫曼编码实验报告》由会员分享,可在线阅读,更多相关《C语言-哈夫曼编码实验报告(18页珍藏版)》请在人人文库网上搜索。1、C语言-哈夫曼编码实验报告11课程:题目:专业:班级:座号:姓名:福建工程学院课程...
  • 字符串编码压缩

    千次阅读 2013-10-03 03:01:00
    因为字符串已经排序好了 AABBBCCCC,只需要比较str[i]与str[i+1],相邻的两个元素,用一个记数器,计到最后,再输出字符与相应的计数即可。具体感受从代码中体会。 #include #include void EncodeString...
  • 文章目录动态字符串(SDS)SDS的底层实现为什么不直接使用C字符串效率差异缓冲区溢出空间预分配策略与惰性空间释放策略二进制安全兼容部分C字符串函数总结 动态字符串(SDS) Redis没有直接使用C语言传统的字符串...
  • redis的字符串底层数据结构是sds(simple dynamic string),即简单动态字符串,其结构体定义如下: struct sdshdr { // buf 中已占用空间的长度 int len; // buf 中剩余可用空间的长度 int free; // 数据...
  • 文章目录SDS简介SDS的内部存储结构C字符串的内部存储结构SDS和C字符串的区别总结 SDS简介 Redis是用C语言写的,但是他的key竟然不是C字符串,这让我很惊讶。既然不是C字符串,那一定有一个数据类型吧,这个数据类型...
  • MySQL字符串函数

    2019-06-27 11:18:35
    MySQL字符串函数1、计算字符串字符数的函数、字符串长度的函数2、合并字符串函数3、替換字符串的函数4、字母大小写转换函数5、获取指定长度的字符串的函数6、填充字符串的函数7、删除空格的函数8、删除指定字符串的...
  • 给定一个字符串,判断其中的字符是否全部相同,不允许使用额外的数据结构,保证空间复杂度为O(1) 1. 实现 比较好的实现方式是利用一个辅助数据来记录每个字符是否出现,即使用位图进行标记。这里需要注意判断题目中...
  • 字符串函数主要用来处理数据库中的字符串数据,MySQL中字符串函数有:计算字符串长度函数、字符串合并函数、字符串替换函数、字符串比较函数、查找指定字符串位置函数等。 1.计算字符串字符数的函数和字符串长度...
  • } /*** * 编码解析 * @param str * @param codeTable * @return */ public static String addressing(String str, Map,String> codeTable){ Map,Character> reCodeTable = new HashMap(); Iterator it = codeTable....
  • 折腾Redis之字符串

    千次阅读 多人点赞 2020-06-27 00:00:48
    字符串是Redis五种基本数据类型中的基础。同时也是我们在学习编程中接触最多的一种数据类型。本文将从使用、源码、编码三个部分讲解此数据类型在Redis中的使用。 字符串       string...
  • postgresql 字符串函数

    千次阅读 2019-08-01 16:36:46
    字符串函数:postgresql中的字符串函数有:计算字符串长度函数、字符串合并函数、字符串替换函数、字符串比较函数、查找指定字符串位置函数等。 1、计算字符串字符数和字符串长度的函数:char_length(str)和...
  • 简单动态字符串

    2019-12-16 21:39:45
    简单动态字符串字符串Redis中的字符串SDS简介SDS VS C获取字符串的长度杜绝缓冲区溢出减少字符串修改带来的内存重分配次数二进制安全兼容部分C字符串函数总结 字符串 作为内存数据库,Redis对字符串的底层数据结构做...
  • PHP字符串编辑函数

    2018-07-29 22:42:41
    PHP字符串编辑函数
  • PostgreSQL字符串函数

    千次阅读 2018-12-28 16:10:12
    1.计算字符串字符数和字符串长度的函数 CHAR_LENGTH(str)返回值为字符串str所包含...LENGTH(str)返回值为字符串的字节长度,使用utf8编码字符集时,一个汉字是3字节,一个数字或字母算一字节。 select length('da...
  • 字符串编码(C#)

    千次阅读 2007-07-03 13:26:00
     System.Text.Encoding.Default 默认编码  Response.Write(  " 编码(GB2312): " +  strGB2312  + " "  );  Response.Write(  " 解码(GB2312): " +  DecodeGB2312  + " <p></p> "  );      ...
  • Redis深入浅出——字符串和SDS

    万次阅读 多人点赞 2018-08-15 13:02:59
    一、字符串 字符串的类信息定义 1.1 字符串介绍 字符串是Redis中最为常见的数据存储类型,其底层实现是简单动态字符串sds(simple dynamic string),是可以修改的字符串。 它类似于Java中的ArrayList,它采用预...
  • MySQL笔记四之 字符串函数 >1.计算字符串字符数的函数和字符串长度的函数 >2.合并字符串函数CONCAT(s1,s2,...)、CONCAT_WS(x,s1,s2,...) > 3.替换字符串的函数INSERT(s1,x,len,s2) > 4.字母大小转换函数 > 5.获取...
  • 字符串函数:postgresql中的字符串函数有:计算字符串长度函数、字符串合并函数、字符串替换函数、字符串比较函数、查找指定字符串位置函数等。1、计算字符串字符数和字符串长度的函数:char_length(str)和length...
  • 1)常数复杂度获取字符串长度:C语言获取一个字符串的长度需要遍历整个字符串时间复杂度为O(N),而SDS在属性len中记录了字符串长度,获取字符串长度的时间复杂度为O(1)。 2)杜绝缓冲区溢出:C字符串在执行拼接字符...
  • 将 Int 和 BigInt 类型数值转换为字符串的可逆方法,可用于缩短网址或记录的ID转换等。 如: 9223372036854775807 => aZl8N0y58M7 class Convert { /** * 默认密钥字符串 * @var string */ const KEY = '...
  • Redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组,以下简称C字符串),而是自己构建了一种名为简单动态字符串(simple dy namic string,SDS)的抽象类型,并将SDS用作Redis的默认字符串表示。...
  • 字符串处理

    千次阅读 2007-06-28 15:28:00
    在第7章已对Java的字符串处理做了简要的介绍。本章将对此做详细论述。像大多数其他计算机语言一样,Java中的字符串也是一连串的字符。但是与许多其他的计算机语言将字符串作为字符数组处理不同,Java将字符串作为...
  • redis_字符串对象

    2018-06-06 16:53:00
    Redis总共支持五种数据类型:string,hash,list,set及zset。这里介绍字符串类型的实现 首先了解字符串对象的结构 // redis对象内存分配,列出... // 字符串的底层编码,有三种:int、raw、embstr,后文介...
  • 背景 有时候爬虫爬过的url需要进行指纹核对,比如Scrapy就是进行指纹核对,如果是指纹重复则不再爬取。...根据Scrapy的指纹生成方式,这次的指纹生成方式也是用hash的MD5对目标URL进行加密,生成固定长度的字符串,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,398
精华内容 6,959
关键字:

编码缩短字符串