2011-10-31 8 views
5

Questa è una domanda molto strana e abbastanza specifica.Non si utilizza un'istruzione if in Java

definitiva sto cercando di scrivere un convertito programma che prende in sorgente di Java, e la trasforma in modo tale che non fa uso (tra l'altro)

  • Array
  • Loop
  • metodi definiti dall'utente
  • Se dichiarazioni

questa è una sfida che mi ero prefissato, dopo il mio insegnante mi ha detto che era impossibile scrivere un programma senza usare queste cose.

La maggior parte di questi ha funzionato, inclusa la funzione di inlining e la sostituzione di array, tuttavia non riesco a capire come gestire un'istruzione if.

In C++ userei etichette e gotos e forse?: Tuttavia Java non supporta le istruzioni GOTO.

mia domanda è questa: Data una sezione di codice,

if(CONDITION) 
{ 
    //More code in here 
} 

Come può trasformarla in modo tale che essa è funzionalmente la stessa, tuttavia non utilizzare la parola chiave se. Si noti che anche le strutture del ciclo sono fuori questione.

Dato questo, sarebbe facile creare altre istruzioni if ​​else. Tuttavia, non sono sicuro di come creare loop utilizzando questo, poiché non esiste alcuna istruzione GOTO e i metodi non sono disponibili.

Edit: prega di notare che gli interruttori sono, inoltre, non autorizzati, né è la ricorsione (esclusa dal fatto che non si può definire metodi utente, e una funzione principale ricorsiva non avrebbe funzionato con tutti i programmi) L'operatore?: non funziona per tutte le situazioni. AFAIK non è possibile chiamare una funzione void con?: Poiché desidera assegnare un valore come parte della sua operazione.

Queste condizioni provengono dall'IB Computer Science SL richiede corso, sto prendendo HL e come classe stavamo ridendo dei fattori di "padronanza" per SL che includono dichiarazioni "se" (E se in realtà 3/15 di loro sono i metodi definiti dall'utente con parametri e tipi di ritorno). La sfida è efficacemente a FAIL un test di padronanza in SL mentre sta ancora producendo un programma che funzioni correttamente.

Risposta: (By bdares)

String result = (CONDITION)?"0":"A"; 
try{ 
    Integer.parseInt(result); 
    //Condition is true 
} catch(NumberFormatException e){ 
    //Condition is false 
} 
+0

Un ciclo che utilizza goto ed etichette è ancora un ciclo, utilizza solo un'altra sintassi. Per eliminare veramente i loop, è necessario srotolarli, ovvero inserire le istruzioni nel ciclo da eseguire in sequenza. Quale sarà impossibile per cicli infiniti (ad esempio 'while (1)'.) –

+1

@JoachimPileborg non è vero; non esclude di usare i loop di librerie pre-scritte, quindi potrebbe (teoricamente) scrivere 'java.util.Loop (myObject.class, 10);' se tale libreria esistesse. Così com'è, può hackerare una soluzione da, ad esempio, oggetti della collezione. – bdares

+0

http: //www.antiifcampaign.com/comunque si tratta di OOP migliorato (rimuovendo la logica tesa e nascosta annidata come IF attraverso un design migliore) – earcam

risposta

2
if(A) { 
    X(); 
} 
else{ 
    Y(); 
} 

può essere convertito in:

A?X():Y(); 

È possibile nidificare questi tutto quello che volete, o semplicemente rimuovere un lato della : e ottenere un semplice if. I condizionali sono facili.

Se si vuole farlo funzionare per i metodi vuoti, ecco un modo:

String result = A?"0":"A"; 
try{ 
    Integer.parseInt(result); 
    X(); 
} catch(NumberFormatException e){ 
    Y(); 
} 
+0

