我的项目采用字符串s
并将全小写版本s.toLowerCase()
传递给无损编码器。
我可以很好地转换编码/解码小写字符串,但这显然不实用,所以我需要能够以某种方式保留原始字符串的大小写。
我在考虑使用Character.isUpperCase()
来获取一个整数数组UpperCaseLetters[]
,它表示s
中所有大写字母的位置。然后,我将使用此数组在编码字符串中的所有位置^
放置UpperCaseLettes[i] + 1
。解码字符串时,我会知道^
之前的每个字符都是大写字母。 (顺便说一句,这个编码器在编码时永远不会生成^
。
这个方法对我来说似乎很草率。我也在考虑使用位串来表示大写,但是应用程序的所有目标都是压缩,因此效率不高。
是否有更简单的方法来获取和应用字符串的capitlization蒙版?如果有,它需要多少“存储”?
答案 0 :(得分:1)
您的选择:
自动利用:强>
使用通用算法进行大小写,使用以下技术之一仅记录生成和实际大小写之间不同的字母。要重新生成,只需再次运行算法并翻转所有录制字母的大小写。假设存在应该存在的大写字母(例如句子的开头),这将使算法略微减慢(仅通过n的小常数因子,并且适当的压缩通常比这慢得多)并且总是减少存储量一些人需要的空间。
资本位置的位图:
你已经涵盖了这个,效率不高。
带有识别字符的前缀大写:
除了您描述了postfix之外,还已经涵盖了,但前缀通常更好,对于更通用的解决方案,您还可以使用^
转义^^
。不错的主意。根据压缩情况,最好使用已经出现在数据集中的字母。最常见或最不常见的字母,或者您可能必须查看压缩算法并进行相当多的处理以确定要使用的理想字母。
以任何格式存储资本的起始距离:
与下一个首都的距离没有优势(下图)。
与下一个大写的距离 - 非位串表示:
通常效率低于使用位串。
位字符串=到下一个大写的距离:
您有一系列长度,每个长度依次指示大写之间的距离。因此,如果我们有距离0,3,1,0,5
,则大小写将如下:AbcdEfGHijklmNo
(跳过0个字符到第一个,3个字符到第二个,1个字符到第3个,等等)。有一些选项可用于存储:
固定长度:不是一个好主意,因为它需要=尽可能长的距离。一个明显的替代方案是在下一个长度中出现某种溢出,但这仍然占用太多空间。
固定长度,不同的设置:最好用一个例子来解释 - 前4位表示长度,00
表示后面有2位表示距离, 01
表示4位,10
表示8位,11
表示16位,如果有可能超过16位,则可能需要执行类似的操作 - { {1}}表示16位,110
表示32位,1110
表示64位等(这听起来类似于确定IPv4地址的类)。因此,11110
会分为0001010100
- 00
,01
- 01
,因此距离为1,4。请注意,长度不必增加功率为2. 16位= 65535个字符很多,2位= 3很小,你可以把它变成4,6,8,(16?),(32?),??? (除非连续有几个大写,那么你可能也想要2位)。
使用转义序列的可变长度:假设转义序列为0100
,我们希望使用所有不包含00
的字符串,所以该位值表将如下所示:
00
Bits Value
1 1
10 2
11 3
101 4 // skipped 100
110 5
111 6
1010 7 // skipped 1000 and 1001
将分为10100101010010101000101000010
,101
,10101
,101010
,0,101
。请注意,10
只会导致左侧1的拆分结束和右侧1的拆分,...1001..
导致拆分结束于第一个0,拆分结束于右侧1,并且{ {1}}表示介于其间的0值距离。伪代码类似于:
...10001...
对于短距离来说,这看起来是一个很好的解决方案,但是一旦距离变大,我怀疑你开始跳过太多的值而且长度增加很快。
没有理想的解决方案,它在很大程度上取决于数据,你必须使用前缀大写和位串距离的不同选项,以查看哪个最适合您的典型数据集。