Baru-baru ini, saya memulai latihan harian saya di CodeWar, dan ini adalah catatan dari pertanyaan pertama saya yang terpecahkan: Isogram.

Pada catatan kali ini saya tidak akan membahas kompleksitas ruang dan waktu, karena saya masih belum familiar dengan JS…

Isogram adalah kalimat (atau “string”) yang tidak memiliki kata berulang.

Dalam pertanyaan ini, kita memiliki satu masukan (string) dan tugas kita adalah mengembalikan keluaran (benar atau salah) untuk mengetahui apakah masukan tersebut isogram atau bukan.

Solusi pertama saya

Untuk mengatasi pertanyaan tersebut, ide pertama saya adalah menggunakan Set untuk menyimpan setiap kata dalam kalimat, dan jika kata tersebut telah disimpan (ulangi kata), fungsi isIsogram akan mengembalikan false; jika semua kata telah dilalui dan tidak ada hasil yang salah, maka fungsinya akan mengembalikan nilai benar.

function isIsogram(str){
  const strL = str.toLowerCase().split('') // convert all words in the sentence to lowercase, and remove all blank.
  const strSet = {}
  for(let i = 0; i< strL.length; i++){
    if(strSet[strL[i]]===0){ // if the word has been stored
      return false
    }
    else{
      strSet[strL[i]] = 0
    }
  }
  return true
}

Solusi orang lain

Setelah mengirimkan jawaban saya, saya mulai meneliti jawaban orang lain:

yang pertama juga menggunakan himpunan untuk menyelesaikan pertanyaan

function isIsogram(str){
  const strL = str.toLowerCase().split('')
  const setStrL = new Set(strL)
  return setStrL.size === strL.length
}

Namun, logikanya adalah menggunakan karakteristik Set —Kunci unik.

Jika string masukan memiliki kata-kata yang berulang, ukuran Himpunan yang dikonversi dari string masukan akan berbeda dengan panjang string.

Solusi kedua, gunakan indexOf di JS untuk menyelesaikan pertanyaan.

function isIsogram(str){
  const strL = str.toLowerCase().split('')
  return strL.every((current, index) => strL.indexOf(current) === index);
}

Dalam solusi ini, kita melintasi semua kata dalam kalimat, dan jika indeks kata saat ini berbeda dari indeks yang dikembalikan oleh fungsi “indexOf”, maka kembalikan salah, jika tidak kembalikan benar.

Fungsi “indexOf” akan mengembalikan indeks kata “pertama” yang ditemukan pada kalimat tersebut, jadi jika kalimat tersebut memiliki kata yang berulang, maka indeksnya akan berbeda, jika tidak, akan selalu menghasilkan nomor indeks yang sama.

Solusi ketiga menggunakan ekspresi reguler.

function isIsogram(str){ 
  return !/(\w).*\1/i.test(str)
}

Untuk solusi ini, saya belajar selama 2 jam untuk mengetahui cara kerjanya.

Pertama, fungsi "test" dirancang untuk ekspresi reguler JS, kata MDN:

Metode RegExp yang menguji kecocokan dalam sebuah string. Ini mengembalikan benar atau salah.

Sekarang mari kita gunakan https://regex101.com/ untuk mengetahui penjelasan ekspresi reguler:

  1. “\w” cocok dengan karakter kata apa pun (setara dengan [a-zA-Z0–9_]), dan”()” akan membuat kecocokan disimpan sebagai grup.
  2. “.” cocok dengan karakter apa pun (kecuali untuk terminator garis)
  3. “*” cocok dengan token sebelumnya antara waktu nol dan tidak terbatas, sebanyak mungkin, memberikan kembali sesuai kebutuhan (serakah)
  4. “\1” cocok dengan teks yang sama dengan yang terakhir dicocokkan oleh grup penangkap pertama. (Dalam hal ini, teks tersebut akan cocok dengan teks yang sama dengan yang terakhir dicocokkan oleh \w)
  5. Pengubah “i”: itidak sensitif. Pencocokan tidak peka huruf besar-kecil (abaikan huruf besar-kecil [a-zA-Z])

Jadi, secara umum “/(\w).*\1/i” akan cocok dengan kalimat berbentuk “…(\w)…(\w)…”.

“!/(\w).*\1/i.test(str)” akan menguji “str”, jika “str” cocok dengan bentuk “…(\w)…(\w)…”, lalu kembalikan salah, kalau tidak kembalikan benar.