我想知道不同的解决方案,我附上我的解决方案谢谢
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());
}
最后一点,上面我提供的方法是扩展方法,所以一定要放在static
class中,别忘了加上引用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 的回答。
我首先要注意的是,您的解决方案仅在数组中有五个元素时才有效。我要向您展示的第一个版本是消除此限制的版本。
但在我这样做之前,我想编写两个可以派上用场的辅助函数:Max
和 Min
。这些函数分别采用数组和 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相加,Min
和Max
方法分别进行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 减法和 Min
和 Max
例程分别执行 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
上的一个奖励实施
他们认为这个解决方案很好,我已经很久没有编程了,大约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()
.
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());
}
最后一点,上面我提供的方法是扩展方法,所以一定要放在static
class中,别忘了加上引用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 的回答。
我首先要注意的是,您的解决方案仅在数组中有五个元素时才有效。我要向您展示的第一个版本是消除此限制的版本。
但在我这样做之前,我想编写两个可以派上用场的辅助函数:Max
和 Min
。这些函数分别采用数组和 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相加,Min
和Max
方法分别进行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 减法和 Min
和 Max
例程分别执行 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