从三角形的每一行获得最高数字并总结

时间:2015-11-20 09:05:33

标签: c#

我有三角形的数字,它将作为参数发送到function

5
9 6
4 6 8
0 7 1 5

现在,这将以下面的函数作为字符串接收,格式为5#9#6#4#6#8#0#7#1#5。到目前为止,我试图仅r #

的数字
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 
    }
}

如何从每一行中获得最高数量并将它们相加,我如何识别行来总结它?希望能找到一些帮助。

6 个答案:

答案 0 :(得分: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;
}

同一行:

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 :(得分: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);
        }
    }
}

答案 2 :(得分: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 :(得分:2)

解决此问题的一种方法是确定三角形的大小。 size 我指的是高度/宽度。例如,提供的三角形的大小为4。

如果尺寸为<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/abc_search_url_text_normal" android:orientation="vertical"> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="100dp" android:layout_alignParentBottom="true" android:layout_gravity="bottom" android:layout_marginBottom="3dp" android:paddingTop="5dp" app:cardBackgroundColor="@color/abc_input_method_navigation_guard"> </android.support.v7.widget.CardView> <ImageView android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="bottom" android:layout_marginBottom="30dp" android:layout_marginRight="10dp" android:scaleType="fitXY" android:src="@drawable/abc_ratingbar_full_material" /> </FrameLayout> ,那么三角形中的元素数量将为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

答案 4 :(得分: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;
        }
    }
}

答案 5 :(得分:0)

我会使用2个函数:

第一个将字符串转换为树形表示:

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

第二个总结线的最大值:

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