Возвращаемые массивы - PullRequest
       7

Возвращаемые массивы

0 голосов
/ 22 февраля 2010
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++;    
    }    
}

Для приведенного выше кода я хотел применить концепции Оопа.

Этот шаблон повторяется почти 5 раз (для div, mul, add, sub, pow) в основной программе с четырьмя одинаковыми строками.

Чтобы уменьшить количество строк и повысить эффективность кода, я написал тоже самое вот так.

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

Код успешно скомпилирован.Но проблема в том, что изменения в массиве и переменных, которые произошли в вызываемой функции, не отражаются в основной программе.Массив и переменные в основной программе остаются неизменными.

Я не могу понять, где я ошибся.Пожалуйста, направьте меня.

Спасибо.

Ответы [ 2 ]

3 голосов
/ 22 февраля 2010

Не думаю, что вы понимаете, для чего нужны ref параметры - как только вы поймете их (и тот факт, что сами массивы не могут измениться в размере), вы поймете, почему Array.Resize принимает ref параметр. Посмотрите мою статью о передаче параметров для подробностей.

Вы можете исправить свой код, изменив его следующим образом:

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

и называя это так:

ext.Resize(ref ip, ref i);

Однако я подозреваю, что использование более подходящей структуры данных сделает ваш код более понятным. Есть ли причина, по которой вы не можете использовать List<string> вместо этого?

1 голос
/ 22 февраля 2010

Вы удаляете предметы из середины последовательности, поэтому сокращаете ее длину. Поэтому использование массивов только усложняет задачу.

Если ip было List<string> вместо 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++;    
}

Похоже, вы анализируете арифметическое выражение. Тем не менее, вы можете захотеть, чтобы круглые скобки контролировали порядок оценки, и это будет сложно с этой структурой.

Обновление: То, что говорит ваш код: Вы собираетесь сканировать последовательность строк. В любом месте этой последовательности вы можете найти символ оператора деления: /. Если это так, вы предполагаете, что вещи по обе стороны могут быть проанализированы с double.Parse. Но:

( 5 + 4 ) / ( 6 - 2 )

В этом примере токены по обе стороны от /: ) и (, поэтому double.Parse не будет работать.

Так что я просто проверяю, что у вас есть еще один слой логики вне этого, который имеет дело с скобками. Например, возможно, вы сначала используете рекурсивный спуск, а затем запускаете только тот фрагмент кода, который вы разместили в последовательностях без скобок.

Если вы хотите, чтобы все это было более «объектным», вы можете рассматривать эту проблему как превращение последовательности токенов в дерево. Каждый узел в дереве может быть оценен. Значение корневого узла - это значение всего выражения. Число - это действительно простой узел, который оценивает само значение числа. Оператор имеет два дочерних узла. Группы круглых скобок просто исчезли бы из дерева - они используются для руководства, как вы его строите. Если бы у меня было какое-то время спустя, я мог бы развить это в короткий пример.

И еще один вопрос: как вы разбиваете всю строку на токены?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...