Bene, posso usare anche LinkedList invece degli array. E?: Non può essere usato per istruzioni if ​​complesse, senza dover precedere ogni riga con var = (condizione)?/* Chiama una funzione o qualcosa qui * /: var – James

+0

non ha escluso la ricorsione. – stivlo

+0

@stivlo Suppongo di no ... se è consentito utilizzare "funzioni di libreria" (presumendo SE6 o SE7), ci sono molti modi per eseguire il loop di codice arbitrario. Ho interpretato male le sue restrizioni. – bdares

2

È possibile utilizzare l'operatore condizionale e di un interruttore:

switch(CONDITION ? 1 : 0) 
{ 
    case 1: 
     //... true code 
     break; 
    case 0: 
     //... false code 
     break; 
} 

Per i loop si può srotolare il codice a un numero massimo predefinito e utilizzare le interruzioni etichettate per saltare in anticipo il codice srotolato in base ad alcune condizioni. Puoi usare break per terminare qualsiasi blocco di codice in Java e non solo cicli.

Il linguaggio Java non ha goto ma la macchina virtuale ha, così si potrebbe naturalmente anche generare istruzioni JVM direttamente, anche se questo sarebbe non molto diverso da un compilatore Java regolare che si traduce anche tutti i se un loop in istruzioni di salto.

+0

accetta solo 'int' come argomento (anche' String' in java 7) . –

+0

Grazie, ma le istruzioni switch sono un altro costrutto "nella lista nera". Avrei dovuto accennare, aggiornerò la domanda – James

1

Non sono sicuro che sia possibile scrivere un intero programma utile senza utilizzare un'istruzione if. Tuttavia, penso che quello che potrebbe ottenere il tuo insegnante è che puoi scrivere codice per seguire lo stesso percorso "logico" usando un approccio più orientato agli oggetti al posto di un'istruzione if. Per esempio:

public interface Moveable { 
    void move(int x, int y); 
} 

public class Ball implements Moveable { 
    private int x; 
    private int y; 

    public void move(int x, int y) { 
    this.x = x; 
    this.y = y; 
    } 
} 

public class NullMoveable { 
    public void move(int x, int y) { 
    // Do nothing. 
    } 
} 

... e poi nel codice dell'applicazione principale:

Moveable mv = new NullMoveable();  
// Move object; don't care if it's a Ball or a NullMoveable 
// so no need to explicitly check with an if-statement. 
mv.move(10, 50); 

Il principio è che i percorsi meno possibili ci sono nel codice (a causa di istruzioni if) più facile è per testare e mantenere.

+0

Ho familiarità con OOP e ho esperienza con la programmazione. Tuttavia, Java è lontano dalla mia lingua principale. Come nota a margine il convertitore attualmente supporta la rimozione di classi utente e strutture, non più OOP :) – James

0

In alcuni casi, è possibile utilizzare la manipolazione dei bit. Per esempio:

if(x > 0) // positive number 
{ 
    isPositive = true; 
} 
else // negative number 
{ 
    isPositive = flase; 
} 

è equivalente a:

isPositive = (x >> 31) == 0; 

EDIT:

Questo è solo un esempio, naturalmente si può fare molto di più complessa manipolazione dei bit con una dichiarazione al posto di farlo usando un sacco di istruzioni if.

+0

divertente, dipende dalla dimensione del numero intero, quando puoi semplicemente scrivere 'isPositive = x> 0;' – stivlo

+0

@stivlo Questo è solo un Ad esempio, è possibile eseguire manipolazioni di bit molto più complesse con una sola istruzione invece di farlo usando una serie di istruzioni if. –

0

Se si hanno permesso di usare le classi interne anonime (questi probabilmente classificano come i metodi definiti dall'utente, ma ti permettono di essere il giudice):

if(COND) { 
    X(); 
} else { 
    Y(); 
} 

diventa:

ifReplacement(COND, 
       new Runnable() { public void run() { X();}}, 
       new Runnable() { public void run() { Y();}}); 

con la firma:

public static void ifReplacement(boolean condition, 
           Runnable ifBranch, 
           Runnable elseBranch) 

Naturalmente, lambda JDK8 renderebbe questo molto più bello:

ifReplacement(COND,()->X(),()->Y()); 
Problemi correlati