2011-01-17 17 views
6

bir ay önce bazı Google PTO üyeleri tarafından röportaj yaptım. sorulardan biri oldu: js içinde yinelemeli bir dize ters çevirin ve bu benim çözüm olduBir dizgeyi ters çevirin: javascript'te yineleme vs yineleme

büyük Ç gösterimde tarafından çalışma süresini açıklamak:

function invert(s){ 
    return (s.length > 1) ? s.charAt(s.length-1)+invert(s.substring(0,s.length-1)) : s; 
} 

Oldukça basit, sanırım.

Ve büyük notasyonla ilgili olarak, hızlı bir şekilde O (n) 'yi çalışma süresi lineer olarak girişe bağlı olarak yanıtladım. - Sessizlik - ve sonra, bana sordu, eğer iterasyon ile uygularsanız, çalışma süresi açısından farklılıklar nelerdir?

Bazen derleyicinin yinelemeyi yinelemeye "çevirir" (bazı programlama dili kursu anıları), bu durumda yineleme ve özyineleme konusunda hiçbir farklılık olmadığını söylerim. Btw bu özel soruyla ilgili hiçbir geri bildirim almadığımdan ve görüşmeci “tamam” ya da “hayır” diye cevap vermediyse, belki benimle aynı fikirde olup olmadığınızı bilmek isterim ya da bana farklılıklar olup olmadığını bana açıklayabilirseniz 2 tür uygulama.

Çok teşekkürler ve Saygılar!

+0

ama, bu bir olmaz özyinelemede çağrı yığını nesil havai olabilir bir döngü. –

+0

Btw, 3 kez erişmek yerine s.length depolamış olabilirdim, ama belki de optimizasyona gerek yoktu ... (Üzgünüm, her zaman erken bir şekilde optimize ederim, bu benim birçok hatamdan biridir) –

+0

@Martin: çağrı yığını üretimi bir * çok * minik havai olmak. Her halükarda, buradaki kod, n kere yinelenir, n kere yinelenen bir döngü olarak aynı hesaplama karmaşıklığına sahiptir. – Juliet

cevap

3

Çözümünüz bana göre O (n ²) görünüyor. substring numaralı çağrı büyük olasılıkla O'dur (n) - tipik bir uygulama yeni bir dizeye yer ayırır ve ardından alt dizeyi kopyalar. [Ama yorumlara bakın.] Dize birleştirme + muhtemelen O (n) olacaktır. Hatta length'un O (n) olması ihtimali de olabilir ama bence bu pek de olası değil.


Bir derleyicinin yinelemeyi yinelemeye dönüştürebileceği düşüncesini gündeme getirdiniz. Bu doğrudur, ancak işlevsel dillerin ve Şemanın dışında nadiren uygulanır; ve tipik olarak uygulanan tek dönüşüm, kuyruk yinelemesi eliminasyonu'dur. Kodunuzda, özyineleme kuyruk pozisyonunda değil: invert özyinelemeli çağrısından sonra hala + hesaplamanız gerekir. Yani kuyruk özyineleme ortadan kaldırılması sizin kodunuz için geçerli değildir. Bu, invert'un yinelemeli sürümünün farklı bir şekilde uygulanması gerektiği anlamına gelir. Bu, invert'un yinelemeli sürümünün farklı bir şekilde uygulanması gerektiği anlamına gelir. Aynı veya farklı karmaşıklığa sahip olabilir, biz onu görene kadar diyemeyiz.

+1

Gerçekten mi? Javascript'i çok iyi bilmiyorum, ama bildiğim birçok dilde, alt dizgisi O (1), orjinal dizgenin saklanmasını paylaşıyor (ya dizgiler değişmez ya da alt dizeler yazma üzerine yazılır). – sepp2k

+0

Soru hangi JavaScript uygulamasının kullanıldığını söylemedi, dolayısıyla benim uyarılar. (Bir keresinde JavaScript'i uyguladı ve benim 'substring' O (n) idi, bu yüzden en az bir JS uygulaması doğrudur!) Ancak 'substring' konusunda haklıysanız bile, '+' nin O olması muhtemeldir. n). –

+0

@ sepp2k: O (1) alt dizgisiyle ilgili sorun, çöp toplama işlemini gerçekten sıkıştırmasıdır. Birden çok megabaytlık bir dize ayırırsam, ortadaki 5 karakteri çekin ve daha sonra orijinal dizenin kapsam dışına çıkmasına izin verin; bu, küçük alt dizgenin hala etrafta dolaştığı için hala koleksiyon için uygun değildir. –

0

Bir yan notta, derleyicinin yinelemenizi döngü olarak uygulamasına izin veren kuyruk özünürlüğünü kullanmak için yığında durumunuz kalmaz. Bu sorunu gidermek için size işlevine ek parametre olarak "devlet" geçirebilirsiniz: Emin değilim

function invert(sofar, s) 
{ 
    return (s.length > 0) ? invert(s.charAt(s.length-1)+sofar, s.substring(0,s.length-1)) : sofar; 
} 
+2

Çoğu (eğer varsa) JavaScript motorlarının Kuyruk Çağrısı Optimizasyonunu gerçekleştirdiğini düşünmüyorum – jimr

+0

Bu doğru, sadece OP, – BrokenGlass

+0

numaralı sorudaki optimizasyon olasılıklarını gündeme getirdi. Haklısınız @BrokenGlass. Örnek, 'optimize edilebilir' herşeyi optimize etmeli: D .. Bu türden şeyler hakkında bir şey yapıp yapamayacağımı bilmek istediğimi düşünüyorum. Btw bu durumda özyinelemenin "dönüştürülmediğini mi düşünüyorsun?" "tekrarı mı? – stecb