C# Finding the Mode [duplicate] - c#

This question already has answers here:
printing all contents of array in C#
(13 answers)
Console.WriteLine(ArrayList) wrong output
(6 answers)
Closed 5 years ago.
In my program I'm trying to find the Mode from a list of integers. Logically wise my program is correct. However when I try to print out the Mode I get the following message "Mode: System.Collections.Generic.List'1[System.Int32]. The outcome I was expecting to print is "Mode: 2, 7" since these 2 numbers occur 3 times in the list of integers. What am I doing wrong here? Thanks in advance.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mode
{
class Program
{
static void Main(string[] args)
{
Test();
}
static void Test()
{
int[] values = { 1, 6, 4, 7, 9, 2, 5, 7, 2, 6, 5, 7, 8, 1, 3, 8, 2 };
List<int> mode = new List<int>();
mode = Mode(values);
Console.WriteLine("Mode: {0}", mode);
Console.ReadLine();
}
static List<int> Mode(int[] values)
{
int[] sorted = new int[values.Length];
values.CopyTo(sorted, 0);
Array.Sort(sorted);
List<int> result = new List<int>();
var counts = new Dictionary<int, int>();
int max = 0;
foreach (int num in sorted)
{
if (counts.ContainsKey(num))
counts[num] = counts[num] + 1;
else
counts[num] = 1;
}
foreach (var key in counts.Keys)
{
if (counts[key] > max)
{
max = counts[key];
result.Add(max);
}
}
return result;
}
}
}

You are trying to string.Format and object from a reference type class that doesn't have a custom .ToString() implementation. I recommend the use of String.Join (reference here)
C#
Console.WriteLine("Mode: {0}", String.Join(", ", mode));

user DesertFox mentioned properly.
You are trying to print a list. Intead of that, as per your requirement, make it as a single string using String.Join.
Modify your test method like below
static void Test()
{
try
{
int[] values = { 1, 6, 4, 7, 9, 2, 5, 7, 2, 6, 5, 7, 8, 1, 3, 8, 2 };
List<int> mode = new List<int>();
mode = Mode(values);
Console.WriteLine("Mode: {0}", String.Join(", ", mode));
Console.ReadLine();
}
catch(Exception ex)
{
}
}
Output

Print the items in the list rather than the list itself.

Related

Creating an array of a sorted sequential sub arrays starting with a sorted array [duplicate]

This question already has answers here:
Use LINQ to group a sequence of numbers with no gaps
(4 answers)
Closed 2 years ago.
Does Anyone know how to do this using C#? It's a coding challenge I have for a class.
Q: array of arrays. Group the input integers into sets that are contiguous in the input array.
e.g.
[1, 2, 3, 5, 6, 8, 9, 10] => [ [1, 2, 3], [5, 6], [8, 9, 10] ]
Try this:
public IEnumerable<IEnumerable<int>> ConsecutiveGroups(IEnumerable<int> items)
{
bool started = false;
var prev = int.MinValue;
var curSet = new List<int>();
foreach(var item in items.OrderBy(x=>x))
{
if (item != prev + 1 && started)
{
yield return curSet;
curSet = new List<int>();
}
curSet.Add(item);
started = true;
}
yield return curSet;
}
Here is a solution that uses the Segment operator from the MoreLinq library.
using System;
using System.Linq;
using static MoreLinq.Extensions.SegmentExtension;
public class Program
{
public static void Main()
{
int[] source = new[] { 1, 2, 3, 5, 6, 8, 9, 10 };
int[][] result = source
.Segment((current, previous, _) => current != previous + 1)
.Select(segment => segment.ToArray())
.ToArray();
Console.Write($"[{String.Join(", ", source)}]");
Console.Write($" => ");
Console.WriteLine($#"[{String.Join(", ", result
.Select(s => $"[{String.Join(", ", s)}]"))}]");
}
}
Output:
[1, 2, 3, 5, 6, 8, 9, 10] => [[1, 2, 3], [5, 6], [8, 9, 10]]
Try it on fiddle.
The Segment extension method has the signature below:
public static IEnumerable<IEnumerable<T>> Segment<T>(
this IEnumerable<T> source,
Func<T, T, int, bool> newSegmentPredicate);

"System.ArgumentOutOfRangeException" why is it showing? And why does the list<>number stop printing?

