我有一个相当笼统的问题,我很抱歉它很长。它不仅与 MySQL 相关,而且可以用任何脚本语言完成,但我没有找到更好的方法来解释它。我有一个独特单词的列表。现在它们在 MySQL 的表中,但实现并不重要,它们也可以在文本文件中。每个单词正好是 6 个字符。单词遵循几种略有不同的格式。我的目标是将每个单词从 6 个字符缩短到 4 个字符,以保持唯一性。
我用谷歌搜索了这个主题,所有像数据最小化/优化/碰撞这样的东西都没有提供有用的结果:(所以我在这里。
这是它的外观示例:
--------------
words
--------------
word short
------ ----
1A0001
1A0002
1A0003
AA0001
AA1001
AB0001
2BAC11
2BAC34
--------------
如您所见,以下通用正则表达式可以表示三种格式:
^[0-9][A-Z][0-9][0-9][0-9][0-9]$ - matches 1A0001 1A0002 1A0003
^[A-Z][A-Z][0-9][0-9][0-9][0-9]$ - matches AA0001 AA1001 AB0001
^[0-9][A-Z][A-Z][A-Z][0-9][0-9]$ - matches 2BAC11 2BAC34
因此,根据格式,可以删除不同的字符以使单词长 4 个字符并保持它们的唯一性。
^[0-9][A-Z][0-9][0-9][0-9][0-9]$ - drop 1, 3
^[A-Z][A-Z][0-9][0-9][0-9][0-9]$ - drop 3, 4
^[0-9][A-Z][A-Z][A-Z][0-9][0-9]$ - drop 1, 4
我创建了short
使用值regexp/concat/substring
和一个临时表来更新words
. 正如我所说,实施对于解释来说并不重要。它几乎可以归结为:
select concat(substring(word,2,1), substring(word,4,3)) from words where word regexp '^[0-9][A-Z][0-9][0-9][0-9][0-9]$';
select concat(substring(word,1,3), substring(word,6,1)) from words where word regexp '^[A-Z][A-Z][0-9][0-9][0-9][0-9]$';
select concat(substring(word,2,2), substring(word,5,2)) from words where word regexp '^[0-9][A-Z][A-Z][A-Z][0-9][0-9]$';
这就是表格最终的样子:
--------------
words
--------------
word short
------ ----
1A0001 A001
1A0002 A002
1A0003 A003
AA0001 AA01
AA1001 AA11
AB0001 AB01
2BAC11 BA11
2BAC34 BA34
--------------
我可以验证short
使用的唯一性:
mysql> select short from words group by short having count(short) > 1;
Empty set (0.00 sec)
mysql>
这是一个非常简化的场景。实际上,单词更长,格式也更多。有时即使格式相同,删除相同的字符也会产生冲突,这意味着两个不同的字符会word
导致相同的字符,short
这是不可接受的。所以short
需要修改才能变得独一无二。最大的困难在于所有的内容word
实际上都是人类可以理解的,所以short
版本也应该是人类可以理解的,并且与原版相似word
。这意味着我无法创建某种散列算法来确保简短版本的唯一性,这还不够,它必须有点像原始单词。现在我正在考虑替换0
为O
等等。
我猜你有一种感觉,这更像是一个科学问题,而不是一个实施问题。实现的唯一重要方面是性能。我想有一个好的表现,所以我不必永远等待。
有没有人见过类似的东西?
我会从哪里开始寻找一种方法呢?