Ciklinių grojaraščių aptikimas „JavaScript“.
Ciklų ar pakartojimų paieška yra dažna problema atsakant į kodavimo interviu klausimus, ypač tuos, kuriems reikia duomenų struktūrų, pvz., susietų sąrašų. Ši problema dažniausiai iškyla grojaraščiuose, kur dainos gali susieti viena su kita nuorodų grandinėje. Sakoma, kad grojaraštis pasikartoja, jei dainoje nurodoma ankstesnė daina.
Šio „JavaScript“ kodavimo pratimo tikslas – parašyti funkciją, kuri nustato, ar grojaraščio dainos kartojasi. Tai peržiūri kiekvieną dainą po vieną ir patikrinama, ar yra nuoroda, kuri grįžta į ankstesnę dainą. Net patyrę programuotojai gali suklupti dėl objektų nuorodų ir kilpos valdymo subtilybių, bandydami išspręsti šią, atrodytų, paprastą „JavaScript“ problemą.
Dažnai problema kyla dėl to, kaip išreiškiama iteracijos logika, ypač dėl to, kaip tvarkomos nuorodos tarp objektų. Šiuo atveju sprendimas priklauso nuo jūsų gebėjimo suprasti, kaip JavaScript tvarko objektų nuorodas kilpų viduje. Nagrinėdami sprendimą sutelksime dėmesį į tai, kaip tinkamai perskirstyti ir sekti šias nuorodas grojaraštyje.
Mes išsamiai išnagrinėsime problemą, pažvelgsime į esamo sprendimo trūkumus ir pasiūlysime veiksmingą šios pasikartojančios grojaraščio kliūties sprendimą tolesnėje diskusijoje. Su šiuo pataisymu funkcija galės tiksliai atpažinti ciklines nuorodas grojaraštyje ir pateikti numatytą rezultatą.
komandą | Naudojimo pavyzdys |
---|---|
Set() | JavaScript Set() objektas naudojamas unikaliems duomenims saugoti. Kad būtų lengviau nustatyti grojaraščio ciklus, pavyzdyje jis naudojamas žiūrimoms dainoms sekti, užtikrinant, kad nė viena daina nebūtų grojama dar kartą. |
has() | Objektas Set() turi funkciją has(). Jis patikrina, ar rinkinyje yra konkretus elementas. Čia jis patikrina, ar daina jau girdėta, o tai rodo, kad grojaraštis kartojasi. |
add() | Objektas Set() turi funkciją has(). Jis patikrina, ar rinkinyje yra tam tikras elementas. Čia jis patikrina, ar daina jau girdėta, o tai rodo, kad grojaraštis kartojasi. |
two-pointer technique | Šis metodas, kuris kartais vadinamas Floydo-Warshall ciklo aptikimo algoritmu, naršo grojaraštį naudodamas dvi nuorodas: lėtą ir greitą. Norint efektyviai aptikti kilpas, lėta žymeklis juda vienu žingsniu, o greitoji – dviem žingsniais. |
nextSong | Dainų klasė turi unikalią savybę, vadinamą nextSong, kuri nurodo dainą, kuri grojaraštyje yra po jos. Tai leidžia imituoti susieto sąrašo struktūrą, kurioje kiekviena daina paeiliui nurodo kiekvieną kitą dainą. |
describe() | Mocha testavimo sistemos funkcija description() naudojama susijusiems vienetų testams organizuoti. Testai suskirstomi į logines kategorijas: grojaraščius, kurie kartojasi, ir tuos, kurie nesikartoja. |
it() | Mochoje bandomojo atvejo apibrėžimas vadinamas it(). Tai nurodo konkretų atvejį, kurį reikia išbandyti, pvz., įsitikinkite, kad funkcija tinkamai atpažįsta pasikartojantį grojaraštį. |
assert.strictEqual() | Šis metodas yra iš Node.js patvirtinimo modulio. Šiuo atveju jis patikrina numatytą grojaraščio pasikartojimo funkcijos rezultatą, nustatydamas, ar dvi reikšmės yra griežtai lygios. |
Grojaraščio ciklo aptikimo „JavaScript“ supratimas
Pirmajame siūlomame scenarijuje naudojamas susieto sąrašo metodas, siekiant nustatyti dainas, kurios kartojasi grojaraštyje, kiekvieną dainą laikant mazgu. „JavaScript“ klasės struktūra naudojama konstruoti a Daina objektas, kuris imituoja grojaraščio eigą iš takelio į takelį, išsaugodamas dainos pavadinimą ir nuorodą į kitą dainą. Pagrindinis sprendimo komponentas įrašo anksčiau sutiktą muziką naudojant a Nustatyti. Naudojame ciklą, kad kartotume dainas, patikrindami, ar dabartinė daina buvo girdėta anksčiau. Jei taip, nurodome, kad grojaraštis kartojasi, grąžindami teisingą.
Floydo ciklo aptikimo algoritmas, paprastai vadinamas dviejų žymeklių technika, naudojamas antruoju būdu. Naudojant šį metodą, du rodyklės grojaraštyje juda skirtingu greičiu: vienas praleidžia dvi dainas ir po vieną dainą juda pirmyn. Šios nuorodos galiausiai susitinka, jei yra ciklas, o tai rodo, kad grojaraštis kartojasi. Kadangi nebūtina išsaugoti matomų dainų, šis metodas taupo erdvę, todėl yra geresnis pasirinkimas didesniems grojaraščiams.
Šie sprendimai taip pat parodo, kaip sukurti susietus sąrašus „JavaScript“, nes kita daina nuosavybės nuorodos Daina prieštarauti kitam. Ciklo aptikimas pirmame scenarijuje naudojasi nustatytos struktūros pranašumais. Kadangi rinkiniai užtikrina unikalumą, įtraukę į rinkinį galime akimirksniu nustatyti, ar daina jau grojama. Dėl to rinkiniai yra ypač naudingi. Tai padeda mums atpažinti, kada prasideda ciklas, ir neleidžia patekti į begalinę kilpą.
Galiausiai, abiejų strategijų vienetų testai garantuoja, kad sprendimas yra tikslus įvairiuose nustatymuose. Norėdami patikrinti savo kodą, naudojome Mocha testavimo sistemą. Node.js tvirtinti modulis naudojamas patvirtinti, kad išėjimai yra tokie, kokių tikėtasi, ir Mocha apibūdinti ir tai funkcijos naudojamos logiškai struktūrizuoti testus. Vienetų testai vaidina lemiamą vaidmenį kūrimo procese, nes jie patvirtina, kad funkcija veikia taip, kaip tikėtasi tiek pasikartojantiems, tiek nesikartojantiems grojaraščiams, užtikrinant sprendimo atsparumą.
Pasikartojančių dainų aptikimas grojaraštyje naudojant „JavaScript“.
Objektinis programavimas JavaScript naudojant Nors Loops
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
Alternatyvus metodas: dviejų rodyklių naudojimas ciklui aptikti
Susieto sąrašo ciklo aptikimas naudojant Floydo-Warshall algoritmą
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
Grojaraščio ciklo aptikimo vienetų tikrinimas
Funkcijos isRepeatingPlaylist testavimas su Node.js ir 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);
});
});
Išplėstinė grojaraščio kilpos aptikimo technika „JavaScript“.
Suprasti pagrindinę grojaraščio struktūrą susietus sąrašus yra įdomi grojaraščio ciklo aptikimo dalis. Kiekviena daina nesikartojančiame grojaraštyje susieja su prieš ją esančia daina, kol nebelieka nuorodų į tą dainą ir sąrašas baigiasi. Mes inicijuojame ciklą, kai daina grįžta į ankstesnę, todėl tam tikra prasme sąrašas yra „begalinis“. Tokių ciklų paieška svarbu ne tik grojaraščiams, bet ir atminties paskirstymui bei maršruto parinkimo algoritmams.
Šiuos ciklus galima efektyviai aptikti „JavaScript“, naudojant rodyklės metodus ir struktūras, tokias kaip Nustatyti. Kadangi tai užtikrina unikalumą ir neleidžia pakartotinai peržiūrėti dainų nepradėjus ciklo, Nustatyti yra ypač naudingas. Ir atvirkščiai, Floyd-Warshall dviejų rodyklių metodas yra erdvėje optimizuotas sprendimas, kuriame dvi judančios nuorodos arba rodyklės turi skirtingą greitį. Jei jie susijungia, randamas modelis.
Padarius šiuos algoritmus efektyvesnius, galima greitai peržiūrėti grojaraščius, kuriuose yra tūkstančiai dainų. Dviejų žymeklių technika puikiai tinka tais atvejais, kai atminties panaudojimas yra problema, nes ji turi O(n) laiko sudėtingumą ir O(1) erdvės sudėtingumą. Be to, patikrinta, ar mūsų sprendimai tinkamai veikia, naudojant vienetų testus, pvz., pagamintus naudojant „Mocha“, kurie aptinka grojaraščius su kilpomis ir be kilpų įvairiuose nustatymuose.
Dažniausiai užduodami klausimai apie grojaraščio ciklo aptikimą
- Kas yra ciklas grojaraštyje?
- Kai daina grojaraštyje nurodo ankstesnę dainą, sukuriama ciklo seka, vadinama ciklu.
- Kaip dviejų taškų technika aptinka ciklą?
- Greitas žymeklis juda dviem žingsniais, o lėtas – vienu žingsniu, naudojant dviejų žymeklio techniką. Jei jie susijungia, yra kilpa.
- Kodėl yra a Set naudojamas ciklo aptikimui?
- A Set, išsaugomos skirtingos reikšmės. Įsidėmėti klausomą muziką yra naudinga. Ciklas atpažįstamas, jei vėl grojama muzika.
- Ar galiu naudoti šį algoritmą kitoms programoms?
- Iš tiesų, daug darbo tenka susietų sąrašų kilpų identifikavimui, atminties valdymui ir tinklo maršruto parinkimui naudojant ciklo aptikimo techniką.
- Kodėl naudojame while kilpos per grojaraščius?
- Galime pakartotinai peržiūrėti grojaraštį naudodami while kilpa, kol rasime ciklą arba pateksime į sąrašo pabaigą.
Paskutinės mintys apie pasikartojančių grojaraščių aptikimą
Gali būti sunku nustatyti grojaraščio ciklus, ypač naršant „JavaScript“ objektų nuorodų tvarkyme. Tačiau galime efektyviai išspręsti šią problemą ir supaprastinti savo kodą naudodami tokius metodus kaip dviejų žymeklių technikos taikymas arba dainų nuorodų sekimas naudojant rinkinį.
Žinodami, kaip veikia šie metodai, galėsite efektyviau spręsti problemas, nesvarbu, ar tai sprendžiate kodavimo interviu, ar praktiniais tikslais. Naudojant efektyvias struktūras, pvz Nustatyti ir suprasti, kaip rodyklės padeda aptikti ciklą, yra pagrindinės pamokos, kurias reikia išmokti.
Grojaraščio ciklo aptikimo šaltiniai ir nuorodos
- Įkvėpimas grojaraščio ciklo aptikimo algoritmams buvo paimtas iš įprastų susietų sąrašų problemų ir metodų, tokių kaip Floydo-Warshall algoritmas. Sužinokite daugiau apie susietus sąrašus ir ciklo aptikimą šiame išsamiame šaltinyje: Ciklo aptikimas Vikipedijoje .
- Kitas puikus naudojamas šaltinis yra „JavaScript“ dokumentacija, skirta Set objektams, kurie atlieka pagrindinį vaidmenį sprendžiant pirmąjį metodą: „JavaScript“ nustatytas MDN .
- Norėdami gauti išsamesnius „JavaScript“ testavimo metodus, „Mocha“ oficiali dokumentacija buvo pagrindinis šaltinis norint suprasti testo struktūrą ir tvirtinimus: Mocha testavimo sistema .
- Išnagrinėkite šį vadovą apie dviejų rodyklių metodą, kuris dažnai naudojamas ciklo aptikimo problemoms spręsti ir yra vienas iš veiksmingų čia naudojamų metodų: Aptikti kilpą susietame sąraše .