2010-02-22 5 views
0
main()  
{  
    .... 

    i = index;     
    while (i < j)  
    {  
    if (ip[i] == "/")  
     {  
     ip[i - 1] = (double.Parse(ip[i - 1])/double.Parse(ip[i + 1])).ToString(); 

     for (int k = i; k < (ip.Length - 2); k++) 
     { 
      ip[k] = ip[k + 2]; 
     } 

     Array.Resize(ref ip, ip.Length - 2);  
     j = j - 2;  
     i--;  
     }  
    i++;  
    }  
} 

Pour le code ci-dessus, je voulais appliquer les concepts d'Oop.Retour des tableaux

Ce motif se répète presque 5 fois (pour div, mul, add, sub, pow) dans le programme principal, avec quatre lignes identiques.

Pour diminuer le nombre de lignes et là pour augmenter l'efficacité du code, j'ai écrit la même chose comme ça.

i = index; 

while (i < j) 

    {  
    if (ip[i] == "/")  
    {  
     ip[i - 1] = (double.Parse(ip[i - 1])/double.Parse(ip[i + 1])).ToString();  

     ext.Resize(ip, i, j); 
    }  
    i++;  
    } 


class ext 
{ 
    public static void Resize(string [] ip, int i, int j)  
    { 

     for (int k = i; k < (ip.Length - 2); k++) { ip[k] = ip[k + 2]; }  
     Array.Resize(ref ip, ip.Length - 2);  
     j=j-2; i--;  
     return ;  
    }  
} 

Le code a été compilé avec succès. Mais le problème est que les changements dans le tableau et les variables qui ont eu lieu dans la fonction appelée ne sont pas reflétés dans le programme principal. Le tableau et les variables restent inchangés dans le programme principal. Je ne suis pas capable de comprendre où je me suis trompé. Plz guide moi.

Merci.

+0

Heh? Où 'j' est-il défini dans' ext.Resize'? 'Array.Resize' est si Esoteric il n'a même pas une description sur MSDN: http://msdn.microsoft.com/en-us/library/1ffy6686%28VS.85%29.aspx – Kobi

+0

@Kobi: Je vois une description: http://msdn.microsoft.com/en-us/library/bb348051.aspx –

+0

Jon - qui est mieux. Merci. Je suppose que Google s'est mal conduit. – Kobi

Répondre

3

Je ne pense pas que vous comprenez ce que ref paramètres sont pour - une fois que vous comprenez les (et le fait que les tableaux ne peuvent se changer en taille), vous verrez pourquoi Array.Resize prend un paramètre ref. Jetez un oeil à mon parameter passing article pour plus de détails.

Vous pouvez corriger votre code en changeant comme ceci:

public static void Resize(ref string [] ip, ref int i)  
{ 
    for (int k = i; k < (ip.Length - 2); k++) 
    { 
     ip[k] = ip[k + 2]; 
    }  
    Array.Resize(ref ip, ip.Length - 2);  
    j = j - 2; 
    i--; 
} 

et de l'appeler comme ceci:

ext.Resize(ref ip, ref i); 

Cependant, je pense que l'utilisation d'une structure de données plus appropriée serait votre code plus clair. Y at-il une raison pour laquelle vous ne pouvez pas utiliser un List<string> à la place?

+0

J'ai moins d'idée concernant les listes. Je ne sais pas comment les utiliser correctement. L'utilisation de listes est donc meilleure dans ce scénario? – Gokul

+1

@Nani: Eh bien, vous pouvez ajouter et supprimer des éléments d'une liste '' , ce qui est exactement à quoi il ressemble que vous devez faire. Je vous suggère fortement de vous renseigner davantage sur les collections intégrées avant d'écrire des quantités importantes de code de production. –

1

Vous supprimez des éléments au milieu d'une séquence, réduisant ainsi sa longueur. Donc, en utilisant des tableaux rend juste difficile.

Si ip était un List<string> au lieu de string[]:

i = index;     
while (i < j)  
{  
    if (ip[i] == "/")  
    {  
     ip[i - 1] = (double.Parse(ip[i - 1])/double.Parse(ip[i + 1])).ToString(); 

     ip.RemoveAt(i); 
     ip.RemoveAt(i); 
     j = j - 2;  
     i--;  
    }  
    i++;  
} 

On dirait que vous êtes l'analyse d'une expression arithmétique. Cependant, vous pourriez vouloir autoriser les parenthèses à contrôler l'ordre d'évaluation, et cela va être difficile avec cette structure.

Mise à jour: Ce que votre code dit est: Vous allez scanner une séquence de chaînes. Partout dans cette séquence, vous pouvez trouver un symbole d'opérateur de division: /. Si oui, vous supposez que les choses de chaque côté peuvent être analysées avec double.Parse. Mais:

(5 + 4)/(6 - 2) 

Les jetons de chaque côté du / dans cet exemple sont ) et ( donc double.Parse ne va pas travailler.

Donc, je vérifie juste que vous avez une autre couche de logique en dehors de ce qui concerne les parenthèses. Par exemple, vous utilisez peut-être d'abord une descente récursive, puis vous exécutez uniquement le morceau de code que vous avez publié sur des séquences qui ne contiennent aucune parenthèse.

Si vous voulez la chose à être plus « objecty », vous pouvez traiter le problème comme l'un de transformer une séquence de jetons dans un arbre. Chaque noeud de l'arbre peut être évalué. La valeur du noeud racine est la valeur de l'expression entière. Un nombre est un nœud très simple qui évalue la valeur du nombre lui-même. Un opérateur a deux nœuds enfants. Les groupes de parenthèses disparaîtraient simplement de l'arbre - ils sont utilisés pour guider la façon dont vous le construisez. Si j'ai un peu de temps, je pourrais développer cela en un court exemple.

Et une autre question: comment allez-vous diviser la chaîne entière en jetons?

+0

En passant, vous n'utilisez pas le même tableau. 'Array.Resize' crée un nouveau tableau, avec le contenu de l'ancien tableau copié dedans. –