Sql-Server

使用 T-SQL 測試字元串是否為回文

  • May 8, 2020

我是 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

始終包含帶有charvarchar定義的長度。Aaron Bertrand在這裡深入討論了它。他在談論,varchar但同樣適用charvarchar(255)如果您只想要相對較短的字元串,或者對於較大的字元串,我會使用 a ,varchar(8000)甚至varchar(max). Varchar適用於可變長度字元串char僅適用於固定字元串。由於您不確定在 use 中傳遞的字元串的長度varcharbinary也不是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 .. ENDIF. 這是因為即使該IF語句是多行長(甚至包含多個命令),它仍然是一條語句(涵蓋在語句中執行的所有內容IFELSE部分語句)。

接下來,您將在兩個RETURNs. 您可以返回變數或文字。您不能同時設置變數並返回它。

               SET @Palindrome = 1 
           END
       ELSE 
           SET @Palindrome = 0

   RETURN @Palindrome

現在我們進入邏輯。首先讓我指出您使用的LEFTRIGHT函式很棒,但它們會為您提供從請求方向傳入的字元數。所以假設你通過了“測試”這個詞。在第一遍你會得到這個(刪除變數):

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

引用自:https://dba.stackexchange.com/questions/137388