How to measure the amount of times 0 & 1 occurs - c#

Here is the code that outputs 1 or 0 depending on the equality of the 2 arrays
static void Main(string[] args)
{
while (true)
{
Console.WriteLine(Here());
}
Here is where the magic happens.
static int Here()
{
Random rnd = new Random();
PlayerInput();
int[] intarray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
string[] sarray = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
int i = rnd.Next(10); // creates a number between 1 and 10
int x = rnd.Next(10);
string iarray = intarray[x].ToString();
if (iarray == sarray[i])
{
return 1;
}
else
{
return 0;
}
}
it outputs 0 when the two arrays don't equal and 1 vise versa. now I want to count the amount of times it outputs 0 & 1.
Questions:
How could I do that?
Should I transfer the output to an array for easier manipulation?

Unless I'm misunderstanding your question, it seems like you could simply have two counter variables:
static void Main(string[] args)
{
int totalOnes = 0;
int totalZeroes = 0;
while (true) // need to replace this with something that will actually exit!!
{
int ret = Here();
if (ret == 1) totalOnes++; else totalZeroes++;
Console.WriteLine(ret);
}
Console.WriteLine("Total Ones: {0} Total Zeroes: {1}", totalOnes, totalZeroes);
}
EDIT: Thanks to L J for pointing out that your while loop will never exit since you have while (true). You need to address that.

like this
static void Main(string[] args)
{
var zeroCount = 0;
var oneCount = 0;
while (true)
{
var result = Here();
if (result == 1) oneCount++;
if (result == 0) zeroCount++;
Console.WriteLine($"Actual result {result}, zero count {zeroCount}, One count {oneCount}");
}
}

static int Here()
{
Random rnd = new Random();
PlayerInput();
int[] intarray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
string[] sarray = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
**var Count1 = 0;
var Count0 = 0;**
int i = rnd.Next(10); // creates a number between 1 and 10
int x = rnd.Next(10);
string iarray = intarray[x].ToString();
if (iarray == sarray[i])
{
**Count1++;**
return 1;
}
else
{
**Count0++;**
return 0;
}
}
Count0 will contain the number of times 0 was outputted.
Count1 will contain the number of times 1 was outputted.

Related

How to out all the int values from a string array and store that int values in another array

There are words and int values in a string array. My goal is to retrieve the int values from another array. I have seen two methods for converting and finding int values from a string array.
To get all the int values from the string, I first create another int array and use an Array.ConvertAll init. The second method is to loop through isDigit().
Now, the problem is that I cannot find a way to store that value in an int array that has been converted to an int. The final goal is to find the minimum and maximum value from the converted values.
string[] strArray1 = { "Bautik", "99", "Sagar", "3", "Tisha", "12", "Riya", "109" };
int result;
int[] num = Array.ConvertAll(strArray1, x =>
{
bool convertStrIntoInt = int.TryParse(x, out int result);
return result;
});
In here, I don't how to get the result outside of it to do a sort to find min and max values.
I don't understand what you want but if you want only int then use this
List<int> list = new List<int>();
string[] strArray1 = { "Bautik", "99", "Sagar", "3", "Tisha", "12", "Riya", "109" };
foreach (string str in strArray1)
{
if (int.TryParse(str, out int val))
{
list.Add(val);
}
}
int[] vs = list.ToArray();
now all the int values are stored in vs array, if there are some words which contains the int value and you want them to be extracted you can use regex to find the digits in word also
I'd use LINQ for this:
string[] strArray1 = { "Bautik", "99", "Sagar", "3", "Tisha", "12", "Riya", "109" };
int[] num =
(
from x in strArray1
let n = int.TryParse(x, out int n) ? (int?)n : null
where n.HasValue
select n.Value
).ToArray();
That outputs:
Then you can do this:
int max = num.Max();
int min = num.Min();
Little optimized solution could be something like below
string[] strArray1 = { "Bautik", "99", "Sagar", "3", "Tisha", "12", "Riya", "109" };
var numArray = strArray1.Where(var=> new Regex(#"^\d+").IsMatch(var)).ToArray();
var res = Array.ConvertAll(numArray,s => int.Parse(s));
If we don't want to use Regex can try something like below
string[] strArray1 = { "Bautik", "99", "Sagar", "3", "Tisha", "12", "Riya", "109" };
int testNum;
var numArray = strArray1.Where(var=> int.TryParse(var,out testNum)).ToArray();
var res = Array.ConvertAll(numArray,s => int.Parse(s));
You can then get max and min value using
res.Min(), res.Max()
This should give you a starting point for your problem
You can try Regex like below :
string[] strArray1 = {"Bautik", "99", "Sagar", "3", "Tisha", "12", "Riya", "109"};
int[] num = strArray1.Where(v => Regex.IsMatch(v, #"^\d+$")).Select(int.Parse).ToArray();
int min = num.Min();
int max = num.Max();
As you don't want to use Regex, you can go with your solution, just do a small modification to get your desired result. Try this :
string[] strArray1 = { "Bautik", "99", "Sagar", "3", "Tisha", "12", "Riya", "109" };
int[] num = Array.ConvertAll(strArray1, x =>
{
bool convertStrIntoInt = int.TryParse(x, out int result);
return result;
}).Where(x => x > 0).ToArray();
int max = num.OrderByDescending(c => c).ToArray()[0];
int min = num.OrderBy(c => c).ToArray()[0];
Here is another way to get int values from a string array into an int array.
Try it on dotnetfiddle.
public static class Extensions
{
public static int[] ToIntegerArray(this string[] sender)
{
var intArray = Array
.ConvertAll(sender,
(input) => new {
IsInteger = int.TryParse(input, out var integerValue),
Value = integerValue
})
.Where(result => result.IsInteger)
.Select(result => result.Value)
.ToArray();
return intArray;
}
}
Use
string[] strArray1 = { "Bautik", "99", "Sagar", "3", "Tisha", "12", "Riya", "109" };
int[] intArray = strArray1.ToIntegerArray();
Array.Sort(intArray);
foreach (var value in intArray)
{
Console.WriteLine(value);
}
Console.WriteLine($"Min: {intArray.Min()}");
Console.WriteLine($"Max: {intArray.Max()}");
Targeting your intial question:
I don't [know] how to get the result outside of it to do a sort to find min and max values.
You simply can't get a complete solution for your Problem using ConvertAll() with a "normal" int.
So if we take a look at your result:
int[] num = Array.ConvertAll(strArray1, x =>
{
bool convertStrIntoInt = int.TryParse(x, out int result);
return result;
});
// num: int[8] { 0, 99, 0, 3, 0, 12, 0, 109 }
We can see each word will result in a 0, since 0 will be returned if the parsing failed - see: Int32.TryParse(...).
And therefore it is impossible to differentiate between an real 0 in your input or a word, which could not be parsed.
But we can tweek the convert a little bit by using Nullable<int>/int?
int?[] num = Array.ConvertAll(strArray1, x =>
{
return (int?)( int.TryParse(x, out int result) ? result : null);
});
// num: Nullable<int>[8] { null, 99, null, 3, null, 12, null, 109 }
So with this we are able to differ between a 0 and a word - represented by null.
Now you can perform other operations like num.Max() and num.Min().
If you need an int[] array, you have add some more function calls.
int[] num = Array.ConvertAll(strArray1, x =>
{
return (int?)( int.TryParse(x, out int result) ? result : null);
}).OfType<int>().ToArray();
//num: int[4] { 99, 3, 12, 109 }
So this is not quite optimal.
My solution for this would be a simple loop.
// Your intput
string[] strArray1 = { "Bautik", "99", "Sagar", "3", "Tisha", "12", "Riya", "109" };
// Output Variables
List<int> result = new();
int min = int.MaxValue;
int max = int.MinValue;
// Loop
foreach( string item in strArray1)
{
if(int.TryParse(item, out int value))
{
result.Add(value);
min = min > value ? value : min;
max = max < value ? value : max;
}
}
// Output
// result: List<int>[4] { 99, 3, 12, 109 }
// min: 3
// max: 109
As already mentioned by Gian Paolo in the comments of this answer
working with a List<int> is much easier than working with an int[]
..., but if you really need an array, then you can just call ToArray().
int[] resultArray = result.ToArray();
Which results in int[4] { 99, 3, 12, 109 }.

Splitting String Arrays into Groups

There is a string [] yield that can contain N count data. I have defined 15 count to be an example.
I want to divide these data into 6 groups.However, I cannot load the last remaining items into the array.
Where am I making a mistake?
string[] tags = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"};
double tagLength = (int)Math.Floor(tags.Length / (double)6);
for (int i = 0; i <= tagLength-1; i++)
{
string[] groupArrays = new string[6];
Array.Copy(tags, i * 6, groupArrays, 0, 6);
}
The output i see
[0] = {1,2,3,4,5,6}
[1] = {7,8,9,10,11,12}
Should be output
[0] = {1,2,3,4,5,6}
[1] = {7,8,9,10,11,12}
[2] = {13,14,15}
I would suggest changing your code to calculate the number of groups you need to this:
int groups = (count / groupSize);
bool hasPartialGroup = count % groupSize != 0;
if (hasPartialGroup)
{
++groups;
}
The result of the first line will be integer division, so 15 / 6 will result in 2. We then see if there is a remainder using the remainder operator (%): count % groupSize. If its result isn't 0, then there is a remainder, and we have a partial group, so we have to account for that.
So for groups = 15 and groupSize = 6, we'll get count = 3. For groups = 12 and groupSize = 6, we'll get count = 2, etc.
Fixing your code to use this, it might look like:
string[] tags = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"};
int count = tags.Length;
const int groupSize = 6;
int groups = (count / groupSize);
bool hasPartialGroup = count % groupSize != 0;
if (hasPartialGroup)
{
++groups;
}
for (int i = 0; i < groups; i++)
{
// you can't copy beyond the end of the array so we have to choose between the remaining ungrouped items and the group size
int currentGroupSize = Math.Min(tags.Length - i*groupSize, groupSize);
// I'm assuming for a partial group you only want this to be as big as the number of items.
// If you want it to always be 6 then change new string[currentGroupSize] to new string[groupSize] and you should be OK.
string[] groupArrays = new string[currentGroupSize];
Array.Copy(tags, i * groupSize, groupArrays, 0, currentGroupSize);
Console.WriteLine(string.Join(",", groupArrays));
}
Try it online // Example with fixed group size
Alternatively, you could create a batching helper method:
private static IEnumerable<T[]> BatchItems<T>(IEnumerable<T> source, int batchSize)
{
var collection = new List<T>(batchSize);
foreach (var item in source)
{
collection.Add(item);
if (collection.Count == batchSize)
{
yield return collection.ToArray();
collection.Clear();
}
}
if (collection.Count > 0)
{
yield return collection.ToArray();
}
}
This will collect batchSize number items together and then return one group at a time. You can read about how this works with yield return here.
Usage:
string[] tags = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"};
List<string[]> batchedTags = BatchItems(tags, 6).ToList();
This will result in 3 string arrays, containing 1,2,3,4,5,6, 7,8,9,10,11,12, and 13,14,15.
You could also make this into an extension method.
Try it online
If you mean why you are not getting groups of 6, the reason for this is that you are flooring the length of tags / 6. So, if the last group has the length of less that 6, it won't get added. Add this to the end:
if (tags.Length%6!=0) { string[] groupArrays = tags[i..tags.Length] } // You can do this manually.
As said before, it's because you use Math.Floor(). Use either Math.Ceiling or remove the -1 from i<= taglength - 1.
Array.Copy will still produce errors when you're tags aren't an exact multiple of 6.
Below code should do the trick and won't produce an error
string[] tags = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15" };
int baselength = 6;
double tagLength = (int)Math.Floor(tags.Length / (double)6);
int length = baselength;
for (int i = 0; i <= tagLength; i++)
{
string[] groupArrays = new string[baselength];
if (i == tagLength)
length = ((i + 1) * length) - tags.Length;
if(length > 0 && length < baselength)
Array.Copy(tags, i * 6, groupArrays, 0, length);
}
Because you use Math.Floor(...). You should use Math.Ceiling(...) instead.
(int)Math.Floor(15d / 6d) // returns 2 >> 2 groups.
(int)Math.Ceiling(15d / 6d) // returns 3 >> 3 groups.
Beware though, you will get an ArgumentOutOfRangeException in Array.Copy, since index 3 * 6 does not exist. You will have to find a way around that.
One possible solution:
string[] tags = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15" };
double tagLength = (int)Math.Ceiling(tags.Length / (double)6);
for (int i = 0; i <= tagLength - 1; i++)
{
int arrLength = (i + 1) * 6 <= tags.Length ? 6 : tags.Length % 6;
string[] groupArrays = new string[arrLength]; // or six if you always want a length of 6
Array.Copy(tags, i * 6, groupArrays, 0, arrLength);
}
Or using Linq:
for (int i = 0; i < (int)Math.Ceiling(tags.Length / 6d); i++)
{
string[] groupArrays = tags.Skip(i * 6).Take(6).ToArray();
}

Dynamic number of nested for loops to list unique combinations of objects

I have n number of lists of objects which I need to convert to a list of object arrays each containing a unique combination of objects from the original lists.
Example:
myList[0] = new List<object>(){a, b, c, d};
myList[1] = new List<object>(){"0", "1", "2", "3", "4"};
myList[2] = new List<object>(){0, 1, 2};
myList[3] = new List<object>(){aClass, bClass}
etc.
Needs to become:
newList[0] = new object[]{a, "0", 0, aClass};
newList[1] = new object[]{a, "0", 0, bClass};
newList[2] = new object[]{a, "0", 1, aClass};
newList[3] = new object[]{a, "0", 1, bClass};
newList[4] = new object[]{a, "0", 2, aClass};
newList[5] = new object[]{a, "0", 2, bClass};
newList[6] = new object[]{a, "1", 0, aClass};
newList[7] = new object[]{a, "1", 0, bClass};
newList[8] = new object[]{a, "1", 1, aClass};
newList[9] = new object[]{a, "1", 1, bClass};
newList[10] = new object[]{a, "1", 2, aClass};
newList[11] = new object[]{a, "1", 2, bClass};
etc.
The order of the variables has to be preserved (the list at myList[0] has to be first, etc) because these object arrays are the parameters passed via reflection:
Indicator temp = (Indicator) newIndicator.Invoke(this, newList[i]);
If the number of lists of objects were static, it might look something like the following:
List<object[]> newList = new List<object[]>();
for(int i = 0; i < myList[0].Count; i++)
{
for(int i2 = 0; i2 < myList[1].Count; i2++)
{
for(int i3 = 0; i3 < myList[2].Count; i3++)
{
for(int i4 = 0; i4 < myList[3].Count; i4++)
{
object[] temp = new object[]{myList[0][i], myList[1][i2], myList[2][i3], myList[3][i4]};
newList.Add(temp);
}
}
}
}
My latest attempt was to create a list of indicies which held the current index of each list and incremented it appropriately, but my math doesn't seem to work out as I scale it out.
private List<object[]> ToParametersList(List<List<object>> listOfLists)
{
int counter = 1;
foreach(List<object> list in listOfLists){ counter *= list.Count; }
List<object[]> returnList = new List<object[]>();
List<int> indicies = new List<int>();
int tempSplit = 0;
List<int> splits = new List<int>();
List<int> splitcounters = new List<int>();
for(int i = 0; i < listOfLists.Count; i++)
{
if(i == 0 && listOfLists[0].Count > 2)
{
splits.Add(counter / listOfLists[0].Count);
tempSplit = counter / listOfLists[0].Count;
} else if(i > 0 && listOfLists[i].Count > 2) {
splits.Add(tempSplit / listOfLists[i].Count);
tempSplit /= listOfLists[i].Count;
} else if(listOfLists[i].Count == 2)
{
splits.Add(1);
}
indicies.Add(0);
splitcounters.Add(1);
}
for(int i = 0; i < counter; i++)
{
object[] newObject = new object[listOfLists.Count];
for(int i2 = 0; i2 < listOfLists.Count; i2++)
{
if(i < splits[i2] * splitcounters[i2] && ((indicies[i2] < listOfLists[i2].Count && listOfLists[i2].Count > 2) || indicies[i2] < listOfLists[i2].Count - 1))
{
newObject[i2] = listOfLists[i2][indicies[i2]];
}
else if(i >= splits[i2] * splitcounters[i2] && ((indicies[i2] < listOfLists[i2].Count && listOfLists[i2].Count > 2) || indicies[i2] < listOfLists[i2].Count - 1))
{
indicies[i2]++;
splitcounters[i2]++;
newObject[i2] = listOfLists[i2][indicies[i2]];
}
else
{
indicies[i2] = 0;
splitcounters[i2]++;
newObject[i2] = listOfLists[i2][indicies[i2]];
}
}
returnList.Add(newObject);
}
return returnList;
}
I have also gone through many of the recursion questions on here and am still having trouble understanding how to apply them to this particular situation (I am relatively new to recursion).
Any help would be greatly appreciated!
EDIT: In Cartesian products with n number of list the OP's post is confusing and the answer provided has no explanation of what is happening. The link to Eric Lippert's Blog is a general overview of Cartesian products which did not help me break the barrier that I needed to properly understand this in the context of what I was trying to do.
To be honest i did not read your last attempt. Other ways using Linq is great but if you really want a recursion follow this way.
To create a good recursion you need to look at which part of method varies and which part does not. the method should take parameters that varies for each call. Also you need if-else to end recursion somewhere.
List<object[]> newList = new List<object[]>();
for(int i = 0; i < myList[0].Count; i++)
{
for(int i2 = 0; i2 < myList[1].Count; i2++)
{
for(int i3 = 0; i3 < myList[2].Count; i3++)
{
for(int i4 = 0; i4 < myList[3].Count; i4++)
{
object[] temp = new object[]{myList[0][i], myList[1][i2], myList[2][i3], myList[3][i4]};
newList.Add(temp);
}
}
}
}
We want to use recursion in this method to be able to use it for any lenght of list.To do this you must convert loop into recursion call. but now you have unknown amount of loops.
The solution is to use params keyword. you can send any amount of int to method. this int's holds the variables i1, i2 , i3 , i4 .... just like the above method you have wrote.
The length of this array (params int[]) is exactly number of loops inside the normal method.
private static void Combine(List<List<object>> myList,List<object[]> newList,params int[] loopInd)
{
if (loopInd.Length <= myList.Count) // should not exceed number of loops.
{
int currentCount = myList[loopInd.Length - 1].Count;
while (loopInd[loopInd.Length - 1] < currentCount) // i<myList[0] , i2<myList[1] , i3<myList[2]
{
Combine(myList, newList, loopInd.Concat(new[] {0}).ToArray()); // Go for inner loop
loopInd[loopInd.Length - 1]++; // i++, i2++ , i3++ ...
}
}
else // no more loops.add the object[] into newList
{
int j = 0;
object[] temp = loopInd.Take(loopInd.Length - 1).Select(i => myList[j++][i]).ToArray();
newList.Add(temp);
}
}
The comments above shows the representations in normal method.
Then you can use it in this way.
List<List<object>> myList = new List<List<object>>();
myList.Add(new List<object>() { a, b, c, d });
myList.Add(new List<object>() { "0", "1", "2", "3", "4" });
myList.Add(new List<object>() { 0, 1, 2 });
myList.Add(new List<object>() {aClass, bClass});
List<object[]> newList = new List<object[]>();
Combine(myList, newList, 0);
// The newList is now what you want
Edit :
If you are after performance you can convert this Linq part
int j = 0;
object[] temp = loopInd.Take(loopInd.Length - 1).Select(i => myList[j++][i]).ToArray();
newList.Add(temp);
Into code
int j = 0;
object[] temp = new object[loopInd.Length - 1];
for (int i = 0; i < loopInd.Length - 1; i++,j++)
{
temp[i] = myList[j][loopInd[i]];
}
Here is a solution that accepts a number of lists that is unknown at compile time.
Method CombineArrayOfLists does what you need:
static List<List<object>> CombineArrayOfLists(List<object>[] myList)
{
List<List<object>> result = myList[0].Select(element => new List<object>() { element }).ToList();
for (int i = 1; i < myList.Length; i++)
{
result = (from c1 in result from c2 in myList[i] select new List<object>(c1) {c2}).ToList();
}
return result;
}
Note that you need to define the desired behavior in case any list in your array of lists is empty. To handle that case you may need to add an if statement to skip that list (if that is the appropriate thing to do).
A complete example written in a slightly more verbose form that could be easier to understand:
class Program
{
static void Main(string[] args)
{
List<object>[] myList = new List<object>[4];
AClass aClass = new AClass();
BClass bClass = new BClass();
myList[0] = new List<object>() { "a", "b", "c", "d" };
myList[1] = new List<object>() { "0", "1", "2", "3", "4" };
myList[2] = new List<object>() { 0, 1, 2 };
myList[3] = new List<object>() { aClass, bClass };
List<List<object>> result = CombineArrayOfLists(myList);
PrintList(result);
}
static List<List<object>> CombineArrayOfLists(List<object>[] myList)
{
List<List<object>> result = myList[0].Select(element => new List<object>() { element }).ToList();
for (int i = 1; i < myList.Length; i++)
{
result = CombineCollections(result, myList[i]).ToList();
}
return result;
}
private static IEnumerable<List<object>> CombineCollections(IEnumerable<List<object>> collection1, List<object> collection2)
{
return from c1 in collection1 from c2 in collection2 select new List<object>(c1) { c2 };
}
// A more verbose form of CombineCollections that may be easier to understand:
//private static IEnumerable<List<object>> CombineCollections(IEnumerable<List<object>> collection1, List<object> collection2)
//{
// foreach (List<object> c1 in collection1)
// {
// foreach (object c2 in collection2)
// {
// List<object> l1 = new List<object>(c1) { c2 };
// yield return l1;
// }
// }
//}
private static void PrintList(List<List<object>> collection)
{
collection.ForEach(list =>
{
list.ForEach(element =>
{
Console.Write(element);
Console.Write(" ");
});
Console.WriteLine();
});
}
}
public class AClass
{ }
public class BClass
{ }
You can use LINQ to get Cartesian product of list of objects.
List<object> arr1 = new List<object> { "a", "b", "c" };
List<object> arr2 = new List<object> { 3, 2, 4,5 };
List<object> arr3 = new List<object> { "0", "1", "2", "3", "4" };
var result = from x in arr1
from y in arr2
from z in arr3
select new { x = x, y = y,z=z };
List<object[]> newList = new List<object[]>();
foreach (var line in result)
{
newList.Add(new object[] { line.x, line.y, line.z });
}
foreach (var obj in newList)
{
foreach (var ele in obj)
{
Console.Write(ele.ToString() + " ");
}
Console.WriteLine();
}
Console.ReadKey();
This will provide you with the list of one objects in the way you require.
Here is the running example
http://csharppad.com/gist/45ebe7c9576dab9c00b8

how to add array elements in one array according to condition in other array in C#?

I have two arrays say one is string array and the other is int array
string array has---> "11","11","11","11","12","12" elements and the int array has 1,2,3,4,5,6 respectively.
I want result two arrays containing string array--->"11","12"
and int array---->10,11
If the string array has duplicate elements, the other array containing that respective index value must be added .For example "11" is in 1st,2nd,3rd,4th index So its corresponding value must sum of all those elements in other array.Can it be done?
I have written some code but unable to do it..
static void Main(string[] args)
{
//var newchartValues = ["","","","","","",""];
//var newdates = dates.Split(',');
//string[] newchartarray = newchartValues;
//string[] newdatearray = newdates;
int[] newchartValues = new int[] { 1, 2, 3, 4, 5, 6 };
string[] newdates = new string[] { "11", "11","11","12","12","12" };
int[] intarray = new int[newchartValues.Length];
List<int> resultsumarray = new List<int>();
for (int i = 0; i < newchartValues.Length - 1; i++)
{
intarray[i] = Convert.ToInt32(newchartValues[i]);
}
for (int i = 0; i < newdates.Length; i++)
{
for (int j = 0; j < intarray.Length; j++)
{
if (newdates[i] == newdates[i + 1])
{
intarray[j] += intarray[j + 1];
resultsumarray.Add(intarray[j]);
}
}
resultsumarray.ToArray();
}
}
I don't quite get what you need, but I think I fixed your code, result will contain 10 and 11 in this example:
int[] newchartValues = new int[] { 1, 2, 3, 4, 5, 6 };
string[] newdates = new string[] { "11", "11", "11", "11", "12", "12" };
List<int> result = new List<int>();
if (newdates.Length == 0)
return;
string last = newdates[0];
int cursum = newchartValues[0];
for (var i = 1; i <= newdates.Length; i++)
{
if (i == newdates.Length || newdates[i] != last)
{
result.Add(cursum);
if (i == newdates.Length)
break;
last = newdates[i];
cursum = 0;
}
cursum += newchartValues[i];
}
Here is an approach that should do what you want:
List<int> resultsumarray = newdates
.Select((str, index) => new{ str, index })
.GroupBy(x => x.str)
.Select(xg => xg.Sum(x => newchartValues[x.index]))
.ToList();
Result is a List<int> with two number: 6, 15
Something like this?
int[] newchartValues = new int[] { 1, 2, 3, 4, 5, 6 };
int[] newdates = new int[] { 11, 11,11,12,12,12 };
var pairs = Enumerable.Zip(newdates, newchartValues, (x, y) => new { x, y })
.GroupBy(z => z.x)
.Select(g => new { k = g.Key, s = g.Sum(z => z.y) })
.ToList();
var distinctDates = pairs.Select(p => p.k).ToArray();
var sums = pairs.Select(p => p.s).ToArray();

Counting the number of times a value appears in an array

So what's a good, simple algorithm to create a loop in C# where every time a certain value appears in an array it adds 1 to a counter in another array?
For example I have this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication22
{
class Program
{
const int SIZE = 12;
static void Main(string[] args)
{
int[] numbers = new int[SIZE] {5, 5, 5, 7, 7, 7, 9, 7, 9, 9, 9, 1};
string[] letters = new string[SIZE] { "m", "m", "s", "m", "s", "s", "s", "m", "s", "s", "s", "s" };
int[] values = new int[SIZE] {15, 22, 67, 45, 12, 21, 24, 51, 90, 60, 50, 44};
string[] status = new string[SIZE] { "f", "m", "f", "a", "m", "f", "f", "f", "m", "f", "m", "f" };
int[] Count = new int[4];
int x = 0;
int i = 0;
for (i = 0; i < SIZE - 1; i++)
{
if (numbers[i] > 0 && numbers[i] < SIZE)
{
x = Count[i];
Count[x]++;
}
}
for (i = 0; i < 4; i++)
{
Console.WriteLine("{0}", Count[4]);
}
}
}
}
I am only counting the number of times 4 numbers appear in the numbers array. Someone suggested I use the method in the first loop but it doesn't seem to be working and creates an error that the index is out of bounds in the array. I want to display the number of times each of those numbers(5, 7,9 and 1) appear in 4 rows.
EDIT: Without using LINQ or any other fancy thing like Dictionary or whatever.
You're getting an index out of bounds error because of this section:
for (i = 0; i < SIZE - 1; i++)
{
if (numbers[i] > 0 && numbers[i] < SIZE)
{
x = Count[i];
Notice that you're iterating through 0 to SIZE - 1 (11) when Count only has a size of 4.
You can do this task pretty easily with LINQ though.
int[] numbers = new int[SIZE] { 5, 5, 5, 7, 7, 7, 9, 7, 9, 9, 9, 1 };
var count = numbers
.GroupBy(e => e)
.Where(e => e.Count() == 4)
.Select(e => e.First());
So it groups the numbers by their value, we then refine the list to only include groups of 4, then select the first of each to be left with a collection of ints.
Here is a non-LINQ based solution using a Dictionary to store the count of numbers.
int[] numbers = new int[SIZE] { 5, 5, 5, 7, 7, 7, 9, 7, 9, 9, 9, 1 };
var dictionary = new Dictionary<int, int>();
var numbersWithFour = new List<int>();
foreach (var number in numbers)
{
if (dictionary.ContainsKey(number))
dictionary[number]++;
else
dictionary.Add(number, 1);
}
foreach (var val in dictionary)
{
if (val.Value == 4)
{
numbersWithFour.Add(val.Key);
}
}
With a little modification to your program you can get some results.
int[] numbers = new int[SIZE] { 5, 5, 5, 7, 7, 7, 9, 7, 9, 9, 9, 1 };
string[] letters = new string[SIZE] { "m", "m", "s", "m", "s", "s", "s", "m", "s", "s", "s", "s" };
int[] values = new int[SIZE] { 15, 22, 67, 45, 12, 21, 24, 51, 90, 60, 50, 44 };
string[] status = new string[SIZE] { "f", "m", "f", "a", "m", "f", "f", "f", "m", "f", "m", "f" };
// Set the size of Count to maximum value in numbers + 1
int[] Count = new int[9 + 1];
int x = 0;
int i = 0;
for (i = 0; i < SIZE - 1; i++)
{
if (numbers[i] > 0 && numbers[i] < SIZE)
{
// Use value from numbers as the index for Count and increment the count
Count[numbers[i]]++;
}
}
for (i = 0; i < Count.Length; i++)
{
// Check all values in Count, printing the ones where the count is 4
if (Count[i] == 4)
Console.WriteLine("{0}", i);
}
Output:
7
9
Use LINQ to do the work
using System.Linq;
var numQuery =
from num in numbers
where num == 5
select num;
Console.WriteLine("Count of 5: " + numQuery.Count);
Or use the method syntax
var numQuery = numbers.Where(num => num == 5);
Console.WriteLine("Count of 5: " + numQuery.Count);
See here for the overview and here for query vs method-syntax.
Found a sample for GroupBy, look here.
I used Regex for my solution since I only had three values.
String results = "" + one.ToString() + " " + two.ToString() + " " + three.ToString();
int count1 = Regex.Matches(results, #one.ToString()).Count;
int count2 = Regex.Matches(results, #two.ToString()).Count;
int count3 = Regex.Matches(results, #three.ToString()).Count;
Seems 'hacky', but worked for me. It'll work with strings or numbers but only if you're working with a few values. Pretty efficient in that case. If not, I think the other answer would be a better option.
your count array has 4 fields ...
one with the index 0, 1, 2 and 3
so what will happen if a number like 4 (or greater) happens to be counted? yor code tries to access index 4 ... which does not exist ...
This is the naive Solution for finding " Counting the number of times a value appears in an array "
Idea : Build a Hash map in Array
Solution :
using System.Collections.Generic;
using System.Text;
namespace GetArrEleFrequency
{
class Program
{
static int[] Arr = new int[5] { 3, 3, 0, 2, 0 };
static int[] Key = new int[5];
static int[] value = new int[5];
static void Main(string[] args)
{
int keyItr = -1, ValueItr = -1, tempIndex = 0, tempValue = 0;
for (int i=0; i <= Arr.Length-1;i++) {
if (!(isPresent(Arr[i]))) {
keyItr += 1;ValueItr += 1;
Key[keyItr] = Arr[i];
value[ValueItr] = 1;
} else {
value[tempIndex] = value[getIndex(Arr[i])] + 1;
}
}
for (int i=0;i<=Key.Length-1;i++) {
Console.WriteLine(Key[i] + "-" + value[i]);
}
Console.ReadKey();
}
public static Boolean isPresent(int num) {
Boolean temp = false;
for (int i=0; i <= Key.Length-1;i++) {
if (Key[i] == num) {
temp = true;
break;
} else {
temp = false;
}
}
return temp;
}
public static int getIndex(int num) {
int temp = 0;
for (int i=0;i<=Key.Length-1;i++) {
if (Key[i] == num) {
break;
} else {
temp += 1;
}
}
return temp;
}
}
}
Output :
3 - 2
0 - 2
2 - 1
0 - 0
0 - 0
static void Main(string[] args)
{
int[] arr = new int[] { 45, 34, 23, 67, 10, 99,99,10 };
foreach(int i in arr.Distinct())
{
int count = occurance(arr,i);
Console.WriteLine(i + "-Occurred For :" + count);
}
Console.ReadLine();
}
public static int occurance(int[] arr,int x)
{
int count = 0;
foreach(int num in arr)
{
if(x==num)
{
count++;
}
}
return count;
}
}
I think the question hasn't been answered without using lists, LINQ or Dictionary so here is my suggestion:
using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
class Program
{
static void Main()
{
int n = int.Parse(Console.ReadLine()); // the size of the array
int[] ints = new int[n]; //an array to store the items, integers in this case
int[] freq = new int[n]; //an array to store the frequency of each element with the same index
for (int i = 0; i < n; i++) // a loop that takes each element on a new row
{
ints[i] = int.Parse(Console.ReadLine());
}
for (int j = 0; j < n; j++) // loops to iterate through the ints array and pick up the
// frequencies and store them in the freq array
{
for (int k = 0; k < n; k++)
{
if (ints[j] == ints[k] && k != n)
{
freq[j]++;
}
}
}
int indexAtMax = freq.ToList().IndexOf(freq.Max()); //this picks up the index of the first maximum count
int mostFrequentNumber = ints[indexAtMax]; // the actual number behind the same inex in the ints array
int frequencyOfRepeating = freq[indexAtMax]; // the actual number of the frequency
Console.WriteLine($"The most frequent number is:{mostFrequentNumber} and it repeats {frequencyOfRepeating} times)");
}
}

Categories

Resources