tags:

views:

126

answers:

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

For the above code I wanted to apply Oop's concepts.

This pattern repeats almost 5 times (for div,mul,add,sub,pow) in main program, with four identical lines .

To decrease the no of lines and there by to increase efficiency of code, I wrote the same like this.

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

Code got compiled successfully. But the problem is the changes in array and variables that took place in called function are not reflecting in main program. The array and variables are remaining unchanged in main program.

I am unable to understand where I went wrong. Plz guide me.

Thank You.

+3  A: 

I don't think you understand what ref parameters are for - once you understand those (and the fact that arrays themselves can't change in size), you'll see why Array.Resize takes a ref parameter. Have a look at my parameter passing article for details.

You can fix your code by changing it like this:

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

and calling it like this:

ext.Resize(ref ip, ref i);

However, I suspect that using a more appropriate data structure would make your code clearer. Is there any reason you can't use a List<string> instead?

Jon Skeet
I have less idea regarding lists.I don't know how to use them properly.So using lists is better in this scenario?
Nani
@Nani: Well you can add and remove elements from a `List<T>`, which is exactly what it looks like you need to do. I *strongly* suggest that you find out more about the built-in collections before writing significant amounts of production code.
Jon Skeet
+1  A: 

You're removing items from the middle of a sequence, so shrinking its length. So using arrays is just making it difficult.

If ip was a List<string> instead of 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++;    
}

It looks like you're parsing an arithmetic expression. However, you might want to allow for parentheses to control the order of evaluation, and that's going to be tricky with this structure.

Update: What your code says is: You are going to scan through a sequence of strings. Anywhere in that sequence you may find a division operator symbol: /. If so, you assume that the things on either side of it can be parsed with double.Parse. But:

( 5 + 4 ) / ( 6 - 2 )

The tokens on either side of the / in this example are ) and ( so double.Parse isn't going to work.

So I'm really just checking that you have another layer of logic outside this that deals with parentheses. For example, perhaps you are using recursive descent first, and then only running the piece of code you posted on sequences that contain no parentheses.

If you want the whole thing to be more "objecty", you could treat the problem as one of turning a sequence of tokens into a tree. Each node in the tree can be evaluated. The root node's value is the value of the whole expression. A number is a really simple node that evaluates to the number value itself. An operator has two child nodes. Parenthesis groups would just disappear from the tree - they are used to guide how you build it. If I have some time later I could develop this into a short example.

And another question: how are you splitting the whole string into tokens?

Daniel Earwicker
By the way, you aren't using the same array. `Array.Resize` makes a new array, with the contents of the old array copied into it.
Daniel Earwicker