我想知道不同的解决方案,我附上我的解决方案谢谢

I would like to know the different solutions, I am attaching my solution thanks

他们认为这个解决方案很好,我已经很久没有编程了,大约1个月了,我的问题是我打开了哪些其他方式来解决以下问题,我附上我的解决方案。

Sample Input 1 2 3 4 5 

Sample Output 10 14 

数字是 1、2、3、4 和 5。

Calculate the following sums using four of the five integers: Sum everything except 1,the sum is 2+3+4+5=14. Sum everything except 2,the sum is 1+3+4+5=13. Sum everything except 3,the sum is 1+2+4+5=12. Sum everything except 4,the sum is 1+2+3+5=11. Sum everything except 5,the sum is 1+2+3+4=10.


代码:

static void Main(string[] args)
{
int[] arr = new int[] { 1, 2, 3, 4, 5 };

miniMaxSum(arr);
}



static void miniMaxSum(int[] arr)
{
List<int> arr2 = new List<int>();
int sum = 0,mn,mx;
int sum2 = 0;
int sum3 = 0;
int sum4 = 0;
int sum5 = 0;
for (int i = 0; i < arr.Length; i++)
{
if(i != 0)
{
sum = sum + arr[i];

}
if (i != 1)
{
sum2 = sum2 + arr[i];

}
if (i!= 2)
{
sum3 = sum3 + arr[i];
}
if (i != 3)
{
sum4 = sum4 + arr[i];
 
}
if (i != 4)
{
sum5 = sum5 + arr[i];
}

}
arr2.Add(sum);
arr2.Add(sum2);
arr2.Add(sum3);
arr2.Add(sum4);
arr2.Add(sum5);
mx = arr2[0];
mn = arr2[0];
for (int j = 0; j < arr2.Count; j++)
{
if (arr2[j] > mx)
{
mx = arr2[j];
}
if(arr2[j] < mn)
{
mn = arr2[j];
}

}
Console.Write(mn + " ");
Console.Write(mx);
         

}

描述与输出不符。但是,假设描述正确

Calculate the following sums using four of the five integers:

  • Sum everything except 1, the sum is 2+3+4+5=14.
  • Sum everything except 2,the sum is 1+3+4+5=13.
  • Sum everything except 3,the sum is 1+2+4+5=12.
  • Sum everything except 4,the sum is 1+2+3+5=11.
  • Sum everything except 5,the sum is 1+2+3+4=10.

您可以执行以下操作


你可以只使用 2 个循环

var arr = new[] { 1, 2, 3, 4, 5 };

for (var i = 0; i < arr.GetLength(0);i++)
{
   var sum = 0;
   for (var j = 0; j < arr.GetLength(0); j++)
      if (i != j) 
         sum += arr[j];
   Console.WriteLine(sum);
}

输出

14
13
12
11
10

或者如果您喜欢 Linq Chain Methods

for (var i = 0; i < arr.GetLength(0);i++)
{
   var sum = arr.Where((x, j) => i != j ).Sum();
   Console.WriteLine(sum);
}

或者你如果非常讨厌循环

var results = Enumerable.Range(0, arr.GetLength(0))
   .Select(i => arr
      .Where((x, j) => i != j)
      .Sum());

Console.WriteLine(string.Join(Environment.NewLine, results));

或者如果扩展方法是您的菜

public static IEnumerable<IEnumerable<T>> FunkyIterator<T>(this T[] source)
   => Enumerable.Range(0, source.GetLength(0))
        .Select(i => source.Where((x, j) => i != j));

...

foreach (var iterations in arr.FunkyIterator())
   Console.WriteLine(iterations.Sum());

对于这个你可以看一下 Statistics 的 Combination 公式,它从 [= 中获取所有可能的 r 元素32=]n个元素,C(n, r).

这是获取所有可能组合的方法:

static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int k)
{
    return k == 0 ? new[] { new T[0] } :
          elements.SelectMany((e, i) => elements.Skip(i + 1)
               .Combinations(k - 1)
               .Select(c => (new[] { e }).Concat(c)));
}

首先,我将尝试在您的案例中使用它。你有这样的数组。

int[] arr = new int[] { 1, 2, 3, 4, 5 };

然后您想对数组中的每个 4 个数字求和,例如 1,2,3,4 ; 1,2,4,5 ; 1,2,3,5 ; ...等。因此,您可以将上述方法与名为 Sum().

的 Linq 方法结合使用
foreach(IEnumerable<int> result in arr.Combinations(4))
{
    Console.WriteLine(result.Sum());
}

此外,如果您想对每个 3 元素求和,例如 1,2,3 ; 3,4,5; 1,2,5; ...等等,你只需要在方法 Combinations:

中更改参数 k
foreach(IEnumerable<int> result in arr.Combinations(3))
{
    Console.WriteLine(result.Sum());
}

最后一点,上面我提供的方法是扩展方法,所以一定要放在staticclass中,别忘了加上引用System.Linq.

这种方法怎么样?

