使用 T-SQL 測試字元串是否為回文
我是 T-SQL 的初學者。我想確定輸入字元串是否是回文,如果不是,則輸出 = 0,如果是,則輸出 = 1。我仍在弄清楚語法。我什至沒有收到錯誤消息。我正在尋找不同的解決方案和一些回饋,以便更好地理解和了解 T-SQL 的工作原理,從而變得更好——我仍然是一名學生。
在我看來,關鍵思想是將最左邊和最右邊的字元相互比較,檢查是否相等,然後繼續比較左邊第二個字元和倒數第二個字元,等等。我們做一個循環:如果字元彼此相等,我們繼續。如果我們到達終點,我們輸出 1,如果沒有,我們輸出 0。
請您批評一下:
CREATE function Palindrome( @String Char , @StringLength Int , @n Int , @Palindrome BIN , @StringLeftLength Int ) RETURNS Binary AS BEGIN SET @ n=1 SET @StringLength= Len(String) WHILE @StringLength - @n >1 IF Left(String,@n)=Right(String, @StringLength) SET @n =n+1 SET @StringLength =StringLength -1 RETURN @Binary =1 ELSE RETURN @Palindrome =0 END
我認為我在正確的軌道上,但我還有很長的路要走。有任何想法嗎?
由於有很多解決方案,我將使用您問題的“批評”部分。幾點說明:我修正了一些錯別字並註明了我所做的。如果我錯了他們是錯字,請在評論中提及,我會解釋發生了什麼。我將指出您可能已經知道的幾件事,所以如果我這樣做了,請不要生氣。有些評論可能看起來很挑剔,但我不知道你的旅程在哪裡,所以必須假設你才剛剛開始。
CREATE function Palindrome ( @String Char , @StringLength Int , @n Int , @Palindrome BIN , @StringLeftLength Int
始終包含帶有
char
或varchar
定義的長度。Aaron Bertrand在這裡深入討論了它。他在談論,varchar
但同樣適用char
。varchar(255)
如果您只想要相對較短的字元串,或者對於較大的字元串,我會使用 a ,varchar(8000)
甚至varchar(max)
.Varchar
適用於可變長度字元串char
僅適用於固定字元串。由於您不確定在 use 中傳遞的字元串的長度varchar
。binary
也不是bin
。接下來,您不需要將所有這些變數都作為參數。在您的程式碼中聲明它們。如果您打算將其傳入或傳出,請僅將其放入參數列表中。(你會在最後看到它的樣子。)你也有
@StringLeftLength
但從未使用它。所以我不打算宣布它。接下來我要做的是重新格式化一下,讓一些事情變得明顯。
BEGIN SET @n=1 SET @StringLength = Len(@String) -- Missed an @ WHILE @StringLength - @n >1 IF Left(@String,@n)=Right(@String, @StringLength) -- More missing @s SET @n = @n + 1 -- Another missing @ SET @StringLength = @StringLength - 1 -- Watch those @s :) RETURN @Palindrome = 1 -- Assuming another typo here ELSE RETURN @Palindrome =0 END
如果您查看我進行縮進的方式,您會注意到我有這個:
WHILE @StringLength - @n >1 IF Left(@String,@n)=Right(@String, @StringLength) SET @n = @n + 1
那是因為命令喜歡
WHILE
並且IF
只影響它們之後的第一行程式碼。BEGIN .. END
如果你想要多個命令,你必須使用一個塊。所以修復我們得到:WHILE @StringLength - @n > 1 IF Left(@String,@n)=Right(@String, @StringLength) BEGIN SET @n = @n + 1 SET @StringLength = @StringLength - 1 RETURN @Palindrome = 1 END ELSE RETURN @Palindrome = 0
你會注意到我只
BEGIN .. END
在IF
. 這是因為即使該IF
語句是多行長(甚至包含多個命令),它仍然是一條語句(涵蓋在語句中執行的所有內容IF
和ELSE
部分語句)。接下來,您將在兩個
RETURNs
. 您可以返回變數或文字。您不能同時設置變數並返回它。SET @Palindrome = 1 END ELSE SET @Palindrome = 0 RETURN @Palindrome
現在我們進入邏輯。首先讓我指出您使用的
LEFT
和RIGHT
函式很棒,但它們會為您提供從請求方向傳入的字元數。所以假設你通過了“測試”這個詞。在第一遍你會得到這個(刪除變數):LEFT('test',1) = RIGHT('test',4) t = test LEFT('test',2) = RIGHT('test',3) te = est
顯然這不是你所期望的。你真的想
substring
改用。子字元串不僅可以讓您傳入起點,還可以傳入長度。所以你會得到:SUBSTRING('test',1,1) = SUBSTRING('test',4,1) t = t SUBSTRING('test',2,1) = SUBSTRING('test',3,1) e = s
接下來,您將僅在 IF 語句的一個條件中遞增您在循環中使用的變數。將遞增的變數完全拉出該結構。這將需要一個額外的
BEGIN .. END
塊,但我確實要刪除另一個塊。WHILE @StringLength - @n > 1 BEGIN IF SUBSTRING(@String,@n,1) = SUBSTRING(@String, @StringLength,1) SET @Palindrome = 1 ELSE SET @Palindrome = 0 SET @n = @n + 1 SET @StringLength = @StringLength - 1 END
您需要更改您的
WHILE
條件以允許最後一次測試。WHILE @StringLength > @n
最後但並非最不重要的一點是,如果有奇數個字元,我們現在不會測試最後一個字元。例如,‘ana’
n
未經測試。沒關係,但我需要考慮一個字母詞(如果你想讓它算作積極的話)。所以我們可以通過預先設置值來做到這一點。現在我們終於有了:
CREATE FUNCTION Palindrome (@String varchar(255)) RETURNS Binary AS BEGIN DECLARE @StringLength Int , @n Int , @Palindrome binary SET @n = 1 SET @StringLength = Len(@String) SET @Palindrome = 1 WHILE @StringLength > @n BEGIN IF SUBSTRING(@String,@n,1) = SUBSTRING(@String, @StringLength,1) SET @Palindrome = 1 ELSE SET @Palindrome = 0 SET @n = @n + 1 SET @StringLength = @StringLength - 1 END RETURN @Palindrome END
最後一條評論。一般來說,我是格式化的忠實粉絲。它真的可以幫助您了解您的程式碼是如何工作的,並幫助您指出可能的錯誤。
編輯
正如 Sphinxxx 提到的,我們的邏輯仍然存在缺陷。一旦我們點擊
ELSE
並設置@Palindrome
為 0 就沒有繼續的意義了。事實上,那時我們可以RETURN
。IF SUBSTRING(@String,@n,1) = SUBSTRING(@String, @StringLength,1) SET @Palindrome = 1 ELSE RETURN 0
鑑於我們現在只
@Palindrome
用於“它仍然有可能這是回文”,因此擁有它真的沒有意義。我們可以擺脫變數並將我們的邏輯切換到失敗時短路RETURN 0
(the )和RETURN 1
(a positive response)只有當它一直通過循環時。你會注意到這實際上在某種程度上簡化了我們的邏輯。CREATE FUNCTION Palindrome (@String varchar(255)) RETURNS Binary AS BEGIN DECLARE @StringLength Int , @n Int SET @n = 1 SET @StringLength = Len(@String) WHILE @StringLength > @n BEGIN IF SUBSTRING(@String,@n,1) <> SUBSTRING(@String, @StringLength,1) RETURN 0 SET @n = @n + 1 SET @StringLength = @StringLength - 1 END RETURN 1 END