When I execute it, it stops printing at 8 and shows me
"System.ArgumentOutOfRangeException"
List<int> number = new List<int> { 1, 2, 2, 5, 4, 8, 6};
number.ForEach(delegate (int i) { Console.WriteLine(number[i]); });
Console.ReadKey();
As #tkausl already mentioned, ForEach passes you the value, not the index, it is not recommended to use List.ForEach actually, but if you still want to use it, you can do something like this:
number.ForEach(c => { Console.WriteLine(c); });
You can simply use a foreach like this:
foreach (var c in number)
{
Console.WriteLine(c);
}
You can find the discussion here: foreach vs someList.ForEach(){}
You can use this foreach ,
It will never make a mistake
List<int> number = new List<int> { 1, 2, 2, 5, 4, 8, 6 };
foreach (var item in number)
{
Console.WriteLine(item);
}

Check if all elements from one array are in the second array c#

How can I check if all the elements from one array are in another array? I have a 2d array with 3 arrays in it,and I want to check all of those 3 arrays if they have all the elements from allnumbers. array1=allnumbers ? array2=allnumbers ? array1=allnumber2 ? I need to return true if at least one contains all the elements from allnumbers. I have the code bellow,but I need it not to contain more than 3 control flow statements.
// int[,][] array = {array1, array2, array3}
static bool CheckLine(int[,][] array)
{
const int maxL = 9;
bool result = false;
int[] allnumbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
foreach (var singlearray in array)
{
int[] arr = singlearray;
int p = 0;
foreach (var num in allnumbers)
{
foreach (var arraynumber in singlearray)
{
if (arraynumber == num)
{
p++;
}
}
if (p == maxL)
{
result = true;
break;
}
}
}
return result;
}
If the values in your array are unique, and you don't care about the order they're in, this is a job for HashSet. (In other words, if your arrays contain sets of numbers you can treat them as sets.) Here's the basic outline of comparing sets.
var allnumbersSet = new HashSet<int>(allnumbers);
var allnumbers2Set= new HashSet<int>(allnumbers2);
if (allnumbersSet.IsSupersetOf(allnumbers2Set)) {
/* everything in allnumbers2 is also in allnumbers1 */
}
The people who put together DotNet did a really good job creating and optimizing those collection classes; you can use them with confidence to get good performance.
It seems, that you have two-dimensional jagged array. You can simplify your code by using Except and check the difference between allnumbers array and single row at every loop iteration.
static bool CheckLine(int[,][] array)
{
int[] allnumbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
foreach (var singlearray in array)
{
var diff = allnumbers.Except(singlearray);
if (!diff.Any())
{
return true;
}
}
return false;
}
If there is no elements in a difference, it'll mean that single item from source 2D array has all elements from allnumbers array.
Example of the usage
var array = new int[2, 2][];
array[0, 0] = new[] { 1, 2, 8 };
array[0, 1] = new[] { 3, 4, 5, 6 };
array[1, 1] = new[] { 3, 2, 1, 4, 5, 7, 6, 10, 9, 8 };
array[1, 0] = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
CheckLine(array);
The last two items satisfy the condition, execution will break and return true for { 3, 2, 1, 4, 5, 7, 6, 10, 9, 8 } array. Also don't forget to add using System.Linq directive at the top of file
Thank you for your help. I forgot to mention that I can use only "using System;"

Combinations without repetitions with must included in the combos