int[] arr = new int[] { 1, 2, 3, 4, 5 };

var total = arr.Sum();
List<int> sums = new List<int>();
foreach(int i in arr) {
  sums.Add(total - i);
}
var min = sums.Min();
var max = sums.Max();

Console.WriteLine("min = " + min);
Console.WriteLine("max = " + max);

或者,如果您不想使用任何 LINQ:

int[] arr = new int[] { 1, 2, 3, 4, 5 };

int total = 0;    
foreach(int i in arr) {
  total += i;
}
int min = 0, max = 0;
for(int i=0; i<arr.Length; i++) {
  int sum = total - arr[i];
  if (i == 0) {
    min = sum;
    max = sum;
  }
  else {
    if (sum < min) {
      min = sum;
    }
    if (sum > max) {
      max = sum;
    }
  }
}

Console.WriteLine("min = " + min);
Console.WriteLine("max = " + max);

我将采用与当前发布的其他两个答案略有不同的方法。我将一步一步地慢慢改进您的解决方案。我将避免使用 LINQ;不要误会我的意思 LINQ 很酷,您绝对应该学习它,但了解内部发生的事情很有用。有关 LINQ 的更多信息,请参阅上面@General 的回答。

我首先要注意的是,您的解决方案仅在数组中有五个元素时才有效。我要向您展示的第一个版本是消除此限制的版本。

但在我这样做之前,我想编写两个可以派上用场的辅助函数:MaxMin。这些函数分别采用数组和 return 最大元素和最小元素。

    static int Min(int[] arr)
    {
        int min = int.MaxValue;
        foreach (var val in arr)
        {
            min = Math.Min(min, val);
        }
        return min;
    }
    
    static int Max(int[] arr)
    {
        int max = int.MinValue;
        foreach (var val in arr)
        {
            max = Math.Max(max, val);
        }
        return max;
    }

有了这些,我们就可以编写一个可以处理任意大小数组的函数版本。

    /// Adds capability to work with arrays longer the 5 elements.
    static void MinMaxSum1(int[] arr)
    {
        // This array will hold the sums obtained if
        // the corresponding element in the input
        // array was left out of the sum.
        // So sums[0] is the sum if the zeroth element
        // is left out.
        int[] sums = new int[arr.Length];
        // skip is the index of the element we'll leave out
        // of the sum
        for (int skip = 0; skip < arr.Length; skip++)
        {
            int sum = 0;
            for (int current = 0; current < arr.Length; current++)
            {
                if (current != skip)
                {
                    sum += arr[current];
                }
            }
            sums[skip] = sum;
            Console.WriteLine($"MinMaxSum1: arr[{skip}] = {arr[skip]} sums[{skip}] = {sum}");
        }
        int min = Min(sums);
        int max = Max(sums);
        Console.WriteLine($"MinMaxSum1: min={min} max={max}");
        Console.WriteLine("================================");  
    }

如果数组有 n 个元素,花点时间考虑一下这将执行多少操作是值得的。内循环将进行 n-1 次加法,外循环将导致 运行 n 次,因此大致 n2相加,MinMax方法分别进行n比较。所以大致n2 + 2n次操作。

我们可以做得更好吗?

嗯,是的,我们可以。如果您查看输出,您可能会意识到 arr[i] + sum[i] == 15。这是有道理的,有两种方法可以得到答案:

  • 添加要跳过的元素
  • 将所有元素相加并减去您要省略的元素。 注意所有元素的总和不会改变!

所以如果我们有一个辅助函数 Sum 对数组中的所有元素求和,我们可以这样写:

    static void MinMaxSum2(int[] arr)
    {
        int sum = Sum(arr);
        int[] sums = new int[arr.Length];
        for (int i = 0; i < sums.Length; ++i)
        {
            sums[i] = sum - arr[i];
            Console.WriteLine($"MinMaxSum2: arr[{i}] = {arr[i]} sums[{i}] = {sums[i]}");
        }
        int min = Min(sums);
        int max = Max(sums);
        Console.WriteLine($"MinMaxSum2: min={min} max={max}");
        Console.WriteLine("================================");          
    }

这遍历数组一次以计算 sum 执行 n 加法,另一次计算 sums 数组执行 n 减法和 MinMax 例程分别执行 n 比较,因此大约 4n 操作总共

我们可以做得更好吗?

是的,但是这次我们需要查看问题文本中未提及的部分解决方案。看起来您只需要最小和最大部分和。从上面的实现中,我希望您可以看到 sum - Max(arr) 将出现最小值,sum - Min(arr).

将出现最大值

这导致了这个实现:

    static void MinMaxSum3(int[] arr)
    {
        int min = Min(arr);
        int max = Max(arr);
        int sum = Sum(arr);
        Console.WriteLine($"MinMaxSum3: min sum = {sum - max}");
        Console.WriteLine($"MinMaxSum3: max sum = {sum - min}");
        Console.WriteLine("================================");
    }

您可以找到所有这些版本,以及 Sum 的实施和 .NET Fiddle

上的一个奖励实施