Saya seorang pemula di T-SQL. Saya ingin memutuskan apakah string input adalah palindrome, dengan output = 0 jika tidak dan output = 1 jika itu. Saya masih mencari tahu sintaksisnya. Saya bahkan tidak mendapatkan pesan kesalahan. Saya mencari solusi yang berbeda dan beberapa umpan balik, untuk mendapatkan pemahaman dan pengetahuan yang lebih baik tentang bagaimana T-SQL bekerja, untuk menjadi lebih baik - Saya masih seorang mahasiswa.
Gagasan utama, seperti yang saya lihat, adalah untuk membandingkan karakter paling kiri dan paling kanan satu sama lain, untuk memeriksa kesetaraan, kemudian melanjutkan untuk membandingkan karakter kedua dari kiri dengan yang kedua dari yang terakhir, dll. Kami melakukan loop: Jika karakter sama satu sama lain, kami melanjutkan. Jika kita mencapai akhir, kita menghasilkan 1, jika tidak, kita menghasilkan 0.
Tolong kritik.
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
Saya pikir saya berada di jalur yang benar, tetapi saya masih jauh. Ada ide?
LTRIM(RTRIM(...))
ruang putih?Jawaban:
Jika Anda menggunakan SQL Server, Anda dapat menggunakan fungsi REVERSE () untuk memeriksa?
Termasuk komentar Martin Smith, jika Anda menggunakan SQL Server 2012+ Anda dapat menggunakan fungsi IIF () :
sumber
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.
SELALU termasuk panjang dengan a
char
atauvarchar
definisi. Aaron Bertrand berbicara tentang secara mendalam di sini . Dia berbicara tentangvarchar
tetapi yang sama berlaku untukchar
. Saya akan menggunakanvarchar(255)
untuk ini jika Anda hanya menginginkan string yang relatif pendek atau mungkinvarchar(8000)
untuk yang lebih besar atau bahkanvarchar(max)
.Varchar
adalah untuk string panjang variabelchar
hanya untuk yang tetap. Karena Anda tidak yakin panjang tali yang digunakanvarchar
. Jugabinary
tidakbin
.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.
Jika Anda melihat cara saya melakukan indentasi, Anda akan melihat bahwa saya memilikinya:
Itu karena perintah suka
WHILE
danIF
hanya memengaruhi baris kode pertama setelahnya. Anda harus menggunakanBEGIN .. END
blok jika Anda menginginkan banyak perintah. Jadi memperbaiki yang kita dapatkan:Anda akan melihat bahwa saya hanya menambahkan
BEGIN .. END
blok diIF
. Itu karena meskipunIF
pernyataan itu panjang baris ganda (dan bahkan berisi banyak perintah) itu masih merupakan pernyataan tunggal (mencakup semua yang dilakukan di dalamIF
danELSE
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.Sekarang kita masuk ke dalam logika. Pertama-tama izinkan saya menunjukkan bahwa fungsi
LEFT
danRIGHT
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):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: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.Anda perlu mengubah
WHILE
kondisi Anda untuk memungkinkan tes terakhir.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:
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 sajaRETURN
.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 (theRETURN 0
) danRETURN 1
(respons positif) hanya jika itu membuat semua jalan melalui loop. Anda akan melihat ini sebenarnya menyederhanakan logika kami.sumber
Anda juga bisa menggunakan pendekatan tabel Angka.
Jika Anda belum memiliki tabel angka bantu Anda dapat membuatnya sebagai berikut. Ini diisi dengan satu juta baris sehingga akan bagus untuk panjang string hingga 2 juta karakter.
Di bawah ini membandingkan setiap karakter di sebelah kiri dengan mitra terkait di sebelah kanan, dan jika ada perbedaan ditemukan dapat korsleting dan mengembalikan 0. Jika string adalah panjang ganjil, karakter tengah tidak diperiksa karena ini tidak akan mengubah hasilnya .
Jika Anda tidak yakin cara kerjanya, Anda dapat melihat dari bawah
Ini pada dasarnya adalah algoritma yang sama seperti yang dijelaskan dalam pertanyaan, tetapi dilakukan dengan cara yang ditetapkan berdasarkan daripada kode prosedur iteratif.
sumber
The
REVERSE()
Metode "membaik", yaitu membalikkan hanya setengah dari string:Saya tidak mengharapkan sesuatu yang aneh terjadi jika string memiliki jumlah karakter yang aneh; karakter tengah tidak harus diperiksa.
Sebuah komentar dikemukakan oleh @hvd bahwa ini mungkin tidak menangani pasangan pengganti dengan benar di semua pemeriksaan.
@srutzky berkomentar bahwa ia menangani Karakter Tambahan / Pasangan Pengganti dengan cara yang sama dengan
REVERSE()
metode ini, karena mereka hanya berfungsi dengan baik ketika Collation default basis data saat ini berakhir_SC
.sumber
Tanpa menggunakan
REVERSE
, itulah yang langsung terlintas dalam pikiran, tetapi masih menggunakan fungsi 1 ; Saya akan membangun sesuatu seperti berikut ini.Bagian ini hanya menghapus fungsi yang ada, jika sudah ada:
Ini fungsinya sendiri:
Di sini, kami menguji fungsinya:
Ini membandingkan paruh pertama kata dengan kebalikan dari setengah kata terakhir (tanpa menggunakan
REVERSE
fungsi). Kode ini menangani dengan benar kata-kata panjang dan ganjil. Alih-alih mengulang seluruh kata, kita cukup mendapatkan bagianLEFT
dari kata pertama, kemudian mengulangi bagian terakhir kata untuk mendapatkan bagian yang dibalik dari bagian kanan. Jika kata itu panjangnya ganjil, kita lewati huruf tengah, karena menurut definisi itu akan sama untuk kedua "belahan".1 - fungsi bisa sangat lambat!
sumber
Tanpa menggunakan REVERSE ... Itu selalu menyenangkan untuk menggunakan solusi rekursif;) (Saya punya saya di SQL Server 2012, versi sebelumnya mungkin memiliki batasan pada rekursi)
sumber
Ini adalah versi TVF-friendly inline dari solusi berbasis set Martin Smith , juga dihiasi dengan beberapa perangkat tambahan yang berlebihan:
sumber
Hanya untuk bersenang-senang, inilah fungsi yang Ditentukan Pengguna SQL Server 2016 dengan Fitur OLTP Di Memori:
sumber
Masalah utama yang akan Anda hadapi adalah bahwa dengan nilai lebih dari 1,
LEFT
atauRIGHT
akan mengembalikan banyak karakter, bukan karakter pada posisi itu. Jika Anda ingin tetap menggunakan metode pengujian ini, cara yang sangat sederhana untuk mengubahnya adalahIni akan selalu mengambil karakter paling kanan dari string kiri dan karakter paling kiri dari string kanan.
Mungkin cara yang kurang bundaran untuk memeriksa ini, adalah dengan menggunakan
SUBSTRING
:Perhatikan bahwa
SUBSTRING
1-diindeks, maka+ 1
di((LEN(String) - @n) + 1)
.sumber