I have 2 list of ints and I need a list of all possible combinations without repetitions of 5 numbers. But it also needs to include all the ints from another list.
Example:
var takeFrom = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var mustInclude = new List<int> { 1, 3, 5 };
I have been using KwCombinatorics but it takes ages to finish. And almost 80% of the result is useless because it doesn't contain the ints from the mustInclude list.
Example of output:
var result = new List<int>
{
{ 1, 3, 5, 9, 10 },
{ 1, 3, 5, 8, 7 },
{ 1, 3, 5, 6, 9 },
}
It doesn't have to be in this order, as long as it doesn't contain repetitions.
Borrowing GetAllCombos from this Question, and using the idea from #juharr, I believe the following code gives you the results you are looking for.
List<int> takeFrom = new List<int> { 2, 4, 6, 7, 8, 9, 10 };
List<int> mustInclude = new List<int> { 1, 3, 5 };
protected void Page_Load(object sender, EventArgs e)
{
List<List<int>> FinalList = new List<List<int>>();
FinalList = GetAllCombos(takeFrom);
FinalList = AddListToEachList(FinalList, mustInclude);
gvCombos.DataSource = FinalList;
gvCombos.DataBind();
}
// Recursive
private static List<List<T>> GetAllCombos<T>(List<T> list)
{
List<List<T>> result = new List<List<T>>();
// head
result.Add(new List<T>());
result.Last().Add(list[0]);
if (list.Count == 1)
return result;
// tail
List<List<T>> tailCombos = GetAllCombos(list.Skip(1).ToList());
tailCombos.ForEach(combo =>
{
result.Add(new List<T>(combo));
combo.Add(list[0]);
result.Add(new List<T>(combo));
});
return result;
}
private static List<List<int>> AddListToEachList(List<List<int>> listOfLists, List<int> mustInclude)
{
List<List<int>> newListOfLists = new List<List<int>>();
//Go through each List
foreach (List<int> l in listOfLists)
{
List<int> newList = l.ToList();
//Add each item that should be in all lists
foreach(int i in mustInclude)
newList.Add(i);
newListOfLists.Add(newList);
}
return newListOfLists;
}
protected void gvCombos_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
List<int> drv = (List<int>)e.Row.DataItem;
Label lblCombo = (Label)e.Row.FindControl("lblCombo");
foreach (int i in drv)
lblCombo.Text += string.Format($"{i} ");
}
}
GetAllCombos gives you all the combinations without the numbers required by all Lists, and then the second AddListToEachList method will add the required numbers to each List.
As already suggested in the comments, you can remove the three required numbers from the list and generate the combinations of two instead of five.
Something like this:
takeFrom = takeFrom.Except(mustInclude).ToList();
listOfPairs = KwCombinatorics(takeFrom, 2);
result = listOfPairs.Select(pair => mustInclude.Concat(pair).ToList()).ToList();

Creating a method that returns an array

I'm to create a helper method that returns a new array whose elements are the square of an original array. But when I run the code, the console returns "System.Double[]". How can I fix this?
Here's the method code:
static double[] powerOfTwo(int[] arr)
{
double[] elevatedPower = new double[10];
elevatedPower[0] = Math.Pow(arr[0], 2);
elevatedPower[1] = Math.Pow(arr[1], 2);
elevatedPower[2] = Math.Pow(arr[2], 2);
elevatedPower[3] = Math.Pow(arr[3], 2);
elevatedPower[4] = Math.Pow(arr[4], 2);
elevatedPower[5] = Math.Pow(arr[5], 2);
elevatedPower[6] = Math.Pow(arr[6], 2);
elevatedPower[7] = Math.Pow(arr[7], 2);
elevatedPower[8] = Math.Pow(arr[8], 2);
elevatedPower[9] = Math.Pow(arr[9], 2);
return elevatedPower;
}
And the code to print it in the console:
static void Main(string[] args)
{
double[] powerValues = powerOfTwo(new int[] {1,2,3,4,5,6,7,8,9,10});
Console.Write(powerValues);
Console.ReadLine();
}
Your method works fine. But when you do Console.WriteLine(powerValues), the compiler calls ToString() method of the datatype which is System.double[].
foreach(var value in powerValues)
Console.WriteLine(value);
With Linq, using System.Linq;
var powerValues = (new int[] {1,2,3,4,5,6,7,8,9,10}).Select(x => x*x);
Actually, you are not printing your values. You try to print your array which returns it's full type name as System.Double[] since ToString calls it which is called by Console.Write explicitly.
You don't even need such a method. Just use Enumerable.Select to generate IEnumerable<int> which contains squared values like;
var values = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
foreach (var value in values.Select(i => i * i))
{
Console.Write(value); // 149162536496481100
}
And I would use Console.WriteLine to writing those values in separate lines each or put at least a white space after them if you choose Write like Console.Write(value + " ")
When you calling Console.Write(powerValues); actually call Console.Write(powerValues.ToString());ToString returns a string that represents the current object. For double[] this is "System.Double[]".
Change your code like this :
static void Main(string[] args)
{
double[] powerValues = powerOfTwo(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
foreach (var value in powerValues)
{
Console.WriteLine(value);
}
Console.ReadLine();
}
Write Your code in just simple one line using below code.
new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }.ToList().ForEach(i => Console.WriteLine(i * i));
and each value are display in new line so result are also good compare to other.

Categories