Den vanlige FizzBuzz -implementeringen jeg så, bruker en sjekk på% 15 for utskrift «FizzBuzz»

Vil du gi meg beskjed hvis det er noe galt / bedre med denne tilnærmingen?

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)); } } } } 

Kommentarer

  • Versjonen din er optimalisert for datamaskinen. Winston ‘ s versjon er optimalisert for mennesket. Må stole på en kompilator at den kan gjøre en god jobb med å stokke om og optimalisere koden. Det er også mulig at en enkelt io-setning vil fungere raskere enn to separate. Du bør kjøre din versjon mot den andre.
  • Jeg ‘ Jeg vil fortelle deg hvorfor jeg liker versjonen min bedre (bare for intervjuskonteksten) 1) vedlikeholdsevne – du kan eksternalisere Fizz og Buzz som strenger, du trenger ikke ‘ ikke å eksternalisere FizzBuzz 2) TØRR, en bruker som skriver ovennevnte kode tenker på å ikke gjenta seg selv, noe jeg liker
  • +1 men bruk en StringBuilder og ikke 100 * System.out.println (..), og Integer.valueOf (i)
  • @ cl-r takk, jeg vil beholde den på originalen, så kommentarene fremdeles gir mening, takk for tilbakemeldingen
  • FizzBuzzEnterpriseEdition er den beste implementeringen som finnes: github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition ; D

Svar

La oss sammenligne versjonen din med % 15 -versjonen:

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)); } } } } 

% 15 versjonen er sim pler og lettere å lese. Denne versjonen beskriver problemet pent i de 4 forskjellige sakene, og håndterer hvert tilfelle. Derimot introduserer din versjon et boolsk logisk flagg (som jeg anser som et betydelig antimønster) og en ikke helt intuitiv avhengighet av rekkefølgen på if-setningene.

Kommentarer

  • 15 er et » magisk nummer » her. Jeg ‘ jeg foreslår at du bruker (3 * 5) i stedet. Kompilatoren skal konvertere den til 15 …
  • @Ron – Så er det, "FizzBuzz", etter disse kriteriene. Ikke at du ‘ feil nødvendigvis, men for disse typene ‘ trivia ‘ spørsmål, nødvendigheten av å erklære alt blir vanligvis litt avslappet. For strengt tatt, for eksempel på produksjonsnivåkode, skal alle tallene og strengene det er referert til / skrevet ut her, fanges opp som navngitte konstanter.
  • @ X-Zero, vil du fange 3 som en konstant, hva vil du kalle det?
  • @Winston – Det generelle problemet med dette er at det ‘ er i utgangspunktet en ‘ konstruert ‘ eksempel, så det kan være vanskelig å få gode navn på dette. Spesielt som det som testen har, egentlig er ‘ flere ‘ kontroller – ved å fortsette å dekomponere dette vil det sannsynligvis resultere i en slags matrise / tabellstruktur (ja … jeg vet … på vei til verdensromsarkitektur). Så, MATCH kanskje? CONDITION? Urgh. Det er grunnen til at slike konvensjoner blir avslappet for slike tester; testen er for grunnleggende kodingsevne, ikke (nødvendigvis) full abstraksjon ferdigheter.
  • Jeg vil flytte if-for-15 inne hvis-for-5, hvis du kan ‘ t dele et tall med 3, kan absolutt ‘ t dele med 15, lagre 4/5 sjekker for alle tall

Svar

Det ser bra ut. String.valueOf() er unødvendig. System.out.println(i) vil skrive ut det samme, men det er fortsatt OK. Denne testen brukes bare for å sikre at intervjuobjektet kan skrive kode slik det tilknyttede nettstedet sier:

Denne typen spørsmål vil ikke identifisere gode programmerere, men det vil identifisere de svake. Og det er definitivt et skritt i riktig retning.

Svar

De er absolutt ikke perfekte, men jeg har prøvd noen måter å optimalisere testen på, her er resultatet (jeg har hatt tall for å holde oversikt over gode svar), og jeg bruker en StringBuilder for å unngå initialisering av output IO:

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; } } } 

Og utgangen:

------ 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 

Kommentarer

  • StringBuilder er basert på en char[16]. Du bør sette startkapasiteten til en verdi som er større enn strengen du vil opprette – eller forverre ytelsen, ettersom StringBuilder må vokse (tildel nye char[], kopier gamle data). Du bør også være oppmerksom på hvordan [System.nanoTime()] (stas-blogspot.blogspot.com /2012/02/what-is-behind-systemnanotime.html) fungerer og problemene den har.Og jeg ‘ vil råde deg til å gjøre mange flere iterasjoner. Jeg tror du hovedsakelig måler tiden for System.out.println() akkurat nå, de andre operasjonene tar sannsynligvis veldig lite tid i forhold til et systemanrop.
  • Fortell meg, har du noen gang hørt om konseptet over-engineering …?
  • @Max jeg gjør, men er dette nettstedet gjort for noen undersøkelser eller ikke? Er det for behagelige øyne, eller for å prøve å forstå hvordan noen måter er bedre? Så du kan velge og sammenligne raskere, lett å lese eller forhøre koden for å finne manglende optimalisering.
  • Se Regler for optimalisering . IMHO Winston Ewert ga det beste svaret.
  • Forklar matematikk med tabellkode takk?

Svar

Her er en versjon som «s (IMHO) er litt bedre for mennesker enn din og bedre for datamaskiner også:

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); } } } 

Kommentarene gir informasjon til mennesker (men de kunne fremdeles se det alene) og det er bare en System.out.println samtale per i.

EDIT: Dette er en annen måte å fizz-buzz (fokus: TØRK):

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); } } } 

EDIT 2: enda en, ved hjelp av StringBuilder, TØRR også:

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); } } 

Kommentarer

  • StringBuilder virker en raskere tilnærming enn + = i dette tilfellet
  • @EranMedan – Er du sikker på dette? StringBuilder er bra fordi N legger til ikke

t fører tilNtildelinger, men her erNmaksimalt 2, som er en lite nok antall til at det sannsynligvis ikke vant ‘ t, og det ‘ er ganske sannsynlig å være 1, noe som ikke betyr noen forskjell kl. alt (eller kanskje verre, daStringBuildersannsynligvis gjør en ekstra tildeling for det ene vedlegget).

  • @asveikau – du har sannsynligvis rett, jeg antar at dette vil være over optimalisering for å finne ut nøyaktig hva som er raskere 🙂
  • Jeg ‘ er klar over StringBuilder – som jeg bruker hele tiden i String heavy code – og tenkte med linjene til asveikau . += er mindre » støyende » (også grunnen til at jeg unngikk Integer.toString()) og den vant ‘ t gjør stor forskjell da det ‘ er høyst to sammenkoblinger . Btw .: Jeg ‘ d har brukt StringBuilder slik: erklær før sløyfen, initialiser med kapasitet satt til 8, ryddet og gjenbruk pr. iterasjon. Hvis du oppretter den i sløyfen, ville ‘ ikke forbedres mye.
  • se ovenfor for en annen versjon som bruker StringBuilder – men bare ett anrop til System.out.println(...).
  • Legg igjen en kommentar

    Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *