2011-12-19 3 views
1

Задача: Если задана запятая строка чисел, вы хотите узнать самое высокое среднее число цифр. , например: рассмотрим строку с номером «123,345,555», выход будет равен 5, так как 5 - самый высокий средний среди 123,345,555.Оптимизируйте этот кусок кода C#

Вот мой program..in C#

int Max_Avg(string number_list) 
{ 
     int i; 
     Int32 sum; 
     Int32 max_avg = 0; 
     int limit = 0; 
     string[] num = number_list.Split(','); 
     limit = num.Length; 
     while (limit-- > 0) 
     { 
       i=0; 
       sum = 0; 
       while (i < num[limit].Length) 
       { 
        sum += Convert.ToInt32(num[limit].Substring(i, 1)); 
        i++; 
       } 
       int tmp=sum/num[limit].Length; 
       if (tmp > max_avg) 
       { 
        max_avg = tmp; 
       } 
     } 
     return max_avg; 
} 

Если любой может можно оптимизировать производительность или предложить более оптимизированный подход ускорить его .....

+4

Оптимизировать в плане чего? Память/сложность времени/производительность/строки кода? – sll

+3

не будет выход 5 (из 5, 5, 5) –

+0

извините, моя ошибка ... обновлено – Jay

ответ

8

(оптимизирован для ремонтопригодности/код, а не сырая производительность)

return (int) number_list.Split(',') 
     .Select(term => term.Average(c => (int) (c - '0'))).Max(); 
+0

thats кажется таким симпатичным ..... может вы просто объясните, что у вас было .... я на самом деле новичок в C# – Jay

+0

Это лечение, но и медленнее. В зависимости от того, сколько данных вы обрабатываете в том, насколько жестким будет цикл, это может быть фактором медленнее - может или я не буду восприимчивым, вы не даете контекста. – TomTom

+1

@Jay использует методы расширения LINQ; сначала мы берем «Сплит» (по запятой), предоставляя нам 3 члена; то для каждого слагаемого мы выполняем * проекцию * ('Select'), которая принимает термин« строка », и усредняет символы, используя символьную математику, чтобы быть эффективной; то вычисляется максимум этих средних значений. Я немного туман с некоторым заказом здесь, чтобы это было просто. –

1

Единственная разумная оптимизация скорости я вижу в этой строке:

Convert.ToInt32 (num [limit] .Substring (i, 1));

Это медленное - вы разбиваете строки символом на подстроки, а затем используете общий парсер.

Подфункция может принимать символ, а затем сделать ПЕРЕКЛЮЧАТЕЛЬ по 10 действительным валу (0-9) или преобразовать числовое значение char в число непосредственно. Это все, что вы могли бы сделать. Я думаю, что метод COnvert.ToInt32 слишком распространен, чтобы быть быстрым.

Имеет значение только тогда, когда вы это делаете тысячи раз, но, черт возьми, я пишу анализаторы данных в тот момент, когда такие оптимизации значительно увеличивают их.

+1

Действительно, это должно быть просто '(int) (num [limit] [i] - '0')' –

+0

Точно. Должно быть ТОН быстрее ni в узкой петле. – TomTom

+0

На самом деле вы также можете избавиться от массива и сделать его указателем - еще одна оптимизация;) Требуется небезопасная привилегия. – TomTom

1

Это моя версия, немного чище, на мой взгляд, но, вероятно, не намного быстрее или что-то еще.

int Max_Avg(string number_list) 
{ 
    int result = 0; 
    var numbers = number_list.Split(','); 
    foreach (var num in numbers) 
    { 
     var total = 0.0; 
     foreach (var ch in num) 
     { 
      total += (int) ch; 
     } 
     var avg = total/num.Length; 
     result = avg > result ? avg : result; 
    } 
    return result; 
} 
0
int Max_Avg(string number_list) 
{ 
    var result = 0; 
    var sum = 0; 
    var count = 0; 
    for (var i = 0; i < number_list.Length; i++) 
    { 
     if (number_list[i] == ',') 
     { 
      if (count > 0) 
      { 
       result = math.Max(result, sum/count); 
       sum = 0; 
       count = 0; 
      } 
     } 
     else 
     { 
      sum += number_list[i] - '0'; 
      count++; 
     } 
    } 
    return result; 
} 
+0

Это использует целочисленное деление, как в коде OP (что мне кажется неправильным). – Fantius

Смежные вопросы