A közös FizzBuzz megvalósítás, amelyet láttam, a% 15 ellenőrzését használja a “FizzBuzz” nyomtatása

Tudatja velem, hogy van-e valami baj / jobb ezzel a megközelítéssel?

public class FizzBuzz { public static void main(String[] args) { for (int i = 1; i <= 100; i++) { boolean fizzOrBuzz = false; if (i % 3 == 0) { System.out.print("Fizz"); fizzOrBuzz = true; } if (i % 5 == 0) { System.out.print("Buzz"); fizzOrBuzz = true; } if (fizzOrBuzz) { System.out.println(); } else { System.out.println(String.valueOf(i)); } } } } 

Megjegyzések

  • Az Ön verziója a számítógépre van optimalizálva. A Winston ‘ verziója az ember számára van optimalizálva. Meg kell bíznom egy fordítóban, hogy jó munkát végezhet a kód újbóli keverésében és optimalizálásában. Lehetséges, hogy egyetlen io utasítás gyorsabban fog működni, mint két külön. Versenyeznie kell a verziójával a másikkal.
  • Megmondom, miért szeretem jobban a verziómat (csak az interjú kontextusában) 1) karbantarthatóság – a Fizz-et és a Buzz-ot stringként vonhatja ki, nem kell ‘ nem szükséges a FizzBuzz 2) DRY-t külsõvé tenni. A fenti kódot író felhasználó azon gondolkodik, hogy ne ismételje meg önmagát, ami tetszik
  • +1, de használjon StringBuilder és ne 100 * System.out.println (..) és Integer.valueOf (i)
  • @ cl-r köszönöm, megtartom az eredetiben, így a megjegyzéseknek még mindig lesz értelme, köszönöm a visszajelzést
  • A FizzBuzzEnterpriseEdition a legjobb megvalósítás: github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition ; D

Válasz

Hasonlítsuk össze a verziódat a % 15 verzióval:

public class FizzBuzz { public static void main(String[] args) { for (int i = 1; i <= 100; i++) { if (i % 15 == 0) { System.out.println("FizzBuzz") } else if (i % 3 == 0) { System.out.println("Fizz"); } else if (i % 5 == 0) { System.out.println("Buzz"); } else { System.out.println(String.valueOf(i)); } } } } 

A verzió sim pler és könnyebben olvasható. Ez a verzió szépen körvonalazza a problémát a 4 különböző esetre, és mindegyiket kezeli. Ezzel szemben az Ön verziója bevezet egy logikai logikai jelzőt (amelyet jelentős anti-mintának tartok), és nem teljesen intuitív függőséget az if utasítások sorrendjétől.

Megjegyzések

  • 15 egy ” varázsszám ” itt. ‘ javaslom a (3 * 5) használatát. A fordítónak 15-re kell konvertálnia …
  • @Ron – Így van, "FizzBuzz", e kritérium alapján. Nem mintha ‘ szükségszerűen tévedne , de az ilyen típusú ‘ trivia ‘ kérdések, minden nyilatkozatának szükségessége általában enyhül. Például szigorúan véve a gyártási szintű kódok esetében minden az itt hivatkozott / kinyomtatott számokat és karakterláncokat megnevezett állandóként kell rögzíteni.
  • @ X-Zero, elkapná a 3 konstansként, mit nevezhetne?
  • @Winston – Ezzel az általános probléma az, hogy ‘ ez alapvetően egy ‘ kitalált ‘ példa, így nehéz lehet ehhez neveket szerezni. Különösen, mivel a teszt lényegében ‘ többszörös ‘ ellenőrzés – ennek tovább bontása valószínűleg valamiféle tömb / tábla struktúrát eredményezne (igen … tudom … a világűr-építészet felé tartok). Tehát, talán MATCH? CONDITION? Urgh. Ezért enyhítik az ilyen típusú egyezményeket az ilyen típusú tesztek során; a teszt az alapvető kódolási képességre vonatkozik, nem (feltétlenül) a teljes absztrakciós készségekre.
  • Ha-15-et mozgatnék if-5-be, ha tudsz ‘ t osztani egy számot 3-mal, minden bizonnyal ‘ t fel lehet osztani 15-vel, az összes szám 4/5-ös ellenőrzését mentheti el

Válasz

Nagyon jól néz ki. A String.valueOf() felesleges, a System.out.println(i) ugyanazt nyomtatná, de még mindig rendben van. Ezt a tesztet csak arra használják, hogy megbizonyosodjon arról, hogy az interjúalany képes-e kódot írni, ahogy a linkelt webhely mondja:

Ez a fajta kérdés nem azonosítja a nagyszerű programozókat, de azonosítani fogja a gyengéket. És ez mindenképpen egy lépés a helyes irányba.

Válasz

Ők biztosan nem tökéletesek, de kipróbáltam néhány módszert a teszt optimalizálására, itt az eredmény (számom volt arra, hogy a jó válaszokat nyomon kövessem), és egy StringBuildert használok az IO kimenet inicializálásának elkerülésére:

package exercices; import java.util.Hashtable; import org.memneuroo.outils.communs.utilitaires.EnvPrm; public class FizzBuzz { // time for cum with nbIter=30 > 300; 30 ~= 3000 static final int nbIter = 30; static final String sep = "_"; static long ifNested() { final StringBuilder sb = new StringBuilder(); final long t = System.nanoTime(); for (int i = 0; i < nbIter; i++) { sb.append(// i % 15 == 0 // ? "FizzBuzz" // : (i % 3 == 0 // ? "Fizz"// : (i % 5 == 0// ? "Buzz" // : i)));// sb.append(sep); } final long totT = System.nanoTime() - t; System.out.format("ifNested\t%20d\n", totT); // sb.append(EnvPrm.NEWLINE); System.out.println(sb.toString()); return totT; } static long stringPlus() { final StringBuilder sb = new StringBuilder(); final long t = System.nanoTime(); for (int i = 0; i < nbIter; i++) { String x = ""; x += (i % 3 == 0) ? "Fizz" : ""; x += (i % 5 == 0) ? "Buzz" : ""; if (x.isEmpty()) { // MODIF x += Integer.toString(i); } sb.append(x);// sb.append(sep); } final long totT = System.nanoTime() - t; System.out.format("stringPlus\t%20d\n", totT); // sb.append(EnvPrm.NEWLINE); System.out.println(sb.toString()); return totT; } static long withIf() { final StringBuilder sb = new StringBuilder(); final long t = System.nanoTime(); for (int i = 0; i < nbIter; i++) { if (i % 3 == 0) { sb.append("Fizz"); if (i % 5 == 0) { sb.append("Buzz"); } } else if (i % 5 == 0) { sb.append("Buzz"); } else { sb.append(i); }// sb.append(sep); } final long totT = System.nanoTime() - t; System.out.format("withIf\t\t%20d\n", totT); // sb.append(EnvPrm.NEWLINE);System.out.println(sb.toString()); return totT; } static long withArray() { final String[] lis = {"FizzBuzz", "", "", "Fizz", "", "Buzz", "Fizz", "", "", "Fizz", "Buzz", "", "Fizz", "", "",}; final StringBuilder sb = new StringBuilder(); final long t = System.nanoTime(); for (int i = 0; i < nbIter; i++) { final String pos = lis[i % 15]; sb.append(((0 == pos.length()) ? i : pos));// sb.append(sep); } final long totT = System.nanoTime() - t; System.out.format("withArray\t%20d\n", totT); // sb.append(EnvPrm.NEWLINE); System.out.println(sb.toString()); return totT; } static long withTable() { final Hashtable<Integer, String> ht = new Hashtable<>(8); ht.put(0, "FizzBuzz"); ht.put(3, "Fizz"); ht.put(5, "Buzz"); ht.put(6, "Fizz"); ht.put(9, "Fizz"); ht.put(10, "Buzz"); ht.put(12, "Buzz"); final StringBuilder sb = new StringBuilder(); final long t = System.nanoTime(); for (int i = 0; i < nbIter; i++) { final String s = ht.get(i % 15); // MODIF // http://www.developpez.net/forums/d1196563-2/java/general-java/if-null-object-if-objet-null/#post6561766 // sb.append((null == s ? i : s));// sb.append(sep); if (null == s) { sb.append(i); } else { sb.append(s); } } final long totT = System.nanoTime() - t; System.out.format("withTable\t%20d\n", totT); // sb.append(EnvPrm.NEWLINE); System.out.println(sb.toString()); return totT; } static int recursive(final StringBuilder sb, final int n) { if (0 == n) { return 1; } if (n % 3 == 0) { sb.insert(0, "Fizz"); if (n % 5 == 0) { sb.insert(0, "Buzz"); } } else if (n % 5 == 0) { sb.insert(0, "Buzz"); } else { sb.insert(0, n); } return n + recursive(sb, n - 1); } static long recursive() { final StringBuilder sb = new StringBuilder(""); final long t = System.nanoTime(); recursive(sb, nbIter); final long totT = System.nanoTime() - t; System.out.format("recursive\t%20d\n", totT); sb.append(EnvPrm.NEWLINE); System.out.println(sb.toString()); return totT; } /*** @param args */ public static void main(final String[] args) { long cum = 0L, cum2 = 0L; for (int i = 0; i < 5; i++) { System.out.println("------ " + i + " -----"); final long totSb = stringPlus(); final long totIn = ifNested(); final long totWi = withIf(); final long totWa = withArray(); final long totWt = withTable(); final long totRe = recursive(); System.out.format("... stringPlus/withIf :%5d\n", (totSb * 100) / totWi); System.out.format("... ifNested/withIf :%5d\n", (totIn * 100) / totWi); System.out.format("... withArray/withIf :%5d\n", (totWa * 100) / totWi); System.out.format("... withTable/withIf :%5d\n", (totWt * 100) / totWi); System.out.format("... recursive/withIf :%5d\n", (totRe * 100) / totWi); cum += totIn + totSb + totWi + totWa + totWt + totRe; System.out.println("CUMUL (SECOND) == " + cum / 100000000 + "." + cum % 100000000 + "\t , diff: " + (cum - cum2)); cum2 = cum; } } } 

És a kimenet:

------ 0 ----- stringPlus 529397 ifNested 643657 withIf 27657 withArray 43581 withTable 40788 recursive 87441 12Fizz4BuzzFizz78FizzBuzz11Fizz1314BuzzFizz1617Fizz19BuzzFizz2223FizzBuzz26Fizz2829BuzzFizz ... stringPlus/withIf : 1914 ... ifNested/withIf : 2327 ... withArray/withIf : 157 ... withTable/withIf : 147 ... recursive/withIf : 316 CUMUL (SECOND) == 0.1372521 , diff: 1372521 ------ 1 ----- stringPlus 345295 ifNested 88280 withIf 88279 withArray 88838 withTable 101689 recursive 93308 12Fizz4BuzzFizz78FizzBuzz11Fizz1314BuzzFizz1617Fizz19BuzzFizz2223FizzBuzz26Fizz2829BuzzFizz ... stringPlus/withIf : 391 ... ifNested/withIf : 100 ... withArray/withIf : 100 ... withTable/withIf : 115 ... recursive/withIf : 105 CUMUL (SECOND) == 0.2178210 , diff: 805689 ------ 2 ----- stringPlus 380216 ifNested 36597 withIf 20953 withArray 60063 withTable 91352 recursive 111467 12Fizz4BuzzFizz78FizzBuzz11Fizz1314BuzzFizz1617Fizz19BuzzFizz2223FizzBuzz26Fizz2829BuzzFizz ... stringPlus/withIf : 1814 ... ifNested/withIf : 174 ... withArray/withIf : 286 ... withTable/withIf : 435 ... recursive/withIf : 531 CUMUL (SECOND) == 0.2878858 , diff: 700648 ------ 3 ----- stringPlus 489168 ifNested 29613 withIf 22070 withArray 27099 withTable 27378 recursive 91911 12Fizz4BuzzFizz78FizzBuzz11Fizz1314BuzzFizz1617Fizz19BuzzFizz2223FizzBuzz26Fizz2829BuzzFizz ... stringPlus/withIf : 2216 ... ifNested/withIf : 134 ... withArray/withIf : 122 ... withTable/withIf : 124 ... recursive/withIf : 416 CUMUL (SECOND) == 0.3566097 , diff: 687239 ------ 4 ----- stringPlus 143035 ifNested 24025 withIf 15924 withArray 23187 withTable 26819 recursive 87162 12Fizz4BuzzFizz78FizzBuzz11Fizz1314BuzzFizz1617Fizz19BuzzFizz2223FizzBuzz26Fizz2829BuzzFizz ... stringPlus/withIf : 898 ... ifNested/withIf : 150 ... withArray/withIf : 145 ... withTable/withIf : 168 ... recursive/withIf : 547 CUMUL (SECOND) == 0.3886249 , diff: 320152 

megjegyzések

  • A StringBuilder egy char[16] alapú. A kezdeti kapacitást nagyobb értékre kell állítania, mint a létrehozni kívánt karakterlánc – vagy rontja a teljesítményt, mivel a StringBuildernek növekednie kell (rendeljen hozzá új char[], másolja a régi adatokat). Arról is tisztában kell lennie, hogyan [System.nanoTime()] (stas-blogspot.blogspot.com /2012/02/what-is-behind-systemnanotime.html) működik és a benne rejlő problémák.És én ‘ azt tanácsolom, hogy végezzen sokkal több iterációt. Azt hiszem, hogy elsősorban a System.out.println() idejét méri jelenleg, a többi művelet valószínűleg nagyon kevés időt vesz igénybe egy rendszerhíváshoz képest.
  • Mondja meg, volt-e már valaha hallott már a over-engineering …?
  • @Max I koncepcióról, de ezt a weboldalt egyes kutatások végzik, vagy sem? Kényelmes szemek, vagy hogy megpróbálja megérteni, hogy egyes módszerek jobbak? Így kiválaszthatja és összehasonlíthatja a gyorsabb, könnyen olvasható szöveget, vagy lekérdezheti a kódot, hogy megtalálja a hiányzó optimalizálást.
  • Lásd: Az optimalizálás szabályai . Az IMHO Winston Ewert adta a legjobb választ.
  • kérem, magyarázza el a matematikát a Táblázat kóddal?

Válasz

Itt van az a verzió (IMHO), amely egy kicsit jobb az emberek számára, mint a tiéd, és jobb a számítógépeknek is:

public class FizzBuzz { public static void main(String[] args) { for (int i = 1; i <= 100; i++) { String value; switch (i % 15) { case 3: case 6: case 9: case 12: // divisible by 3, print Fizz value = "Fizz"; break; case 5: case 10: // divisible by 5, print Buzz value = "Buzz"; break; case 0: // divisible by 3 and by 5, print FizzBuzz value = "FizzBuzz"; break; default: // else print the number value = Integer.toString(i); } System.out.println(value); } } } 

A megjegyzések információkat nyújtanak embereknek (de még így is láthatták egyedül), és System.out.println csak i hívás van.

SZERKESZTÉS: Ez a fizz-buzz (fókusz: SZÁRAZ) másik módja:

public class FizzBuzz { public static void main(String[] args) { final String EMPTY = ""; for (int i = 1; i <= 100; i++) { String value = EMPTY; if (i % 3 == 0) value += "Fizz"; if (i % 5 == 0) value += "Buzz"; if (value == EMPTY) value += i; System.out.println(value); } } } 

2. SZERKESZTÉS: még egy, a , DRY is:

public class FizzBuzz { public static void main(String[] args) { StringBuilder builder = new StringBuilder(1000); for (int i = 1; i <= 100; i++) { final int length = builder.length(); if (i % 3 == 0) builder.append("Fizz"); if (i % 5 == 0) builder.append("Buzz"); if (length == builder.length()) builder.append(i); builder.append("\n"); } System.out.println(builder); } } 

Megjegyzések

  • A StringBuilder gyorsabb megközelítésnek tűnik mint + = ebben az esetben
  • @EranMedan – Biztos ebben? StringBuilder jó, mert a N hozzáfűz nem

tNkiosztáshoz vezet, itt azonbanNlegfeljebb 2, ami egy Elég kicsi szám ahhoz, hogy valószínűleg ‘ t elnyerjen, és ‘ valószínűleg 1, ami azt jelenti, hogy nincs különbség mind (vagy még rosszabb, mivel aStringBuildervalószínűleg extra allokációt végez az 1 függelékhez).

  • @asveikau – valószínűleg igazad van, gondolom, ez lesz az optimalizálás felett, hogy pontosan megtudjam, melyik a gyorsabb 🙂
  • Tisztában vagyok a StringBuilderrel – amelyet mindig a String heavy kódban használok -, és végiggondoltam a asveikau sorai. A += kevesebb ” zajos ” (ez az oka annak is, hogy elkerültem a Integer.toString()) és ‘ nem fog nagy különbséget tenni, mivel ‘ legfeljebb két összefűzés lehetséges . Btw .: I ‘ d a StringBuildert így használtam: deklarálok a ciklus előtt, inicializálok 8 értékre állítva, törlöm és újra felhasználom ismétlés. A ciklus belsejében létrehozása nem javítana ‘.
  • lásd fentebb egy másik verziót a StringBuilder használatával – de csak egy hívás a System.out.println(...) címre.
  • Vélemény, hozzászólás?

    Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük