2011-03-25 5 views
0

J'essaie d'augmenter les performances de la mise à jour(); fonction ci-dessous. Les nombres à l'intérieur de la variable mathNumber proviendront d'un NSString créé à partir d'un champ de texte. Même si j'utilise cinq nombres, je voudrais pouvoir exécuter n'importe quel montant que l'utilisateur insère dans un champ de texte. Comment puis-je accélérer le code dans update()? avec C et/ou Objective-C? Je voudrais aussi travailler sur le Mac et l'iPhone.Résoudre des équations mathématiques à partir d'un champ de texte

typedef struct { 
    float *left; 
    float *right; 
    float *equals; 
    int operation; 
} MathVariable; 

#define MULTIPLY 1 
#define DIVIDE 2 
#define ADD 3 
#define SUBTRACT 4 

MathVariable *mathVariable; 
float *mathPointer; 
float newNumber; 

void init(); 
void update(); 
float solution(float *left, float *right, int *operation); 

void init() 
{ 
    float *mathNumber = (float *) malloc(sizeof(float) * 9); 

    mathNumber[0] =-1.0; 
    mathNumber[1] =-2.0; 
    mathNumber[2] = 3.0; 
    mathNumber[3] = 4.0; 
    mathNumber[4] = 5.0; 
    mathNumber[5] = 0.0; 
    mathNumber[6] = 0.0; 
    mathNumber[7] = 0.0; 
    mathNumber[8] = 0.0; 

    mathVariable = (MathVariable *) malloc(sizeof(MathVariable) * 4); 

    mathVariable[0].equals = &mathPointer[5]; 
    mathVariable[0].left = &mathPointer[2]; 
    mathVariable[0].operation = MULTIPLY; 
    mathVariable[0].right = &mathPointer[3]; 

    mathVariable[1].equals = &mathPointer[6]; 
    mathVariable[1].left = &mathPointer[1]; 
    mathVariable[1].operation = SUBTRACT; 
    mathVariable[1].right = &mathPointer[5]; 

    mathVariable[2].equals = &mathPointer[7]; 
    mathVariable[2].left = &mathPointer[0]; 
    mathVariable[2].operation = ADD; 
    mathVariable[2].right = &mathPointer[6]; 

    mathVariable[3].equals = &mathPointer[8]; 
    mathVariable[3].left = &mathPointer[7]; 
    mathVariable[3].operation = MULTIPLY; 
    mathVariable[3].right = &mathPointer[4]; 

    return self; 
} 

// This is updated with a timer 
void update() 
{ 
    int i; 

    for (i = 0; i < 4; i++) 
    { 
     *mathVariable[i].equals = solution(mathVariable[i].left, mathVariable[i].right, &mathVariable[i].operation); 
    } 

    // Below is the equivalent of: newNumber = (-1.0 + (-2.0 - 3.0 * 4.0)) * 5.0; 
    // newNumber should equal -75 
    newNumber = mathPointer[8]; 
} 

float solution(float *left, float *right, int *operation) 
{ 
    if ((*operation) == MULTIPLY) 
    { 
     return (*left) * (*right); 
    } 
    else if ((*operation) == DIVIDE) 
    { 
     return (*left)/(*right); 
    } 
    else if ((*operation) == ADD) 
    { 
     return (*left) + (*right); 
    } 
    else if ((*operation) == SUBTRACT) 
    { 
     return (*left) - (*right); 
    } 
    else 
    { 
     return 0.0; 
    } 
} 

EDIT:

Je dois d'abord vous dire merci pour tous vos messages aimables. C'est le premier forum que j'ai eu des gens qui ne me disent pas que je suis un idiot complet. Désolé pour le retour moi-même; Je ne me suis pas rendu compte que c'était aussi un forum objectif-C (donc pourquoi j'ai utilisé C en hâte). J'ai mon propre analyseur qui est lent mais je ne suis pas concerné par sa vitesse. Tout ce que je veux c'est accélérer la fonction update() car elle ralentit tout et 90% des objets l'utilisent. En outre, j'essaie de le faire fonctionner plus vite avec les appareils iOS car je ne peux rien compiler dans les zones de texte. Si vous avez d'autres conseils sur la mise à jour() plus vite je vous remercie.

Merci encore, Jonathan

EDIT 2:

Eh bien, je l'ai eu à courir plus vite en le changeant de:

int i; 

for (i = 0; i < 4; i++) 
{ 
*mathVariable[i].equals = solution(*mathVariable[i].left, *mathVariable[i].right, mathVariable[i].operation); 
} 

Pour:

*mathVariable[0].equals = solution(*mathVariable[0].left, *mathVariable[0].right, mathVariable[0].operation); 
*mathVariable[1].equals = solution(*mathVariable[1].left, *mathVariable[1].right, mathVariable[1].operation); 
*mathVariable[2].equals = solution(*mathVariable[2].left, *mathVariable[2].right, mathVariable[2].operation); 
*mathVariable[3].equals = solution(*mathVariable[3].left, *mathVariable[3].right, mathVariable[3].operation); 

est-il toute autre façon de l'incrémenter aussi vite que les nombres préchargés dans le tableau lik e ci-dessus?

+0

Vous avez 'return self' dans une fonction C, et cela ressemble à une confusion entre' mathNumber' et 'mathPointer' ...Je suppose que ce n'est pas le vrai code? – CRD

+1

Évaluation des chaînes comme des maths? Il y a du code pour ça ... http://github.com/davedelong/DDMathParser –

Répondre

0

Votre code est un mélange de styles et contient certaines utilisations injustifiées de pointeurs (par exemple, lors du passage de operation à solution). Il n'est pas clair pourquoi vous passez les flotteurs par référence, mais peut-être que vous avez l'intention que ces changements soient changés et que l'expression soit réévaluée? Vous trouverez ci-dessous quelques changements à la fois pour ranger et accélérer le processus - le coût de tout cela n'est pas élevé et vous pourriez être coupable d'une optimisation prématurée. Comme l'a commenté @Dave, il existe des bibliothèques pour faire l'analyse syntaxique pour vous, mais si vous ciblez des expressions mathématiques simples, un analyseur/évaluateur basé sur une pile de précédence d'opérateur est assez facile à coder.

Suggestion 1: utiliser enum - nettoyant:

typedef enum { MULTIPLY, DIVIDE, ADD, SUBTRACT } BinaryOp; 

typedef struct 
{ 
    float *left; 
    float *right; 
    float *equals; 
    BinaryOp operation; 
} MathVariable; 

Suggestion 2: utiliser switch - plus propre et probablement plus rapide ainsi:

float solution(float left, float right, int operation) 
{ 
    switch(operation) 
    { 
     case MULTIPLY: 
      return left * right; 
     case DIVIDE: 
      return left/right; 
     case ADD: 
      return left + right; 
     case SUBTRACT: 
      return left - right; 
     default: 
      return 0.0; 
    } 
} 

Remarque J'ai aussi enlevé passant des pointeurs, l'appel est maintenant :

*mathVariable[i].equals = solution(*mathVariable[i].left, 
            *mathVariable[i].right, 
            mathVariable[i].operation); 

Maintenant, une personne OO va probablement s'opposer (: -)) au switch (ou le if/else) et arguez que chaque nœud (votre MathVariable) doit être une instance qui sait comment effectuer sa propre opération. Une personne C peut vous suggérer d'utiliser des pointeurs de fonction dans le nœud afin qu'ils puissent effectuer leur propre opération. Tout cela est du design et vous devrez le comprendre vous-même.

Questions connexes