เนื่องจากมีโซลูชั่นจำนวนพอสมควรฉันจะไปกับ "บทวิจารณ์" ส่วนหนึ่งของคำถามของคุณ คู่ของบันทึกย่อ: ฉันได้แก้ไขความผิดพลาดบางอย่างและตั้งข้อสังเกตว่าฉันอยู่ที่ไหน ถ้าฉันผิดเกี่ยวกับพวกเขาเป็นตัวพิมพ์ผิดพูดถึงในความคิดเห็นและฉันจะอธิบายสิ่งที่เกิดขึ้น ฉันจะชี้ให้เห็นสิ่งต่าง ๆ ที่คุณอาจรู้อยู่แล้วดังนั้นโปรดอย่าทำผิดถ้าฉันทำ ความคิดเห็นบางอย่างอาจดูพิถีพิถัน แต่ฉันไม่รู้ว่าคุณอยู่ที่ไหนในการเดินทางของคุณดังนั้นต้องคิดว่าคุณเพิ่งจะเริ่ม
CREATE function Palindrome (
@String Char
, @StringLength Int
, @n Int
, @Palindrome BIN
, @StringLeftLength Int
เสมอรวมถึงความยาวด้วยchar
หรือvarchar
ความหมาย แอรอนเบอร์ทรานด์พูดเกี่ยวกับในในเชิงลึกที่นี่ เขาพูดถึงแต่เดียวกันจะไปสำหรับvarchar
char
ฉันต้องการใช้varchar(255)
สำหรับการนี้หากคุณต้องการเพียงสตริงค่อนข้างสั้นหรืออาจจะเป็นคนที่มีขนาดใหญ่หรือแม้กระทั่ง varchar(8000)
สำหรับสตริงที่มีความยาวผันแปรได้มีไว้สำหรับสตริงคงที่เท่านั้น เนื่องจากคุณไม่แน่ใจว่าความยาวของสตริงที่ถูกส่งในการใช้งาน นอกจากนี้ก็ไม่ได้varchar(max)
Varchar
char
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
สำหรับ "ยังคงเป็นไปได้นี่คือ palindrome" ไม่มีจุดที่จะมีได้จริง ๆ เราสามารถกำจัดตัวแปรและเปลี่ยนตรรกะของเราเป็นไฟฟ้าลัดวงจรเมื่อความล้มเหลว ( RETURN 0
) และRETURN 1
(การตอบสนองเชิงบวก) ก็ต่อเมื่อมันผ่านวงจร คุณจะสังเกตเห็นว่าสิ่งนี้ทำให้ตรรกะของเราง่ายขึ้น
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
LTRIM(RTRIM(...))
ช่องว่าง?