I have a dictionary, let's it key value pair be as follow:
a - 1
b - 3
c - 2
I want to find out the number of odd and even value chars. For example, the above will return me 2 odd and 1 even.
I was thinking of iterating but I read iterating is the wrong way if we are using a dictionary. What is the best approach?
use LINQ:
var numOdd = myDic.Count(e => e.Value % 2 == 1);
See this link What is the best way to iterate over a Dictionary in C#? , iterating internally or externally is needed.
The code should be something like following. It first identifies the number of evens, then the number of odd will be total elements minus event numbers.
int evenCounter=0;
foreach(var item in myDictionary.Values)
{
if(item %2 ==0)
evenCounter++;
}
int oddCounter = myDictionary.Count -evenCounter;
Related
I have a list like this:
myList.Add(1);
myList.Add(1);
myList.Add(3);
myList.Add(4);
myList.Add(5);
myList.Add(6);
I want to find the number of '1's upto an index of 4. So, in this case, the result should be 2.
How do you I put a condition in the Count().
I need the number of integers, which fulfills the criterion n<2 && n>0 (i.e. n==1).
You only care abou the first 4 entries in the list (as you said, values with higher indexes don't matter).
So at first, restrict the search to these four numbers:
myList.Take(4)
from these you want to count only the entries that are 1. You can achieve that using the Count() linq extension that takes a predicate:
int numberOfOnes = myList.Take(4).Count(i => i == 1);
int value = myList.Take(4).Where(w=>w == 1).Sum()
Additionally, 'Where' has a less commonly used overload that provides the index: myList.Where((w,ix)=>ix < 4 && w == 1).Sum().
I would probably use .Take() for readability and performance reasons (see #mjwills comment) though.
I want to write a program that prints from a given array of integers those numbers that are divisible by 3 and 9.I want to use the built-in extension methos and lambda expression.
What I've done:
static void Main(string[] args)
{
List<int> l = new List<int>() {18,3,27,42};
List<int> divBy3 = l.FindAll(x => (x % 9) == 0);
List<int> divBy9 = l.FindAll(x => (x % 3) == 0);
if (divBy9 == divBy3)
{
foreach (var num in divBy9)
{
Console.WriteLine("The numbers divisible by 9 and 3 are: {0}",num);
}
}
else
{
Console.WriteLine("There are no numbers divisible by 9 and 3.");
}
}
And the output should be {27,18}.
My output is always the else branch but I don't understand why.I've tried to put in the original array of integers only the values {18,27} and it should verify the equality.In foreach I put to check only in the divBy9 list because I thought that if the 2 lists are equal would be the same thing to check only in one list, but I don't think is good.
What's wrong? Thank you.
You're comparing two handles, not the items in the lists they represent. And that's not what you want anyway, you want the intersection:
var intersect = divBy9.Intersect(divBy3); // returns an IEnumerable<int>
I don't really know what you're trying to achieve though, the result will always be in divBy9 because of math reasons.
Also you probably should stop using the obsolete FindAll, you can use Where to get a clean Enumerable without allocating memory for the temporary arrays.
You are creating two different lists and comparing them by reference and even though the lists may contain the same elements (they do not) the references will always be different so your code will select the else branch.
As a number divisible by 9 is also divisible by 3 your test seems kind of odd but let us assume that you want to find the numbers divisible by 5 and 9 instead. Then the lambda becomes:
x => x%5 == 0 && x%9 == 0
E.g.
List<int> divBy5And9 = l.FindAll(x => x%5 == 0 && x%9 == 0);
This will filter the source list and only pick the elements that are both divisible by 5 and 9.
The equality is not doing what you think it's doing. It is comparing the object references, and they are not the same because they are different objects.
You need to take each element in divBy3 and make sure that they are also in divBy9 and vice versa. This is set equality.
you are comparing the list instances themselves, ie the object references and these will not be the same, as they are different list instances. See this for more details
You want to compare the lists to see if they contain the same values.
There is an extension method which will help you SequenceEqual
to check only in one list,
Create a dynamic entity to hold the results such as:
var numbers = Enumerable.Range(1, 50) // 1,2,3,...50
.ToList();
numbers.Where(nmb => (nmb % 3) == 0) // Give us all numbers divisible by 3.
.Select(nmb => new
{
Number = nmb,
By3 = true,
By3And9 = (nmb % 9) == 0 // The ones divisible by 9
});
Result:
Let me explain the situation first:
I receive a value from my Binary Search on a collection, and quickly jump to that to do some coding. Next I want to jump to the next item in the list. But this next item is not exactly the one that follows it could be 3 or 4 items later. Here is my data to understand the sitatuion
Time ID
0604 ABCDE
0604 EFGH
0604 IJKL
0626 Some Data1
0626 Some Data2
0626 Some Data3
0626 Some Data4
Let's say Binary search return's index 0, I jump to index 0 (0604 ABCDE). I process/consume all 0604. Now I am at index 0, how do I jump to index 3 (0626) and consume / process all of it. Keeping in mind this will not always be the same. Data can be different. So I can't simply jump : index + 3
Here's my code:
var matches = recordList.Where(d => d.DateDetails == oldPointer);
var lookup = matches.ToLookup(d => d.DateDetails).First();
tempList = lookup.ToList();// build templist
oldPointer here is the index I get from Binary search. I take this up and build a templist. Now after this I want to jump to 0626.
How many records with the same "old pointer" do you typically expect? Is usually going to be less than 100? if so: don't over-complicate it - just iterate:
public static int FindNextPointerIndex(int oldIndex, string oldPointer, ...)
{
for(int i = oldIndex + 1; i < collection.Count ; i++)
{
if(collection[i].DateDetails != oldPointer) return i;
}
return -1;
}
If you want something more elegant, you will have to pre-index the data by DateDetails, presumably using something like a ToLookup over the entire collection, but: note that this makes changes to the data more complicated.
Have a look at Skip List , http://en.wikipedia.org/wiki/Skip_list
It will allow you to jump forward more than 1 in your linked list, but the down side to find the start of your search will be O(n)
I came across an algorithm problem. Suppose I receive a credit and would like to but two items from a local store. I would like to buy two items that add up to the entire value of the credit. The input data has three lines.
The first line is the credit, the second line is the total amount of the items and the third line lists all the item price.
Sample data 1:
200
7
150 24 79 50 88 345 3
Which means I have $200 to buy two items, there are 7 items. I should buy item 1 and item 4 as 200=150+50
Sample data 2:
8
8
2 1 9 4 4 56 90 3
Which indicates that I have $8 to pick two items from total 8 articles. The answer is item 4 and item 5 because 8=4+4
My thought is first to create the array of course, then pick up any item say item x. Creating another array say "remain" which removes x from the original array.
Subtract the price of x from the credit to get the remnant and check whether the "remain" contains remnant.
Here is my code in C#.
// Read lines from input file and create array price
foreach (string s in price)
{
int x = Int32.Parse(s);
string y = (credit - x).ToString();
index1 = Array.IndexOf(price, s) ;
index2 = Array.IndexOf(price, y) ;
remain = price.ToList();
remain.RemoveAt(index1);//remove an element
if (remain.Contains(y))
{
break;
}
}
// return something....
My two questions:
How is the complexity? I think it is O(n2).
Any improvement to the algorithm? When I use sample 2, I have trouble to get correct indices. Because there two "4" in the array, it always returns the first index since IndexOf(String) reports the zero-based index of the first occurrence of the specified string in this instance.
You can simply sort the array in O(nlogn) time. Then for each element A[i] conduct a binary search for S-A[i] again in O(nlogn) time.
EDIT: As pointed out by Heuster, you can solve the 2-SUM problem on the sorted array in linear time by using two pointers (one from the beginning and other from the end).
Create a HashSet<int> of the prices. Then go through it sequentially.Something like:
HashSet<int> items = new HashSet<int>(itemsList);
int price1 = -1;
int price2 = -1;
foreach (int price in items)
{
int otherPrice = 200 - price;
if (items.Contains(otherPrice))
{
// found a match.
price1 = price;
price2 = otherPrice;
break;
}
}
if (price2 != -1)
{
// found a match.
// price1 and price2 contain the values that add up to your target.
// now remove the items from the HashSet
items.Remove(price1);
items.Remove(price2);
}
This is O(n) to create the HashSet. Because lookups in the HashSet are O(1), the foreach loop is O(n).
This problem is called 2-sum. See., for example, http://coderevisited.com/2-sum-problem/
Here is an algorithm in O(N) time complexity and O(N) space : -
1. Put all numbers in hash table.
2. for each number Arr[i] find Sum - Arr[i] in hash table in O(1)
3. If found then (Arr[i],Sum-Arr[i]) are your pair that add up to Sum
Note:- Only failing case can be when Arr[i] = Sum/2 then you can get false positive but you can always check if there are two Sum/2 in the array in O(N)
I know I am posting this is a year and a half later, but I just happened to come across this problem and wanted to add input.
If there exists a solution, then you know that both values in the solution must both be less than the target sum.
Perform a binary search in the array of values, searching for the target sum (which may or may not be there).
The binary search will end with either finding the sum, or the closest value less than sum. That is your starting high value while searching through the array using the previously mentioned solutions. Any value above your new starting high value cannot be in the solution, as it is more than the target value.
At this point, you have eliminated a chunk of data in log(n) time, that would otherwise be eliminated in O(n) time.
Again, this is an optimization that may only be worth implementing if the data set calls for it.
this is a very specific question, but i also have very specific details on what i'm looking for. i currently do not have (and cannot find) a good method for accomplishing this. please help if you can.
i have an integer list that will always contain 4 items and 3 of the items will always end in the same digit. i need to some how extract the 1 item that has a unique final digit. the unique item will not always be in the same location in the list and all numbers in the list will be a value from 0-40 (so one to two digits).
example list contents: 12,22,27,32. i need a method to return or extract the 27.
example 2: 4,13,23,33. i would need to return 4.
the solution should either remove the 3 repeated final digit numbers from the list or possibly create just a standard int variable with the unique value.
i've tried converting to a string and gather that character and have this ridiculous function that tests the integer length (number of digits) and adds just the end digit to another list and some comparison code. it's just really ridiculous. if you know of any ideas i should try, please let me know, thanks in advance.
Assuming numbers is some iterable of integers:
int unique = numbers.GroupBy(i => i % 10).Single(g => g.Count() == 1).Single();
This groups the numbers by their last digit, pulls out the only group with a single member, and returns its only member.
number % 10 will give you the last digit of number.
Some simple ifs here, although you are probably looking for fancy LINQ* :)
*LINQ is actually pretty fancy
//compare first to second
if((list[0] - list[1]) % 10 != 0)
{
//they're not the same, see if first and third are different
if((list[0] - list[2])% 10 != 0)
{
return list[0]; //yes, so first is the odd one
}
else
{
return list[1]; //no, so second is the odd one
}
}
//first two are same, so check if third is the odd one
if((list[0] - list[2]) % 10 != 0)
return list[2]; //yes it is
//only fourth remains
return list[3];
for such a specific format, just use a simple if-then-else network on the
remainder mod 10 of the numbers.
if(arem10==brem10) { return( (arem10==crem10) ? d : c); }
if(arem10==crem10) { return(b); }
return(a);
I am pretty sure there is a remainder calculation you can use in C# to solve this. In C it is %. Eg: 15%10 gives 5.
Now, let us assume we have four remainders: a,b,c & d.
If a==b:
if c==b:
return d
else:
return c
else:
if a==c:
return b
else:
return a
If you have lot of numbers instead of just 4:
def func(x):
if len(x)<3:
return NULL
if x[0]!=x[1]:
if x[0]==x[2]:
return x[1]
else:
return x[0]
for i in 2:(len(x)-1) :
if x[0]!=x[i]:
return x[i]
return NULL