2015-11-20 3 views
3

У меня есть ниже треугольника чисел, которые будут отправлены в качестве параметра в functionполучить наибольшее число из каждой строки треугольника и подвести его

5 
9 6 
4 6 8 
0 7 1 5 

Теперь это будет получено в виде строки в поле ниже функции с формат 5#9#6#4#6#8#0#7#1#5. До сих пор я пытался пульсация только цифры от #

public class Sample 
{ 
    public static string validtrianglesum(string input) 
    { 
     string sum="0"; 
     foreach(char num in input) 
     { 
      if(!num.Equals('#')) 
      { 
       Console.PrintLine(num); //here am getting only the nums excluding # 
       //How to sum up based on each row 
      } 
     } 
     return sum; //return 
    } 
} 

как можно наибольшее число из каждой строки и суммировать их и как я мог определить строки подводить итоги? Надеюсь найти какую-то помощь.

+0

Но как вы думаете, что ваши показатели программы, сколько числа существуют на каждом линия? Всегда ли оно начинается с '1' и увеличивается? –

+0

@ SonerGönül Каждая строка будет содержать только один дополнительный номер, и на данный момент мне нужен вывод только для 4 строк. – CodeFreek

+0

1) Вы знаете, что первая строка имеет длину 1, вторая строка имеет длину 2 и т. Д. Это как вы можете их идентифицировать. 2) Вы не можете суммировать 'string', поэтому вам нужно преобразовать их в 'int'. –

ответ

2

Один из способов решить эту проблему, чтобы определить размер треугольника. К размер Я имею в виду высоту/ширину. Например, предоставленный треугольник имеет размер 4.

Если размер n, то количество элементов в треугольнике будет n(n + 1)/2. Когда число элементов во входных данных, как известно, это может быть решено, чтобы определить n (размер), решая вторую степень полинома и выбирая положительное решение (выражение ниже с участием квадратного корня):

var triangle = "5#9#6#4#6#8#0#7#1#5"; 
var values = triangle.Split('#').Select(Int32.Parse).ToList(); 
var sizeAsDouble = (-1 + Math.Sqrt(1 + 8*values.Count))/2; 
var size = (Int32) sizeAsDouble; 
if (sizeAsDouble != size) 
    throw new ArgumentException("Input data is not a triangle."); 

Так с предоставленным входом size будет 4.Затем можно использовать размер, чтобы выбрать каждую строку в треугольнике и выполнять нужные арифметические операции:

var maxValues = Enumerable 
    .Range(0, size) 
    .Select(i => new { Start = i*(i + 1)/2, Count = i + 1 }) 
    .Select(x => values.Skip(x.Start).Take(x.Count)) 
    .Select(v => v.Max()); 

Первый Select будет вычислить необходимые показатели, чтобы правильно разрезать массив значений, который делается во втором Select. Опять используется формула n(n + 1)/2. Если вы захотите, вы можете объединить некоторые из этих операций Select, но я думаю, что их разложение позволяет прояснить, что происходит.

Результатом этого будет число 5, 9, 8, 7. Если вы хотите, чтобы подвести их вы можете сделать это следующим образом:

return maxValues.Sum(); 
+0

Perfect @Martin Liversage и его удивительное объяснение тоже .. Спасибо .. :) – CodeFreek

3

Подытоживая все значения в каждой строке:

private static IEnumerable<int> Sum(string input) 
{ 
    int i = 0, s = 0, z = 1; 
    foreach (var v in input.Split('#').Select(int.Parse)) 
    { 
     s += v; 
     if (++i != z) continue; 
     z++; 
     yield return s; 
     s = i = 0; 
    } 
} 

То же самое в одной строке:

private static IEnumerable<int> Sum(string input) => new Func<int, int, IEnumerable<int>>((i, z) => input.Split('#').Select(int.Parse).GroupBy(e => i++ == z && (i = 1) != null ? ++z : z, e => e).Select(e => e.Sum()))(0, 1); 

Суммируя все самые высокие значения в каждой строке:

private static int Sum(string input) 
{ 
    int i = 0, s = 0, z = 1, m = 0; 
    foreach (var v in input.Split('#').Select(int.Parse)) 
    { 
     if (v > m) m = v; 
     if (++i != z) continue; 
     z++; 
     s += m; 
     i = m = 0; 
    } 
    return s; 
} 

Same в одной строке:

private static int Sum(string input) => new Func<int, int, int>((i, z) => input.Split('#').Select(int.Parse).GroupBy(e => i++ == z && (i = 1) != null ? ++z : z, e => e).Select(e => e.Max()).Sum())(0, 1); 

