有沒有人有最長公共子字符串(LCS)的MySQL函數?我發現一個函數here,但在SQL中。作爲一名自學成才的程序員,我不太瞭解MySQL,但是從事與藝術相關的項目。MySQL最長公共子字符串
回答
MySQL可以說並不是實現字符串操作函數的最合適的地方,通常我們需要問題來展示所需代碼的一些工作。我對這個有點靈活,因爲你至少可以找到你想要做什麼的參考,並詢問MySQL是否具有本地功能。
它沒有。
您還問過示例代碼是否可以重寫爲MySQL。
它不能。它似乎依賴於未在MySQL服務器中實現的功能。
但是......這個問題讓我很感興趣,而且我喜歡在MySQL中做不尋常的事情(有時候,能夠在數據庫中做一些事情是很好的,儘管它不一定是最有效的地方,有時候可以說是相當的錯的地方,但還是方便)......等等,而不是一個淋浴的,我今天早上洗了個澡,並在這段時間裏,我想出了這個:
DELIMITER $$
DROP FUNCTION IF EXISTS `longest_common_substring` $$
CREATE FUNCTION `longest_common_substring`(short_str TEXT, long_str TEXT) RETURNS text CHARSET utf8
NO SQL
DETERMINISTIC
BEGIN
-- http://stackoverflow.com/questions/35545281/mysql-longest-common-substring
DECLARE short_len INT DEFAULT CHAR_LENGTH(short_str);
DECLARE long_len INT DEFAULT CHAR_LENGTH(long_str);
DECLARE swap_str TEXT;
DECLARE max_matched_len INT DEFAULT 0;
DECLARE max_at_left_marker INT DEFAULT NULL;
DECLARE max_at_match_len INT DEFAULT NULL;
DECLARE left_marker INT DEFAULT 0;
DECLARE match_len INT DEFAULT NULL;
IF short_str IS NULL OR long_str IS NULL THEN
RETURN NULL;
ELSEIF short_str = long_str THEN
RETURN short_str;
END IF;
IF short_len > long_len THEN
SET swap_str = long_str;
SET long_str = short_str;
SET short_str = swap_str;
SET short_len = long_len;
SET long_len = CHAR_LENGTH(long_str);
END IF;
left_loop:
LOOP
SET left_marker = left_marker + 1;
IF left_marker + max_matched_len > short_len THEN
LEAVE left_loop;
END IF;
SET match_len = max_matched_len;
right_loop:
LOOP
SET match_len = match_len + 1;
IF 1 - left_marker + match_len > short_len THEN
LEAVE right_loop;
END IF;
IF long_str LIKE CONCAT ('%',SUBSTRING(short_str FROM left_marker FOR match_len),'%') THEN
SET max_matched_len = match_len, max_at_left_marker = left_marker;
ELSE
LEAVE right_loop;
END IF;
END LOOP;
END LOOP;
IF (max_matched_len) THEN
RETURN SUBSTRING(short_str FROM max_at_left_marker FOR max_matched_len);
ELSE
RETURN NULL;
END IF;
END $$
DELIMITER ;
它似乎工作正確。
mysql> SELECT longest_common_substring('Lions are growing like yellow roses on the wind','and we turn gracefully in the medieval garden of their roaring blossoms');
+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| longest_common_substring('Lions are growing like yellow roses on the wind','and we turn gracefully in the medieval garden of their roaring blossoms') |
+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| n the |
+-------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT longest_common_substring('die, bart, die','sideshow bob dislikes bart simpson');
+---------------------------------------------------------------------------------+
| longest_common_substring('die, bart, die','sideshow bob dislikes bart simpson') |
+---------------------------------------------------------------------------------+
| bart |
+---------------------------------------------------------------------------------+
1 row in set (0.01 sec)
有一些注意事項 -
如果有一個以上的「最長」串匹配,也就是說,如果有長的一模一樣的兩個(或更多)的「最長」子字符串匹配,第一場比賽將是返回的比賽。
此代碼並不認爲空格或標點符號的重要性不如其他字符,因此在上面的第二個示例中,答案實際上是5個字符,具有前導空格的' bart'
。可以說,具有5個非空格字符的子字符串如果存在則是更好的匹配,並且該代碼不會找到它,因爲使用了第一個匹配,並且除非它們更長,否則不會考慮後續匹配。它可以被修改成更復雜,但這實質上是一個概念證明。
mysql> SELECT longest_common_substring('bart and lisa','bart or lisa');
+----------------------------------------------------------+
| longest_common_substring('bart and lisa','bart or lisa') |
+----------------------------------------------------------+
| bart |
+----------------------------------------------------------+
1 row in set (0.00 sec)
...但是,如果一個較短的比賽是一個候選人,但未連接的較長的一個如下,結果肯定是符合市場預期。
mysql> SELECT longest_common_substring('bart and maggie','bart or maggie');
+--------------------------------------------------------------+
| longest_common_substring('bart and maggie','bart or maggie') |
+--------------------------------------------------------------+
| maggie |
+--------------------------------------------------------------+
1 row in set (0.00 sec)
工作原理:
我們需要兩個參數,第一個期待較短的字符串。如果較長的字符串是第一個,那很好,因爲我們將它們交換到內存中,但它花費了我們一點處理時間。
然後,我們拖動一個臨時子字符串 - 短字符串的特製短片 - 跨過長字符串,檢查長字符串是否爲LIKE
%+我們的臨時子字符串+%。如果不是,我們轉向下一個角色。如果是這樣,我們將臨時子字符串擴展1個字符,直到我們不再匹配 - 但是當我們擁有匹配時,我們保存了它的位置和長度,並將此信息用作後續優化,以避免不必要的比較不可能產生更好的匹配。
我可以將其添加到https://github.com/sqlbot/dtsl-mysql,這是我收集的日期,時間和字符串操作函數,一旦我準備好發佈它。
- 1. 一系列字符串的最長公共子序列
- 2. 3個字符串中最長的公共子序列
- 3. 查找2個字符串的最長公共子序列?
- 4. 獲取基於字符串相似最長公共子
- 5. Lucene搜索最長公共子字符串
- 6. 如何找到多個字符串中最長的公共子字符串?
- 7. 來自兩個以上字符串的最長公共子字符串 - C++
- 8. 由最長公共起始子字符串組成的字符串組
- 9. WAP返回兩個字符串之間最長公共子串的長度
- 10. 最長公共子串的方法
- 11. 最長的公共子串問題
- 12. 最長的公共子串算法
- 13. 的Java:最長公共子
- 14. 倍捻最長公共子
- 15. 最長公共子錯誤
- 16. 最長的子字符串
- 17. bash中兩個字符串的最長公共前綴
- 18. Perl - 2個或更多字符串的最長公共前綴?
- 19. 非常大的字符串之間最長的公共子序列
- 20. 兩個字符串的所有可能的LCS(最長公共子序列)
- 21. 生成所有最長公共子字符串的列表和變化
- 22. 最長公共Subseqence
- 23. 3串輸入中最長的公共子串
- 24. 最長的公共子序列Algo
- 25. 最長公共子序列優化
- 26. 找到所有最長公共子
- 27. 最長的公共子序列算法
- 28. 如何找到最長公共子陣
- 29. 打印最長公共子序列
- 30. 最長公共子序列的界限