Reputation: 5
As part of a homework I have to find solution (using C#) for the following task: 'We are given 5 integer numbers. Write a program that finds all subsets of these numbers whose sum is 0. Assume that repeating the same subset several times is not a problem.'
As a newbie I've decided to go with if-statements. The problem is that the else-statement is executed even when one or some of the if-s are true. And I can't use if, else if, else if, etc, because I need all of the if-statements checked. So is there a way of using multiple ifs, all of them to get checked and if none is true, an else-statement to be executed?
Here is my code so far:
using System;
namespace ZeroSubset
{
class ZeroSubset
{
static void Main()
{
Console.WriteLine("You have to enter five integers. Please enter the first one.");
int a = int.Parse(Console.ReadLine());
Console.WriteLine("Please enter an integer.");
int b = int.Parse(Console.ReadLine());
Console.WriteLine("Please enter an integer.");
int c = int.Parse(Console.ReadLine());
Console.WriteLine("Please enter an integer.");
int d = int.Parse(Console.ReadLine());
Console.WriteLine("Please enter an integer.");
int e = int.Parse(Console.ReadLine());
if (a + b == 0)
{
Console.WriteLine("{0} + {1} = 0", a, b);
}
if (a + c == 0)
{
Console.WriteLine("{0} + {1} = 0", a, c);
}
if (a + d == 0)
{
Console.WriteLine("{0} + {1} = 0", a, d);
}
if (a + e == 0)
{
Console.WriteLine("{0} + {1} = 0", a, e);
}
if (b + c == 0)
{
Console.WriteLine("{0} + {1} = 0", b, c);
}
if (b + d == 0)
{
Console.WriteLine("{0} + {1} = 0", b, d);
}
if (b + e == 0)
{
Console.WriteLine("{0} + {1} = 0", b, e);
}
if (c + d == 0)
{
Console.WriteLine("{0} + {1} = 0", c, d);
}
if (c + e == 0)
{
Console.WriteLine("{0} + {1} = 0", c, e);
}
if (d + e == 0)
{
Console.WriteLine("{0} + {1} = 0", d, e);
}
if (a + b + c == 0)
{
Console.WriteLine("{0} + {1} + {2} = 0", a, b, c);
}
if (a + b + d == 0)
{
Console.WriteLine("{0} + {1} + {2} = 0", a, b, d);
}
if (a + b + e == 0)
{
Console.WriteLine("{0} + {1} + {2} = 0", a, b, e);
}
if (a + c + d == 0)
{
Console.WriteLine("{0} + {1} + {2} = 0", a, c, d);
}
if (a + c + e == 0)
{
Console.WriteLine("{0} + {1} + {2} = 0", a, c, e);
}
if (a + d + e == 0)
{
Console.WriteLine("{0} + {1} + {2} = 0", a, d, e);
}
if (b + c + d == 0)
{
Console.WriteLine("{0} + {1} + {2} = 0", b, c, d);
}
if (b + d + e == 0)
{
Console.WriteLine("{0} + {1} + {2} = 0", b, d, e);
}
if (b + c + e == 0)
{
Console.WriteLine("{0} + {1} + {2} = 0", b, c, e);
}
if (c + d + e == 0)
{
Console.WriteLine("{0} + {1} + {2} = 0", c, d, e);
}
if (a + b + c + d == 0)
{
Console.WriteLine("{0} + {1} + {2} + {3} = 0", a, b, c, d);
}
if (a + b + c + e == 0)
{
Console.WriteLine("{0} + {1} + {2} + {3} = 0", a, b, c, e);
}
if (a + b + d + e == 0)
{
Console.WriteLine("{0} + {1} + {2} + {3} = 0", a, b, d, e);
}
if (a + c + d + e == 0)
{
Console.WriteLine("{0} + {1} + {2} + {3} = 0", a, c, d, e);
}
if (b + c + d + e == 0)
{
Console.WriteLine("{0} + {1} + {2} + {3} = 0", b, c, d, e);
}
if (a + b + c + d + e == 0)
{
Console.WriteLine("{0} + {1} + {2} + {3} + {4} = 0", a, b, c, d, e);
}
else
{
Console.WriteLine("No zero subset.");
}
}
}
}
Upvotes: 0
Views: 1596
Reputation: 12739
The else is only attached to the last if statement. Instead, use a boolean flag variable and set it true inside each of the if's. At the end turn the else statement into a check against the flag variable being false.
Without getting into ways to simplify your code, let's just work with it intact:
bool bFlag;
if (a + b == 0)
{
Console.WriteLine("{0} + {1} = 0", a, b);
bFlag = true;
}
if (a + c == 0)
{
Console.WriteLine("{0} + {1} = 0", a, c);
bFlag = true;
}
//... etc
if (!bFlag) // this WAS your else
{
Console.WriteLine("No zero subset.");
}
EDIT:
Now if you want to get fancy and not have to use all of those If statements and worry about the number of values, you could use some LINQ and an extension method. We have the PowerSet extension method which will pull together every combination of your numbers From This Site
public static IEnumerable<IEnumerable<T>> PowerSet<T>(this List<T> list)
{
return from m in Enumerable.Range(0, 1 << list.Count)
select
from i in Enumerable.Range(0, list.Count)
where (m & (1 << i)) != 0
select list[i];
}
Then your code can become:
var list = new[] { 1, -1, 4, 5, 6, -10, -2, -5 }; // example, you would still let the user provide the values
var permutations = list.ToList().PowerSet(); // Get Power Set
var zeros = permutations.Where(i => i.Sum() == 0) // Locate all whose sum adds to zero
.OrderByDescending(i => i.Count()) // Order by number of items
.Where(i => i.Count() > 0); // Exclude the empty set
if (!zeros.Any())
{
Console.WriteLine("No zero subset.");
}
else
{
foreach (var item in zeros)
{
Console.WriteLine(string.Format("{0} = 0", string.Join(" + ", item.OrderBy(i=>i))));
}
}
Sample Output:
-10 + -5 + -1 + 1 + 4 + 5 + 6 = 0
-10 + -1 + 1 + 4 + 6 = 0
-10 + -2 + 1 + 5 + 6 = 0
-10 + -5 + 4 + 5 + 6 = 0
-10 + 1 + 4 + 5 = 0
-10 + -1 + 5 + 6 = 0
-5 + -1 + 1 + 5 = 0
-5 + -2 + 1 + 6 = 0
-10 + 4 + 6 = 0
-5 + 1 + 4 = 0
-5 + -1 + 6 = 0
-1 + 1 = 0
-5 + 5 = 0
Running it with var list = new[] { 1, 3 };
instead yields:
No zero subset.
You can also combine the permutations variable and the zeros variable into one statement. Separated here for readability.
Upvotes: 4