Is there a way to know what passed through a if statement - c#

My problem is, that I need to now, what statements passed through a If statement. The code is as follows.
int[] Array = {value1,value2,value3}
foreach {int Value in Array)
{
if (Value < 4)
{
// Here i need to know what values passed through that were less that 4, like
// which one, value 1, value 2, and/or value 3
}
So is there a solution for a problem? I'm kind of new to programming.
My problem is that i do not need an else statement, i Need to know if value 1 or 2 or 3 passed through. Exactly which ones are less than 4. EDIT: fixed some mistakes, was in a rush, forgot to put the sign the other way. When they are less than 4, i need to now which values passed through. Ill prob repost tho. As i messed up. I really don't care for now which ones are greater, or the else statement, i skipped that part.
Edit2: I also came up with a solution, but i don't if its good. Should i run a loop when i store values in the if statement, making another if statement, to compare if the ones inside the if statement are the same on the outside, and then knowing which values passed through?

I'm not 100% positive if I understand the question but it seems you can use the else statement
if (Value > 4)
{
// Do your stuff for elements greater than 4
}
else
{
// Do your stuff for elements greater lower or equal than 4
}

How about use for instead of foreach, since you got index of array member, you will know which one passed through
int[] array = {value1, value2, value3}
for (int index = 0; index < array.Count(); index++)
{
if (array[index] < 4)
{
// do sth with index
}
}

int Array[] = {value1,value2,value3}
foreach {int Value in Array)
{
if (Value > 4)
{
// Here i need to know what elements passed through that were less that 4
}else if(Value < 4){
//values < 4 will execute this code
}

I'm going to make a few general suggestions that should hopefully be helpful. First of all, your conditional says if (Value > 4) so you will not go into that code block where you suggest figuring out which elements are less than 4. Instead you'd need an else. So here's one way;
int Array[] = {value1,value2,value3}
List<int> lessThanFour = new List<int>();
foreach {int Value in Array)
{
if (Value < 4)
{
lessThanFour.Add(Value);
Console.WriteLine(Value);
}
}
The above code puts each value which is less than four into a list so you can access them later. It also prints them to the console.
Another option would be to use LINQ;
var lessThanFour = Array.Where(x => x < 4);
foreach (int c in lessThanFor)
Console.WriteLine(c);
The above code uses the Where operator to create a new array with all ints in the original that have a value less than for. The statement x => x < 4 is best to think of in an iterative since where x is the current element. It works the same as the foreach loop. When you execute that code it basically says, for each int x in Array, if x is less than four add it to the result. Then I use a foreach below that to print out the results.

Your question is poorly framed I think but it sounds like you are looking for a switch case.
if (x < 4) {
switch (x) {
case 1:
Console.WriteLine("Case 1");
break;
case 2:
Console.WriteLine("Case 2");
break;
case 3:
Console.WriteLine("Case 3");
break;
default:
Console.WriteLine("Default case");
break;
}
}

Related

Domino recursion

I have a recursion assignment where I have to input into console the following data:
On the first line a natural number equal with the number of tiles I have to input on the following lines (in my example the first number is 6).
On the following lines the domino tiles in the following order:
1 2
1 3
3 4
2 3
3 5
4 5
On the last line another number representing the number of tiles that needs to be returned on each separate line (in my example the number is equal with 3).
With this data I have to display all possible combinations of pairs. For each separate line the number the second number from the first pair has to be equal with the first number of the following pair and so on. I had a hint for this assignment where I have to declare an intermediary list that is equal with the function (using recursion from the start) but when I'm trying to run the code it gives me a null exception for the intermediaryList.
In the first instance I read the data as a 2d array but settled with a simple string array where.
This is my code so far, could you help me with a suggestion, how to avoid the null exception?
(sorry if I missed something from the explanation, this is my second post here so far and thank you in advance). Also I have to mention that I'm allowed to use just "using System;" Not allowed to use Linq or anything else.
enter code here
static string[] ReadDominoTiles(int n)
{
string[] input = new string[n];
for (int i = 0; i < n; i++)
{
input[i] = Console.ReadLine();
}
return input;
}
static string[] DominoSolution(string[] dominoTiles, int numberOfPairs)
{
string[] finalList = new string[numberOfPairs];
if (numberOfPairs == 1)
{
return finalList;
}
string[] intermediaryList = DominoSolution(dominoTiles, numberOfPairs - 1);
for (int i = 0; i < intermediaryList.Length; i++)
{
for (int j = 0; j < dominoTiles.Length; j++)
{
// This is where I get the nullref exception, every value from intermediaryList is null
if (intermediaryList[i] != dominoTiles[j] && intermediaryList[j][1] == dominoTiles[j][0])
{
finalList[j] += intermediaryList[j] + " " + dominoTiles[j];
}
}
}
return finalList;
}
static void Main(string[] args)
{
int n = Convert.ToInt32(Console.ReadLine());
string[] dominoTiles = ReadDominoTiles(n);
int numberOfPairs = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(DominoSolution(dominoTiles, numberOfPairs));
}
This is where I get the nullref exception, every value from intermediaryList is null
That's correct, you call the function recursively after doing exactly zero work, besides adding a recursion termination condition which returns an array of nulls. So the first time you come out of your recursion you have in intermediaryList a number of null elements, so when you pretend they're strings and try to get intermediaryList[j][1] you'll get a null reference exception.
As to the solution, it's not exactly clear what's with all the arrays you're allocating. Use a List<> with an actual type and do your work properly. Though I hate to break it to you but if I understand your assignment correctly the solution will use backtracking and combinatorics, which is much more code and much better structured than what you have here.

Filter a list of integers based on integer multiples - C#

I am trying to filter a list of int based on multiples of a specific number, but I am not sure how to do this. I have searched this forum and found nothing related, but apologies in advance if I'm wrong.
Here is my code:
int val = 28;
List<int> divisible = new List<int>();
for (int i = 1; i <= val; i++) {
divisible.Add(i);
}
foreach(var d in divisible)
{
if(val % d == 0)
{
// do something
}
else
{
// get rid of all multiples of the number that "val" is not divisible by
}
}
Basically, this code should create a divisible list from 1 to 28. If val is divisible by one of the numbers in the list, thats fine, but if it falls into else, I want to be able to filter out all multiples of that number out of the current list we are looping through.
The next number that wouldn't be divisible would be 3 in this example, so in the else get rid of 6, 9, 12, ... etc.
Your code is fine, but you're just missing the actual code to remove the item. But there is a caveat: You cannot modify a list when you are looping through it using foreach. There are a couple ways to handle that:
Depending on your requirements, maybe just don't add them in the first place. Move your val % d == 0 condition into the for loop that adds the values, and just don't add the values that are divisible by d.
Make a new list (List<int> toRemove) where you keep track of all the values you need to remove. After you're done the foreach loop, loop through your toRemove list and use divisible.Remove(value) to remove those.
Change your foreach to a for loop, which will allow you to use divisible.RemoveAt(i). But you will have to make sure you don't skip a value on the next iteration of the for loop (since removing a value changes the size of the list).
I agree with Gabriel. You cannot alter a underlying enumeration while traversing it with with foreach. The easiest thing to do would be to convert it to a for loop.
Also in the initial population of your list try using the newer way
var divisible = Enumerable.Range(1, val).ToList();
then do
for(int 0 = 1; i < val; i++)
{
if(val % d == 0)
{
// do something
}
else
{
divisible.RemoveAt(i);
}
}

Interview function with time complexity

I had an interview question to write a program in C# that Outputs odd number of occurrences in an array.
Example: [2, 2, 3, 3, 3] => [3] (Considering the array is sorted)
My solution was:
public list<int> OddOccurance(list<int> InputList)
{
list<int> output = new list<int>();
for(int i=0; i<InputList.length; i++)
{
int Count = 0;
for(int j=1; j<(InputList.length-1); j++)
{
if(InputList[i] == InputList[j])
{
Count++;
}
}
if(Count % 2 != 0)
{
output.add(InputList[i]);
}
}
return output.distinct();
}
I am thinking the answer is correct only but the interviewer had asked me like different ways of how I can make the solution much faster.
Can anyone please tell me the time complexity of the above solution please.
If there is a way to make the above solution much faster then what can be the time complexity of that solution.
Your solution is O(n^2) - if you don't know why - evaluate sum:
This is an equation which describes the running time of your algorithm. You can solve it in linear time easily - just increment i instead of inner loop over all values in array.
for (int i=0; i<InputList.Length; ++i)
{
int currentValue = InputList[i];
int j=i+1;
int count = 1;
while (InputList[j] == currentValue && j<InputList.Length)
{
count++;
i++;
j++;
}
if (count % 2 == 0)
..
}
If array is not sorted - use dictionary (hash table - Dictionary in C#) - value is a dictionary key, count is a dictionary value. (that will give you Contains key check in O(1)) Another way to get linear time if implemented properly.
The root problem of your solution is seen on this line:
return output.Distinct();
The very fact that you are doing a Distinct means that you may be adding more entries than you should.
So how can you optimize it? Observe that since the array is sorted, the only place where you can find a number that's the same as the one you're looking at is next to it, or next to another number that's equal to your current number. In other words, your numbers go in "runs".
This observation lets you go from two nested loops and an O(N2) solution to a single loop and an O(N) solution. Simply walk the array, and check lengths of each "run": when you see a new number, store its index. If you come across a new number, see if the length of the "run" is odd, and start a new run:
int start = 0;
int pos = 1;
while (pos < InputList.Length) {
if (InputList[pos] != InputList[start]) {
if ((pos-start) % 2 == 1) {
output.Add(InputList[start]);
}
start = pos;
}
pos++;
}
// Process the last run
if ((InputList.Length-start) % 2 == 1) {
output.Add(InputList[start]);
}
Demo.

Check if all elements in an array are equal

In the first part I am creating pairs out of array elements and the array is twice as short. The array is always even.
Here is the first part:
using System;
class Program
{
static void Main()
{
int[] Arr = new int[]{1, 2, 0, 3, 4, -1};
int[] newArr = new int[(Arr.Length / 2)];
int sum = 0;
for (int i = 0; i < Arr.Length; i+=2)
{
if (i + 1 < Arr.Length)
{
newArr[sum] = Arr[i] + Arr[i + 1];
}
else
{
newArr[sum] = Arr[i];
}
sum++;
}
in the second part I would like to check if the array elements are equal. What I want to do is to increment int counter each time the index in the for loop is equal to the next index in the array.
What I have as second part:
int counter = 0;
for (int i = 0; i < newArr.Length -1; i++)
{
if (newArr[i] == newArr[i + 1])
{
counter++;
}
else
{
Console.Write(" ");
}
}
What is wrong in this code. I cannot seem to understand how to write code that will work with int Arr[5] and int Arr[5000]
All you need to change is the termination condition in the for loop to
i < newArr.Length - 1
so that you can compare array[i] with array[i + 1]. This change makes sure you do not get past the upper bound of the array.
try this
for ( i=1;i<arr.Length;i++)
{
if(arr[0]==arr[i])
continue;
else
break;
}
if (i==arr.Length)
Console.WriteLine("All element in array are equal");
If there is no need to write so imperative code, other than to achieve your final goal – you don't have to. Almost always you can do it in a much more readable way.
I suggest using LINQ. For collections implementing IEnumerable<T>:
newArr.Distinct().Take(2).Count() == 1
LINQ is a built-in feature, just make sure you are using System.Linq; at the top of your .cs file.
What goes on here?
Distinct returns an IEnumerable<T>, its enumeration will give all distinct elements from your array, but no enumeration, and hence computation, happened yet.
Take returns new IEnumerable<T>, its enumeration will enumerate previous IEnumerable<T> internally, but it will give only first two distinct elements. Again, no enumeration happened yet.
At last, Count enumerates the last IEnumerable<T> and returns its elements count (in our case 0, 1 or 2).
As we used Take(2), the enumeration initiated by Count method will be stopped right when the second distinct element is found. If we don't use Take(2), our code will enumerate the whole array even if it is not needed.
Why is this approach better?
Much shorter and more readable;
Lazy evaluation – if an element is found out to be distinct from the other ones, the enumeration will be stopped immediately;
Flexible – you can pass a custom equality comparer to Distinct method. You can also call Select method before calling Distinct to choose what specific member your elements will be compared by;
Universal – Works with any collection which impletents IEnumerable<T> interface.
Other ways
The same result can be achieved in slightly other ways, for example:
!newArr.Distinct().Take(2).Skip(1).Any()
Experiment with LINQ and choose the way you and your team consider the most readable.
For collections implementing IList<T> you can also write (as #Alexander suggested):
newArr.All(x => x == newArr[0])
This variant is shorter but not as flexible and universal.
OFF TOPIC. Encapsulating common code
You should encapsulate code that does one simple thing into a separate method, it further improves your code readability and allows reusing your method in several places. I'd write an extension method for this one.
public static class CollectionExtensions {
public static bool AllElementsEqual<T>(this IEnumerable<T> items) {
return items.Distinct().Take(2).Count() == 1;
}
}
Later in your code you need just to call this method:
newArr.AllElementsEqual()
Try this..
for (int i = 0; i < newArr.Length-1; i++)
{
for(int j=0 ;j< newArr.Length-1; i++)
{
if (newArr[i] == newArr[j])
{
/////
}
}
}
else
{
Console.Write(" ");
}
}

Cycling through contents of array issue

I am using an int array to hold a long list of integers. For each element of this array I want to check if it is 1, if so do stuff relevant to 1 only, else if it is a 2, do other stuff relevant to 2, and so forth for each value stored in the array. I came up with the code below but it isn't working as expected, is there something I am missing? What is happening is that only the first value of the array is being considered.
int[] variable1 = MyClass1.ArrayWorkings();
foreach (int i in variable1)
{
if (variable1[i] == 1)
{
// arbitrary stuff
}
else if (variable1[i] ==2)
{
//arbitrary stuff
}
}
The i in your foreach loop holds the actual element value from the array in each iteration, not the index. In your particular code sample, your array probably holds only zeroes, which is why you're only getting the first element (you're always using index 0). Hence, you should check i rather than variable1[i].
If you are going to check against various integer constants, a switch expression is more suitable, BTW:
foreach (int i in variable1) {
switch (i) {
case 1:
// arbitrary stuff
break;
case 2:
// arbitrary stuff
break;
}
}
switch/case saves you some writing; if you ever pull your values from anywhere else than from i, you can simply change the (i) part in the switch statement, and moreover, switch might be evaluated by the compiler more efficiently than the chained if-else statements.
Note: You will not be able to directly change array values in the foreach loop, as you cannot assign anything to i. If you need to assign new array values, you'll have to
count yourself with an additional variable while still using foreach or
use another loop such as for and retrieve the item at the current index yourself.
You're trying to do something that doesn't make sense. To see how it works, take a simple example, an array with values: 9, 4, 1.
If you try to run your code on this sample array, you'll get an error:
foreach (int i in variable1)
{
if (variable1[i] == 1) // the item i is 9.
// But variable[i] means, get the value at position #9 in the array
// Since there are only 3 items in the array, you get an Out Of Range Exception
{
// arbitrary stuff
}
{
Instead, this is what you need:
foreach (int i in variable1) // i will be 9, then 4, then 1)
{
if (i == 1)
{
// arbitrary stuff
}
// ... etc
}
The alternative is to use a for loop, which would give you the indices 0, 1, and 2, like this:
for (int i=0 ; i<=variable1.Length ; i++) // i will be 0, 1, 2
// variable[i] will be 9, 4, 1
{
if (variable1[i] == 1)
{
// stuff
}
// ... etc
}
Write like this instead:
foreach (int i in variable1) {
if (i == 1) {
....
The i you fetched is not the index but the value. So check i with 1 or 2.
If you were using for loop then your inner code would have worked perfectly.
int[] variable1 = MyClass1.ArrayWorkings();
foreach (int i in variable1)
{
switch(i)
{
case 1:
// arbitrary stuff
break;
case 2:
//arbitrary stuff
break;
}
}
Try using switch case. Much faster than normal if-else.

Categories