2009-11-10 8 views
-1

MISE À JOUR:C# devinette: interface d'implémentation

Cette question n'est pas une question de devoirs. Et pas apparemment étanche ... Je voulais une discussion sur la représentation interne. Bien sûr: le add1000 doit ajouter 1000.

** S'il vous plaît répondre dans l'esprit de cette question ... Faire Waterproof rendrait cette question sans plus aucune raison .. ** Vous pouvez battre un nombre décimal pur représentation Changing internal representation in runtime MISE à JOUR 2: voir

Créer un type qui implémente cette interface:

interface INumber 
    { 
     void add1000(); 
     void SetValue(decimal d); 
     decimal GetValue();   
    } 

pour que j'itère aussi vite que possible de 0 à 10 milliards (américain milliards, donc jusqu'à 10E9) dans ce pour loo p:

private static void DoSomeAdding(INumber n) 
     { 
      Debug.Assert(n.GetValue()==0); 

      for (long i=0; i<10000000000; i += 1000) 
      { 
       n.add1000(); 
      } 

      Debug.Assert(n.GetValue() == 10000000000); 

     } 

Ainsi, vous pouvez l'appeler comme:

DoSomeAdding(new YourNumberClass()); 
+2

est ce devoir? –

+2

Euh ... pourquoi puis-je demander? – Lazarus

+0

Peut-être une pratique en chargement paresseux. – Anton

Répondre

6

Comme la solution d'Anton, mais avec un peu plus de soin :) Oh, et j'ai changé les noms pour être plus .NET-like.

public Number : INumber 
{ 
    private decimal value = 0m; 
    private int thousands = 0; 

    public void Add1000() 
    { 
     thousands++; 
    } 

    void SetValue(decimal d) 
    { 
     value = d; 
     thousands = 0; 
    } 

    decimal GetValue() 
    { 
     // Careful of the overflow... (do multiplication in decimal) 
     value += thousands * 1000m; 
     thousands = 0; 
     return value; 
    } 
} 
+0

J'ai lu les faits Skeet donc je vais ajuster mon chronomètre si votre solution ne bat pas la mienne – Peter

+0

+1 8 (Mais dans ce cas une représentation mixte est encore un peu plus rapide) – Peter

+0

En fait il est possible qu'il y ait un moyen très rapide convertir un nombre entier de milliers en nombre décimal en utilisant une certaine quantité de ruse ... mais je serais probablement coller avec ce code. –

13
public Cheating : INumber 
{ 
    static int timesCalled = 0; 

    public void add1000() {} 
    public void SetValue(decimal d) {} 

    public decimal GetValue() 
    { 
     if (timesCalled == 0) 
     { 
      timesCalled += 1; 
      return 0; 
     } 

     return 1000000000; 
    } 
} 
+5

Je suppose que l'on pourrait soutenir que ce n'est pas * tricher * mais simplement une solution précoce pour une conception pilotée par les tests qui passe le test unique pour une interface. –

+0

Je pense que cela défait le point. – Anton

+0

soupir ......................... – Peter

4
public class JNumber : INumber 
{ 
    decimal num = 0; 

    public void add1000() 
    { 
     num = 10000000000; 
    } 

    public void SetValue(decimal d) 
    { 
    } 

    decimal GetValue() 
    { 
     return num; 
    } 
} 

... la tricherie, mais passe.

+0

Je pense que cela défait le point. – Anton

1

Je pense que vous avez besoin de plus d'exigences. Comme l'écrit la solution la plus rapide serait quelque chose comme:

class MyNumberClass { 
    bool is_ten_billion = false; 
    int GetValue() { 
     if(is_ten_billion) return 10000000000; 
     is_ten_billion = true; 
     return 0; 
    } 

    decimal add1000() {} 

    void setValue(decimal d) {} 
} 

De cette façon, l'optimiseur peut disposer des appels à add1000(), puis de la boucle tout à fait.

+0

Je pense que cela vainc le point. – Anton