自创一个可逆的字符串长度压缩算法

最近在与友商做数据同步的过程中碰到一个问题:友商的某个字段(类似于uuid,不带中文)长度超过了对应的我们的字段的长度。

自己想出来LZW算法(其他算法压缩出来的长度可能更长),在我们这里并不需要每次都动态生成字符串映射表,只需要提前设定好一个表用于所有的压缩和解压缩过程就行,不过想了一下,这个表会比较庞大,也挺麻烦(陷入思考)…

如果能用一个字符来代表两个字符,那岂不直接能将长度减半?那么如何将两个或多个字符映射为一个字符呢?不妨先将多个字符映射为一个数字试试,然后将该数字转换为 char 字符。
在这里插入图片描述
如何将两个字符或多个字符转换为一个数字,并且可以可逆?(简单的将每个字符的ascii值相加当然行不通,不可逆)
使用二进制分区法则可以很好的唯一标识一串字符
在这里插入图片描述

假定每个字符的ascii码值不会超过 255,那么则可以让每个字符占 8 位,而后拼接起来转换为十进制就得到了唯一的一个数字。将这个流程反转即是逆转过程。最终转换为一个字符。

这个方法同样也可以应用于唯一标识一个IP地址。

压缩方法 Java 实现

public static String yasuo(String mnw) {
    StringBuilder sb = new StringBuilder();
    int index = 0;
    for (index = 1; index < mnw.length(); index += 2) {
        char c1 = mnw.charAt(index - 1);
        char c2 = mnw.charAt(index);
        sb.append((char) (((int) c1 << 8) + (int) c2));
    }
    if (index == mnw.length()) {
        sb.append(mnw.charAt(index - 1));
    }
    return sb.toString();
}

解码方法 Java 实现

public static String jem(String miw) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < miw.length(); i++) {
        int c = miw.charAt(i);
        String binaryString = Integer.toBinaryString(c);
        if (binaryString.length() < 8) {
            sb.append((char) c);
            continue;
        }
        int mnwi1 = Integer.parseInt(binaryString.substring(0, binaryString.length() - 8), 2);
        int mnwi2 = Integer.parseInt(binaryString.substring(binaryString.length() - 8), 2);
        sb.append((char) mnwi1);
        sb.append((char) mnwi2);
    }
    return sb.toString();
}

验证

public static void main(String[] args) {
    String mnw = "12j3jhk1s-12h3-12j3h712-as2h-23Oas";
    System.out.println("压缩前:" + mnw + ",长度: " + mnw.length());
    String miw = yasuo(mnw);
    System.out.println("压缩后:"+miw +",长度:"+ miw.length());
    String hy = jem(miw);
    System.out.println("还原后:"+hy +",长度:"+ hy.length());
}

在这里插入图片描述
验证好使,并且达到了压缩长度的方法。

缺点也很明显

1、压缩后的字符串几乎都为“火星文”,这要是存到库了,别人看了还可能以为是脏数据直接给你删掉了 -_-||
2、并不是对所有字符都能加密,ascii 码值超过一定值时可能会出错
3、java中char占16位,因此最多只能压缩一半的长度。不同语言可能会有所不同
4、不可多次压缩

当然,最后项目里并没有使用这个方法,因为这之后明确了这个字段不会再用于查询友商数据,只用于内部关联,所以就做了简单的字符串截取😄

### 删除字符串的第一个字符的方法 在不同的编程语言中,删除字符串的第一个字符可以通过多种方式实现。以下是几种常见的编程语言及其对应的解决方案。 #### JavaScript 实现 如果目标是在 JavaScript 中删除字符串的第一个字符(特别是当第一个字符为 `0` 或其他特定条件时),可以使用以下方法: ```javascript function removeFirstCharIfZero(str) { while (str.length > 0 && str.charAt(0) === '0') { // 判断首个字符是否为'0' str = str.substring(1); // 移除首个字符 } return str; } ``` 上述代码会持续移除字符串开头的所有 `'0'` 字符[^1]。如果只需要移除单个字符而无需判断其值,则可以直接调用 `substring(1)` 方法即可完成操作。 --- #### Python 实现 对于 Python 而言,由于字符串是不可变对象,因此无法直接修改原字符串的内容。然而,可以通过切片的方式轻松创建一个新的字符串副本并排除掉原始字符串中的第一个字符: ```python def remove_first_char(s): if not s: # 防止空字符串引发错误 return "" return s[1:] # 返回从第二个字符到结尾的部分 ``` 此函数首先验证输入是否为空;如果不为空则返回去掉首位之后的新子串[^2]。 另外需要注意的是,在实际应用过程中应当考虑边界情况——即传入参数可能是一个完全由零组成的数值形式的字符串或者根本就没有长度的情况下的处理逻辑设计合理性问题。 --- #### Java 实现 Java 提供了几种途径来判定以及消除字符串起始位置处指定类型的元素比如数字之类的信息。下面展示了一个简单的例子用来演示怎样做到这一点: ```java public class RemoveLeadingZerosExample { public static String trimLeadingZeros(String input){ int index=0; while(index<input.length()&&Character.isDigit(input.charAt(index))&&(input.charAt(index)=='0')){ ++index; } return input.substring(index); } public static void main(String[] args)throws Exception{ System.out.println(trimLeadingZeros("007Bond")); //"James" System.out.println(trimLeadingZeros("000abc"));//"abc" System.out.println(trimLeadingZeros("xyz")) ;//"xyz" } } ``` 这里定义了一个名为 `trimLeadingZeros()` 的静态方法接受一个字符串作为参数,并循环检查每一个字母直到遇到非数位为止才停止进一步前进再利用 substring 函数提取剩余部分形成最终结果输出给用户查看[^3]. --- ### 总结 每种语言都有各自特色鲜明的操作手段去达成相同目的—那就是有效率又简洁明了地除去目标字串最前端那个不需要保留下来的成分。无论是借助内置库还是自创算法思路都值得我们深入探索学习以便日后能够更加灵活运用它们解决更多复杂场景下提出的挑战需求。
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值