Я возвращаю суммы как IEnumerable<int> и с yield return. Если вы просто хотите распечатать ответы, измените тип возврата на void и удалите строку yield return s;.

+1

хороший, но измените имя параметра, чтобы все увидели, что это делает и его можно обслуживать. и см. последний коммант :) – lordkain

+0

Не могли бы вы дать мне знать в той же подписке, которую я написал сейчас? – CodeFreek

+0

CodeFreek вы должны иметь возможность отлаживать и изменять его правильно :) – lordkain

0

Я хотел бы использовать 2 функции:

1-ый, чтобы преобразовать строку в представлении дерева:

List<List<int>> GetTree(string data) 
    { 
     List<List<int>> CompleteTree = new List<List<int>>(); 
     List<int> ValuesInLine = new List<int>(); 

     int partsinrow = 1; 
     int counter = 0; 

     foreach (string part in data.Split('#')) 
     { 
      int value = int.Parse(part); 
      ValuesInLine.Add(value); 

      if (++counter == partsinrow) 
      { 
       CompleteTree.Add(ValuesInLine); 
       ValuesInLine = new List<int>(); 
       counter = 0; 
       partsinrow++; 
      } 
     } 

     return CompleteTree; 
    } 

2 один подытожить максимум линий:

int GetSumOfTree(List<List<int>> tree) 
    { 
     int sum = 0; 

     foreach (List<int> line in tree) 
     { 
      line.Sort(); 
      int max = line[line.Count - 1]; 
      sum += max; 
     } 

     return sum; 
    } 
1

Пожалуйста, отдайте должное Widi :), но это ваш запрос

var rows = Sum("5#9#6#4#6#8#0#7#1#5"); 
var total = rows.Sum(); 

private static IEnumerable<int> Sum(string inp) 
{ 
    int i = 0, s = 0, z = 1; 
    foreach (var v in inp.Split('#').Select(int.Parse)) 
    { 
     s = Math.Max(s, v); 
     if (++i == z) 
     { 
      z++; 
      yield return s; 
      s = i = 0; 
     } 
    } 
} 
+0

Но если вы увидите мои комментарии к ответу @ Widi, это суммирует каждую строку, а не максимальное число в каждой строке. Мне нужно определить максимальное количество каждой строки и суммировать ее. – CodeFreek

2

Вы можете использовать LINQ:

string input = "5#9#6#4#6#8#0#7#1#5"; 
var nums = input.Split('#').Select(s => Int32.Parse(s)); 

var res = Enumerable.Range(0, nums.Count()) 
        .Select(n => nums.Skip(Enumerable.Range(0, n).Sum()).Take(n)); 
        .Where(x => x.Any()); // here you have IEnumerable<int> for every row 
        .Select(arr => arr.Max()); 
3

Давайте разберем это следующим образом:

Во-первых, включить ввод в массив чисел:

string input = "5#9#6#4#6#8#0#7#1#5"; 
var numbers = input.Split('#').Select(int.Parse).ToArray(); 

сейчас предположим, что у нас есть метод MakeTriangular(int[]), который превращает массив чисел в последовательность строк, причем первая строка имеет длину 1, вторую длину 2 и т. д., так что она возвращает IEnumerable<IEnumerable<int>>.

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

int sum = MakeTriangular(numbers).Sum(row => row.Max()); 

который дает ответ.

Реализация MakeTriangular() может выглядеть следующим образом:

public static IEnumerable<IEnumerable<int>> MakeTriangular(int[] numbers) 
{ 
    for (int i = 0, len = 1; i < numbers.Length; i += len, ++len) 
     yield return new ArraySegment<int>(numbers, i, len); 
} 

Собирает все вместе в компилируемое приложение консоли:

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace Demo 
{ 
    class Program 
    { 
     public static void Main() 
     { 
      string input = "5#9#6#4#6#8#0#7#1#5"; 
      var numbers = input.Split('#').Select(int.Parse).ToArray(); 
      int sum = MakeTriangular(numbers).Sum(row => row.Max()); 
      Console.WriteLine(sum); 
     } 

     public static IEnumerable<IEnumerable<int>> MakeTriangular(int[] numbers) 
     { 
      for (int i = 0, len = 1; i < numbers.Length; i += len, ++len) 
       yield return new ArraySegment<int>(numbers, i, len); 
     } 
    } 
} 
+0

спасибо Мэтью за красивое объяснение. Но у меня нет достаточной репутации для продолжения ... Как только я получу, я вернусь и сделаю это .. :) – CodeFreek

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