Karena ada sejumlah solusi yang adil saya akan pergi dengan bagian "kritik" dari pertanyaan Anda. Beberapa catatan: Saya telah memperbaiki beberapa kesalahan ketik dan mencatat di mana saya melakukannya. Jika saya salah tentang mereka yang salah ketik sebutkan di komentar dan saya akan menjelaskan apa yang terjadi. Saya akan menunjukkan beberapa hal yang mungkin sudah Anda ketahui, jadi jangan tersinggung jika saya tahu. Beberapa komentar mungkin terlihat pilih-pilih tetapi saya tidak tahu di mana Anda berada dalam perjalanan Anda sehingga harus menganggap Anda baru memulai.
CREATE function Palindrome (
@String Char
, @StringLength Int
, @n Int
, @Palindrome BIN
, @StringLeftLength Int
SELALU termasuk panjang dengan a char
atau varchar
definisi. Aaron Bertrand berbicara tentang secara mendalam di sini . Dia berbicara tentang varchar
tetapi yang sama berlaku untuk char
. Saya akan menggunakan varchar(255)
untuk ini jika Anda hanya menginginkan string yang relatif pendek atau mungkin varchar(8000)
untuk yang lebih besar atau bahkan varchar(max)
. Varchar
adalah untuk string panjang variabel char
hanya untuk yang tetap. Karena Anda tidak yakin panjang tali yang digunakan varchar
. Juga binary
tidak bin
.
Selanjutnya Anda tidak perlu menempatkan semua variabel tersebut sebagai parameter. Nyatakan dalam kode Anda. Hanya masukkan sesuatu ke dalam daftar parameter jika Anda berencana meneruskannya atau keluar. (Anda akan melihat bagaimana ini terlihat di akhir.) Anda juga memiliki @StringLeftLength tetapi tidak pernah menggunakannya. Jadi saya tidak akan mendeklarasikannya.
Hal berikutnya yang akan saya lakukan adalah memformat ulang sedikit untuk membuat beberapa hal menjadi jelas.
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
Jika Anda melihat cara saya melakukan indentasi, Anda akan melihat bahwa saya memilikinya:
WHILE @StringLength - @n >1
IF Left(@String,@n)=Right(@String, @StringLength)
SET @n = @n + 1
Itu karena perintah suka WHILE
dan IF
hanya memengaruhi baris kode pertama setelahnya. Anda harus menggunakan BEGIN .. END
blok jika Anda menginginkan banyak perintah. Jadi memperbaiki yang kita dapatkan:
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
Anda akan melihat bahwa saya hanya menambahkan BEGIN .. END
blok di IF
. Itu karena meskipun IF
pernyataan itu panjang baris ganda (dan bahkan berisi banyak perintah) itu masih merupakan pernyataan tunggal (mencakup semua yang dilakukan di dalam IF
dan ELSE
bagian - bagian dari pernyataan).
Selanjutnya Anda akan mendapatkan kesalahan setelah Anda berdua RETURNs
. Anda dapat mengembalikan variabel ATAU literal. Anda tidak dapat mengatur variabel dan mengembalikannya secara bersamaan.
SET @Palindrome = 1
END
ELSE
SET @Palindrome = 0
RETURN @Palindrome
Sekarang kita masuk ke dalam logika. Pertama-tama izinkan saya menunjukkan bahwa fungsi LEFT
dan RIGHT
fungsi yang Anda gunakan hebat, tetapi mereka akan memberi Anda jumlah karakter yang Anda lewati dari arah yang diminta. Jadi katakanlah Anda lulus dalam kata "test". Pada pass pertama Anda akan mendapatkan ini (menghapus variabel):
LEFT('test',1) = RIGHT('test',4)
t = test
LEFT('test',2) = RIGHT('test',3)
te = est
Jelas itu bukan yang Anda harapkan. Anda benar-benar ingin menggunakannya substring
. Substring memungkinkan Anda melewati tidak hanya titik awal tetapi juga panjang. Jadi, Anda akan mendapatkan:
SUBSTRING('test',1,1) = SUBSTRING('test',4,1)
t = t
SUBSTRING('test',2,1) = SUBSTRING('test',3,1)
e = s
Selanjutnya Anda menambah variabel yang Anda gunakan dalam loop Anda hanya dalam satu kondisi pernyataan IF. Tarik variabel yang bertambah keluar dari struktur itu sepenuhnya. Itu akan membutuhkan BEGIN .. END
blok tambahan , tapi saya bisa menghapus yang lain.
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
Anda perlu mengubah WHILE
kondisi Anda untuk memungkinkan tes terakhir.
WHILE @StringLength > @n
Dan last but not least, cara berdiri sekarang kita tidak menguji karakter terakhir jika ada jumlah karakter ganjil. Misalnya dengan 'ana' yang n
tidak diuji. Itu baik-baik saja tetapi tidak saya perlu memperhitungkan satu kata huruf (jika Anda ingin itu dihitung sebagai positif itu adalah). Jadi kita bisa melakukannya dengan mengatur nilai di depan.
Dan sekarang kita akhirnya memiliki:
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
Satu komentar terakhir. Saya penggemar berat pemformatan secara umum. Ini benar-benar dapat membantu Anda melihat bagaimana kode Anda bekerja dan membantu menunjukkan kemungkinan kesalahan.
Edit
Seperti yang Sphinxxx sebutkan, kita masih memiliki kekurangan dalam logika kita. Setelah kita menekan ELSE
dan mengatur @Palindrome
ke 0 tidak ada gunanya melanjutkan. Padahal pada titik itu kita bisa saja RETURN
.
IF SUBSTRING(@String,@n,1) = SUBSTRING(@String, @StringLength,1)
SET @Palindrome = 1
ELSE
RETURN 0
Mengingat bahwa kita sekarang hanya menggunakan @Palindrome
untuk "masih mungkin ini adalah palindrom" tidak ada gunanya memilikinya. Kita dapat menyingkirkan variabel dan mengalihkan logika kita ke hubungan pendek pada kegagalan (the RETURN 0
) dan RETURN 1
(respons positif) hanya jika itu membuat semua jalan melalui loop. Anda akan melihat ini sebenarnya menyederhanakan logika kami.
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(...))
ruang putih?