Many of you must have played the 'mangled words' game in the school. Here is a challenge that gives you an opportunity to play it once again using TSQL.
Your task is to process the input table that contains several mangled words and try to 'un-mangle' them and validate them against a 'dictionary' table. You might be able to create more than one correct word from some of the input strings. It is also possible that a mangled word is completely incorrect and no valid word can be created from it.
As an example, given "xtet", the valid word that can be formed is "text".
- Sample Data
ID MangledWord -- ----------- 1 Lnlaheecg 2 etxtThe second one (Dictionary) contains the valid words. Sample Input Data for Dictionary table.
ID Word -- --------- 1 challenge 2 enigma 3 angle 4 change 5 changing
- Expected Results
ID MangledWord CorrectWords -- ----------- ---------------------- 1 lnlaheecg angle,challenge,change 2 etxt No matching word found
- Rules
- ID should be sorted in Ascending Order.
- The valid words(if found) will be sorted in Ascending order in the CorrectWords column.
- If no words can be formed, then the CorrectWords column should contain No matching word found corresponding to the MangledWord.
- The program should run in SQL SERVER 2005 and above.
- The output should be in the same way as it has been shown.
- 個人解法
DECLARE @tblMangledWord TABLE(ID INT IDENTITY, MangledWord VARCHAR(100))
INSERT INTO @tblMangledWord
SELECT 'lnlaheecg' UNION ALL
SELECT 'etxt'
DECLARE @tblDictionary TABLE(ID INT IDENTITY, Word VARCHAR(100))
INSERT INTO @tblDictionary
SELECT 'challenge' UNION ALL
SELECT 'enigma' UNION ALL
SELECT 'angle' UNION ALL
SELECT 'change' UNION ALL
SELECT 'changing'
;
WITH CTE AS
(
SELECT
ID ,
MangledWord ,
LEN(MangledWord)-1 AS Location ,
SUBSTRING(MangledWord,LEN(MangledWord),1) AS Letter
FROM @tblMangledWord
UNION ALL
SELECT
ID ,
MangledWord ,
Location - 1 ,
SUBSTRING(MangledWord,Location,1)
FROM CTE
WHERE Location > 0
)
,
CTE2 AS
(
SELECT
ID ,
Word ,
LEN(Word) - 1 AS Location ,
SUBSTRING(Word,LEN(Word),1) AS Letter
FROM @tblDictionary
UNION ALL
SELECT
ID ,
Word ,
Location - 1 ,
SUBSTRING(Word,Location,1) AS Letter
FROM CTE2
WHERE Location > 0
)
,
CTE3 AS
(
SELECT T3.*
FROM
(
SELECT
T1.ID ,
T1.MangledWord ,
T2.Word ,
COUNT(DISTINCT T2.Letter) AS LetterCount
FROM CTE AS T1
JOIN CTE2 AS T2 ON T1.Letter = T2.Letter
GROUP BY T1.ID , T1.MangledWord , T2.Word
) AS T3
JOIN
(
SELECT
Word ,
COUNT(DISTINCT Letter) AS LetterCount
FROM CTE2
GROUP BY Word
) AS T4 ON T3.Word = T4.Word
AND T3.LetterCount = T4.LetterCount
)
SELECT
F1.ID ,
F1.MangledWord ,
ISNULL(F2.CorrectWords,'No matching word found') AS CorrectWords
FROM @tblMangledWord AS F1
LEFT JOIN
(
SELECT T5.ID ,
STUFF
(
(
SELECT ',' + Word
FROM CTE3 AS T6
WHERE T5.ID = T6.ID
ORDER BY Word
FOR XML PATH('')
)
,1
,1
,''
) AS CorrectWords
FROM CTE3 AS T5
GROUP BY ID
) AS F2 ON F1.ID = F2.ID
利用 CTE 把兩個 Sample Table 中每個字串的字母都拆出來,兩者進行比對,來判斷是否可以組合成有效單字。
沒有留言:
張貼留言