1

我有一个相当笼统的问题,我很抱歉它很长。它不仅与 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。这意味着我无法创建某种散列算法来确保简短版本的唯一性,这还不够,它必须有点像原始单词。现在我正在考虑替换0O等等。

我猜你有一种感觉,这更像是一个科学问题,而不是一个实施问题。实现的唯一重要方面是性能。我想有一个好的表现,所以我不必永远等待。

有没有人见过类似的东西?

我会从哪里开始寻找一种方法呢?

4

0 回答 0