Zaznavanje cikličnih seznamov predvajanja v JavaScriptu
Iskanje ciklov ali ponovitev je pogosta težava pri odgovarjanju na vprašanja intervjuja o kodiranju, zlasti tistih, ki zahtevajo podatkovne strukture, kot so povezani seznami. Ta težava se običajno pojavi na seznamih predvajanja, kjer so lahko pesmi med seboj povezane v verigi referenc. Za seznam predvajanja pravimo, da se ponavlja, če se pesem sklicuje na prejšnjo skladbo.
Cilj te vaje kodiranja JavaScript je napisati funkcijo, ki določa, ali se katera koli pesem na seznamu predvajanja ponavlja. To pregleduje vsako pesem eno za drugo in ugotavlja, ali obstaja referenca, ki se vrača na prejšnjo pesem. Celo izkušeni programerji se lahko spotaknejo ob tankosti referenc objektov in nadzora zanke, medtem ko poskušajo rešiti to na videz preprosto težavo v JavaScriptu.
Težava pogosto izhaja iz načina izražanja iteracijske logike, zlasti iz načina obravnavanja referenc med objekti. V tem primeru je rešitev odvisna od vaše sposobnosti razumevanja, kako JavaScript upravlja sklice na objekte znotraj zank. Osredotočili se bomo na to, kako ustrezno prerazporediti in slediti tem sklicem na seznamu predvajanja, ko bomo preučevali rešitev.
Težavo bomo podrobno razčlenili, pogledali pomanjkljivosti obstoječe rešitve in ponudili delujočo rešitev za to ponavljajočo se oviro seznama predvajanja v razpravi, ki sledi. S tem popravkom bo funkcija lahko natančno prepoznala ciklične reference na seznamu predvajanja in ustvarila želeni rezultat.
Ukaz | Primer uporabe |
---|---|
Set() | Objekt JavaScript Set() se uporablja za shranjevanje edinstvenih podatkov. Za pomoč pri prepoznavanju ciklov seznama predvajanja je v primeru uporabljen za sledenje ogledanim skladbam, pri čemer se zagotovi, da se nobena pesem ne predvaja znova. |
has() | Objekt Set() ima funkcijo has(). Preveri, ali v množici obstaja določen element. Tukaj preveri, ali je bila pesem že slišana, kar pomeni, da se seznam predvajanja ponavlja. |
add() | Objekt Set() ima funkcijo has(). Preizkuša, ali dani element obstaja v množici. Tukaj preveri, ali je bila pesem že slišana, kar pomeni, da se seznam predvajanja ponavlja. |
two-pointer technique | Ta metoda, ki se včasih imenuje algoritem zaznavanja ciklov Floyd-Warshall, krmari po seznamu predvajanja z uporabo dveh kazalcev: počasnega in hitrega. Za učinkovito zaznavanje zank se počasni kazalec premakne za en korak, medtem ko se hitri kazalec premakne za dva koraka. |
nextSong | Razred Song ima edinstveno lastnost, imenovano nextSong, ki se sklicuje na skladbo, ki je na seznamu predvajanja za njim. Omogoča posnemanje strukture povezanega seznama, v katerem se vsaka pesem zaporedno nanaša na vsako drugo skladbo. |
describe() | Funkcija describe() ogrodja za testiranje Mocha se uporablja za organizacijo povezanih testov enot. Teste razdeli na logične kategorije, takšne sezname predvajanja, ki se ponavljajo, in tiste, ki se ne ponavljajo. |
it() | V Mochi se definicija testnega primera imenuje it(). Označuje poseben primer, ki ga je treba preizkusiti, na primer zagotoviti, da funkcija pravilno prepozna ponavljajoči se seznam predvajanja. |
assert.strictEqual() | Ta metoda je iz modula assert v Node.js. V tem primeru preveri predvideni rezultat funkcije ponavljanja seznama predvajanja tako, da ugotovi, ali sta dve vrednosti popolnoma enaki. |
Razumevanje zaznavanja cikla seznama predvajanja v JavaScriptu
Prvi ponujeni skript uporablja pristop povezanega seznama za prepoznavanje pesmi, ki se ponavljajo na seznamu predvajanja, tako da vsako pesem obravnava kot vozlišče. Struktura razreda JavaScript se uporablja za izdelavo a Pesem predmet, ki posnema tok seznama predvajanja od skladbe do skladbe, tako da shrani ime pesmi in sklic na naslednjo skladbo. Glavna komponenta rešitve sledi glasbi, ki ste jo prej srečali z uporabo a Set. Za ponavljanje pesmi uporabljamo zanko while in preverjamo, ali je bila trenutna pesem že slišana. Če je tako, nakažemo, da se seznam predvajanja ponavlja, tako da vrnemo true.
Floydov algoritem zaznavanja ciklov, običajno imenovan tehnika dveh kazalcev, se uporablja na drugi način. S to metodo se dva kazalca premikata po seznamu predvajanja z različnimi hitrostmi: eden preskoči dve pesmi in se premakne naprej eno pesem naenkrat. Ti kazalci se bodo sčasoma srečali, če obstaja cikel, kar pomeni, da se seznam predvajanja ponavlja. Ker ni treba shranjevati videnih skladb, je ta način prostorsko učinkovitejši in je zato boljša možnost za večje sezname predvajanja.
Te rešitve tudi prikazujejo, kako ustvariti povezane sezname v JavaScriptu, ker nextSong lastninske povezave Pesem nasprotovati drugemu. Zaznavanje cikla v prvem skriptu izkorišča nastavljeno strukturo. Ker nizi zagotavljajo edinstvenost, lahko takoj ugotovimo, ali je pesem že predvajana, ko je dodana v niz. Zaradi tega so kompleti še posebej koristni. To nam pomaga prepoznati, kdaj se cikel začne, in preprečuje, da bi se ujeli v neskončno zanko.
Nazadnje, testi enot, ki so vključeni za obe strategiji, zagotavljajo, da je rešitev točna v različnih nastavitvah. Za preverjanje kode smo uporabili ogrodje za testiranje Mocha. Node.js trditi modul se uporablja za potrditev, da so rezultati v skladu s pričakovanji, in Mocha's opisati in to funkcije se uporabljajo za logično strukturiranje testov. Preizkusi enot igrajo ključno vlogo v razvojnem procesu, saj potrjujejo, da funkcija deluje po pričakovanjih tako za ponavljajoče se kot za neponavljajoče se sezname predvajanja, kar daje zagotovilo o odpornosti rešitve.
Zaznavanje ponavljajočih se pesmi na seznamu predvajanja z JavaScriptom
Objektno usmerjeno programiranje v JavaScriptu z zankami While
class Song {
constructor(name) {
this.name = name;
this.nextSong = null;
}
/
* @return {boolean} true if the playlist is repeating, false if not.
*/
isRepeatingPlaylist() {
let seenSongs = new Set();
let current = this;
while (current) {
if (seenSongs.has(current)) {
return true; // Playlist is repeating
}
seenSongs.add(current);
current = current.nextSong;
}
return false; // Playlist is not repeating
}
}
// Testing the solution
let first = new Song("Hello");
let second = new Song("Eye of the Tiger");
let third = new Song("Third");
first.nextSong = second;
second.nextSong = third;
third.nextSong = first; // Creates a loop
console.log(first.isRepeatingPlaylist()); // true
Alternativni pristop: uporaba dveh kazalcev za zaznavanje cikla
Zaznavanje cikla povezanega seznama z algoritmom Floyd-Warshall
class Song {
constructor(name) {
this.name = name;
this.nextSong = null;
}
/
* @return {boolean} true if the playlist is repeating, false if not.
*/
isRepeatingPlaylist() {
let slow = this;
let fast = this;
while (fast !== null && fast.nextSong !== null) {
slow = slow.nextSong; // move slow pointer by 1 step
fast = fast.nextSong.nextSong; // move fast pointer by 2 steps
if (slow === fast) {
return true; // Loop detected
}
}
return false; // No loop
}
}
// Testing the solution
let first = new Song("Hello");
let second = new Song("Eye of the Tiger");
let third = new Song("Third");
first.nextSong = second;
second.nextSong = third;
third.nextSong = first; // Creates a loop
console.log(first.isRepeatingPlaylist()); // true
Testiranje enote za zaznavanje zanke seznama predvajanja
Preizkušanje funkcije isRepeatingPlaylist z Node.js in Mocha
const assert = require('assert');
describe('isRepeatingPlaylist', function () {
it('should return true for a repeating playlist', function () {
let first = new Song('Song A');
let second = new Song('Song B');
let third = new Song('Song C');
first.nextSong = second;
second.nextSong = third;
third.nextSong = first; // Creates a loop
assert.strictEqual(first.isRepeatingPlaylist(), true);
});
it('should return false for a non-repeating playlist', function () {
let first = new Song('Song A');
let second = new Song('Song B');
let third = new Song('Song C');
first.nextSong = second;
second.nextSong = third;
assert.strictEqual(first.isRepeatingPlaylist(), false);
});
});
Napredne tehnike zaznavanja zanke seznama predvajanja v JavaScriptu
Razumevanje osnovne strukture seznama predvajanja v smislu povezani seznami je zanimiv del zaznavanja zanke seznama predvajanja. Vsaka pesem na neponavljajočem se seznamu predvajanja je povezana s tisto pred njo, dokler ni več sklicevanj na to pesem in se seznam konča. Cikel sprožimo, ko se pesem nanaša nazaj na prejšnjo, zato je seznam v nekem smislu "neskončen". Iskanje tovrstnih ciklov ni pomembno le za sezname predvajanja, ampak tudi za algoritme za dodeljevanje pomnilnika in usmerjanje.
Te cikle je mogoče učinkovito zaznati v JavaScriptu z uporabo kazalnih tehnik in struktur, kot je Set. Ker zagotavlja edinstvenost in preprečuje, da bi se pesmi ponovno ogledale brez začetka cikla, je Set je še posebej koristno. Nasprotno pa je Floyd-Warshallov pristop z dvema kazalcema prostorsko optimizirana rešitev, pri kateri imata dve gibljivi referenci ali kazalci različni hitrosti. Če se združijo, se najde vzorec.
Če so ti algoritmi učinkovitejši, je mogoče hitro pregledati sezname predvajanja, ki vsebujejo na tisoče pesmi. Tehnika dveh kazalcev je popolna za situacije, ko je uporaba pomnilnika težava, ker ima O(n) časovno kompleksnost in O(1) prostorsko kompleksnost. Poleg tega je preverjeno, da naše rešitve pravilno delujejo z uporabo enotnih testov, kot so tisti, narejeni z Mocha, ki zaznajo ponavljajoče se in ne ponavljajoče se sezname predvajanja v različnih nastavitvah.
Pogosta vprašanja o zaznavanju cikla seznama predvajanja
- Kaj je cikel na seznamu predvajanja?
- Ko se skladba na seznamu predvajanja sklicuje na prejšnjo skladbo, se ustvari zankasto zaporedje, imenovano cikel.
- Kako tehnika dveh kazalcev zazna cikel?
- Hiter kazalec premakne dva koraka, počasen pa korak za korakom s tehniko dveh kazalcev. Če se združita, je prisotna zanka.
- Zakaj je a Set uporablja za zaznavanje cikla?
- V a Set, so shranjene različne vrednosti. Koristno je beleženje poslušane glasbe. Če se glasba ponovno predvaja, se prepozna zanka.
- Ali lahko ta algoritem uporabim za druge aplikacije?
- Dejansko je veliko dela vloženega v prepoznavanje zank v povezanih seznamih, upravljanje pomnilnika in omrežno usmerjanje z uporabo tehnike zaznavanja ciklov.
- Zakaj uporabljamo while zanke pri prehodu seznama predvajanja?
- Po seznamu predvajanja lahko iterativno pregledujemo z while zanke, dokler ne najdemo cikla ali pridemo do konca seznama.
Končne misli o zaznavanju ponavljajočih se seznamov predvajanja
Morda bo težko prepoznati cikle na seznamu predvajanja, zlasti pri krmarjenju po upravljanju referenc objektov JavaScript. Vendar pa lahko učinkovito rešimo to težavo in poenostavimo našo kodo z uporabo tehnik, kot je uporaba tehnike dveh kazalcev ali sledenje referencam pesmi z naborom.
Poznavanje delovanja teh tehnik vam bo pomagalo pri učinkovitejšem reševanju težav, ne glede na to, ali se tega lotevate za razgovor o kodiranju ali za praktično uporabo. Uporaba učinkovitih struktur, kot je Set in razumevanje, kako kazalci pomagajo pri odkrivanju cikla, sta glavni lekciji, ki se ju je treba naučiti.
Viri in reference za cikel zaznavanja seznama predvajanja
- Navdih za algoritme za zaznavanje ciklov predvajanja so črpali iz pogostih težav s povezanimi seznami in tehnik, kot je algoritem Floyd-Warshall. Izvedite več o povezanih seznamih in zaznavanju ciklov v tem obsežnem viru: Zaznavanje cikla na Wikipediji .
- Drug odličen vir, ki se uporablja, je dokumentacija JavaScript za objekte Set, ki igrajo ključno vlogo pri pristopu prve rešitve: JavaScript je nastavljen na MDN .
- Za podrobnejše tehnike testiranja v JavaScriptu je bila uradna dokumentacija podjetja Mocha ključni vir za razumevanje strukturiranja testov in trditev: Ogrodje za testiranje Mocha .
- Raziščite ta vodnik o tehniki dveh kazalcev, ki se pogosto uporablja za težave z zaznavanjem ciklov in je ena izmed učinkovitih metod, uporabljenih tukaj: Zaznaj zanko na povezanem seznamu .