Counting the number of times a value appears in an array - c#

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)");
}
}

Related

How can sort by odd,even row?

I hava jagged Array
I want sort first,third row ascending order and second,fourth row descending order
public class JaggedArrayTest {
public static void Main() {
int[][] arr = new int[4][] {
new int[] {
11,
78,
56,
21
},
new int[] {
2,
7,
5,
6
},
new int[] {
8,
3,
9,
12
},
new int[] {
1,
10,
19,
17
}
};
// Traverse array elements
for (int i = 0; i < arr.Length; i++) {
for (int j = 0; j < arr[i].Length; j++) {
System.Console.Write(arr[i][j] + " ");
}
System.Console.WriteLine();
}
}
}
I want output like this
11, 21, 56, 78 
7, 6, 5,2
3, 8,9,12
19,17,10,1
Algo:-
Loop through each row.
Use Array.Sort() to sort each row
for(int row = 0; row < arr.Length; row++)
{
Array.Sort(arr[row]);
}
Although a little "allocatey", this can be done with linq and the remainder operator (to test for odd or even) fairly easily
The remainder operator ``% computes the remainder after dividing its
left-hand operand by its right-hand operand.
var results = arr.Select((values, i)
=> (i % 2 == 0 ? values.OrderBy(x => x) : values.OrderByDescending(x => x)).ToArray())
.ToArray();
foreach (var values in results)
Console.WriteLine(string.Join(", ",values));
Or an in situ, less "allocatey", and more idiomatic approach
for (var i = 0; i < arr.Length; i++)
{
Array.Sort(arr[i]);
if(i % 2 != 0)
Array.Reverse(arr[i]);
}
Output
11, 21, 56, 78
7, 6, 5, 2
3, 8, 9, 12
19, 17, 10, 1

c# printing an array list which is made of generic lists

There is an array list, it is made of generic lists and generic lists' elements are class variables. How can i print the whole arrayList? I have to use array list, generic lists and a class. Logic is something like Array List[Generic Lists[Classes]].
namespace temp
{
internal class tempClass
{
public string Name;
public int Number;
}
internal class Program
{
private static void Main(string[] args)
{
string[] Names = { "a", "b", "c", "d", "e", "f","g", "h", "i", "j", "k", "l", "m","n", "o", "p", "q", "r", "s", "t", "u","v", "w", "x", "y", "z", "z2", "z3" };
int[] Number = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,20, 21, 22, 23, 24, 25, 26, 27, 28 };
ArrayList arrayList = new ArrayList();
int counter = 0;
List<tempClass> genericList;
tempClass ClassExample;
for (int i = 0; i < Names.Length;)
{
genericList = new List<tempClass>();
int elementCount = (int)Math.Pow(2, counter);
for (int j = 0; j < elementCount; j++)
{
ClassExample = new tempClass();
ClassExample.Name = Names[i];
ClassExample.Number = Number[i];
genericList.Add(ClassExample);
i++;
if (i == Names.Length) break;
}
arrayList.Add(genericList);
counter++;
}
Console.Read();
}
}
} ```
I added this and it worked, thanks!
int counter2 = 0;
foreach (List<tempClass> temp in arrayList)
{
foreach (tempClass temp2 in temp)
Console.WriteLine("Name: " + temp2.Name + " Number: " + temp2.Number);
}
The below will give you a single dimensional list you can use foreach to print out each item.
List<tempClass> tests = arrayList.ToArray()
.Select(obj => (List<tempClass>)obj)
.Aggregate((first, second) => { second.AddRange(first.ToArray()); return second; });
foreach(tempClass test in tests)
{
Console.WriteLine(test.Name);
}

Randomly pick from a list of numbers until specific limit

Let's say I have a list of predefined numbers, and a list of predefined max limits.
When a user picks a limit, I need to randomly pick a certain amount of numbers from the first list, up until their totals match (As close to, but never over) the user selected total.
What I've tried so far:
void Main()
{
List<int> num = new List<int>(){ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,17, 18, 19, 20 };
int maxNum = 17;
List<int> curNum = new List<int>();
int curTotal = 0;
foreach(int sel in num.Where(x => x < maxNum)){
curTotal += sel;
if(curTotal <= maxNum){
curNum.Add(sel);
}
}
}
There needs to be x amount of numbers picked. In this case, 5 numbers picked, +- 20 numbers to be randomly picked from, and 1 max values.
So the end list should look like this:
1, 2, 3, 4, 7 (17)
1, 2, 3, 5, 6 (17)
1, 2, 3, 4, 6 (16) <- This will be fine if there isn't a solution to the max value.
Building upon #AlexiLevenkov's answer:
class Program
{
static void Main(string[] args)
{
int limit = 17;
int listSize = 5;
List<int> a = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
a.Shuffle();
List<int> genList = new List<int>();
int stoppedCount = 0;
for (int i = 0; i < a.Count(); i++)
{
if (i < listSize)
{
genList.Add(a[i]);
stoppedCount = i;
}
else
{
break;
}
}
while (genList.Sum() > limit)
{
genList.Remove(genList.Max());
stoppedCount++;
genList.Add(a[stoppedCount]);
}
}
}
static class ThisClass
{
public static void Shuffle<T>(this IList<T> list)
{
Random rng = new Random();
int n = list.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
I think shuffle + "take while sum < limit" may be what you are looking for.
Something like following:
var shuffledList = num.ToList();
shuffledList.Shuffle();
var sum = 0;
var count = 0;
while (shuffledList[count] + sum < max)
{
sum += shuffledList[count++];
}
return shuffledList.Take(count);

Splitting a list of items evenly between x number of smaller lists

I'm asking this question again, since the last time I asked it, it was falsely marked as duplicated. I am going to include some more information this time, that might make it easier to understand my need (it may very well have been my own fault for not defining the question properly).
I'm trying to split a list of a generic type into 4 lists. For simplicity and understanding, I will use a list of integers in this example, but that shouldn't make a difference.
I have done a lot of searching, found multiple answers like "Split List into Sublists with LINQ", using batch methods to split, I have tried MoreLinq's Batch methods and so on. Those suggestions work fine for what they should, but they do not work the way I need them to.
If I have a list containing the following elements (integers ranging 1-25):
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
Then what I need to do is make 4 lists with a variable number of elements in them, where the elements increment in the same list, instead of jumping to the next list with the next element.
[ 1, 2, 3, 4, 5, 6, 7]
[ 8, 9, 10, 11, 12, 13, 14]
[15, 16, 17, 18, 19, 20, 21]
[20, 21, 22, 23, 24, 25]
When using the solutions in either of the questions linked, with 4 "parts" as the parameter, I get lists like this (this is the example where the element jumps to the next list instead of just the next element of the list):
[1, 5, 9, 13, 17, 21, 25],
[2, 6, 10, 14, 18, 22, 26],
[3, 7, 11, 15, 19, 23, 27],
[4, 8, 12, 16, 20, 24]
or this (does the same as MoreLinq's Batch method)
[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20],
[21, 22, 23, 24],
[25, 26, 27],
So the first solution splits the list into 4 lists, but puts the elements in the wrong order. The second solution splits the lists in the right order, but not in the right length. In the last solution, he gets X amount of lists with 4 elements in each, where I need to have 4 lists with X elements in each.
You can use following extension method to split list on required number of sub-lists, and include additional items in first sub-list:
public static IEnumerable<List<T>> Split<T>(this List<T> source, int count)
{
int rangeSize = source.Count / count;
int firstRangeSize = rangeSize + source.Count % count;
int index = 0;
yield return source.GetRange(index, firstRangeSize);
index += firstRangeSize;
while (index < source.Count)
{
yield return source.GetRange(index, rangeSize);
index += rangeSize;
}
}
With given input
var list = Enumerable.Range(1, 25).ToList();
var result = list.Split(4);
Result is
[
[ 1, 2, 3, 4, 5, 6, 7 ],
[ 8, 9, 10, 11, 12, 13 ],
[ 14, 15, 16, 17, 18, 19 ],
[ 20, 21, 22, 23, 24, 25 ]
]
UPDATE: This solution adds additional item to each range
public static IEnumerable<List<T>> Split<T>(this List<T> source, int count)
{
int rangeSize = source.Count / count;
int additionalItems = source.Count % count;
int index = 0;
while (index < source.Count)
{
int currentRangeSize = rangeSize + ((additionalItems > 0) ? 1 : 0);
yield return source.GetRange(index, currentRangeSize);
index += currentRangeSize;
additionalItems--;
}
}
Here is another solution based on IEnumerable<T>. It has the following characteristics:
Always yields batchCount items, if the source enumerable is smaller than the batch size, it will yield empty lists.
Favors larger lists at the front (e.g. when the batchCount is 2 and the size is 3, the length of the results will be [2,1].
Iterates multiple times of the IEnumerable. This means AsEnumerable should be called somewhere if something like an Entity Framework query is executed here.
The first example is optimized for List<T>
public static class BatchOperations
{
public static IEnumerable<List<T>> Batch<T>(this List<T> items, int batchCount)
{
int totalSize = items.Count;
int remain = totalSize % batchCount;
int skip = 0;
for (int i = 0; i < batchCount; i++)
{
int size = totalSize / batchCount + (i <= remain ? 1 : 0);
if (skip + size > items.Count) yield return new List<T>(0);
else yield return items.GetRange(skip, size);
skip += size;
}
}
public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> items, int batchCount)
{
int totalSize = items.Count();
int remain = totalSize%batchCount;
int skip = 0;
for (int i = 0; i < batchCount; i++)
{
int size = totalSize/batchCount + (i <= remain ? 1 : 0);
yield return items.Skip(skip).Take(size);
skip += size;
}
}
}
Sergey's answer is clearly the best for this, but for completeness here's a solution you could use if you did not want to make copies of the sublists for some reason (perhaps because you just had IEnumerable<T> as input):
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
public static class EnumerableExt
{
public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> input, int blockCount, int count)
{
int blockSize = count/blockCount;
int currentBlockSize = blockSize + count%blockSize;
var enumerator = input.GetEnumerator();
while (enumerator.MoveNext())
{
yield return nextPartition(enumerator, currentBlockSize);
currentBlockSize = blockSize;
}
}
private static IEnumerable<T> nextPartition<T>(IEnumerator<T> enumerator, int blockSize)
{
do
{
yield return enumerator.Current;
}
while (--blockSize > 0 && enumerator.MoveNext());
}
}
class Program
{
private void run()
{
var list = Enumerable.Range(1, 25).ToList();
var sublists = list.Partition(4, list.Count);
foreach (var sublist in sublists)
Console.WriteLine(string.Join(" ", sublist.Select(element => element.ToString())));
}
static void Main()
{
new Program().run();
}
}
}
I guess this would run much more slowly than using Lists, but it would use much less memory.
const int groupSize = 4;
var items = new []{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25};
var currentGroupIndex=-1;
var step1 = items.Select(a =>{
if (++currentGroupIndex >= groupSize)
currentGroupIndex = 0;
return new {Group = currentGroupIndex, Value = a};
}).ToArray();
var step2 = step1.GroupBy(a => a.Group).Select(a => a.ToArray()).ToArray();
var group1 = step2[0].Select(a => a.Value).ToArray();
var group2 = step2[1].Select(a => a.Value).ToArray();
var group3 = step2[2].Select(a => a.Value).ToArray();
var group4 = step2[3].Select(a => a.Value).ToArray();
What this does is it first introduces an counter (currentGroupIndex) which starts at zero and will be incremented for each element in the list. The index gets reset to zero when the group size has reached.
the variable step1 now contains items continaing a Group and a Value property.
The Group value is then used in the GroupBy statement.
Take & Skip could be very helpful here i think but personally i like using Func to make these choices, makes the method more flexible.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Splitter
{
class Program
{
static void Main(string[] args)
{
List<int> numbers = Enumerable.Range(1, 25).ToList();
int groupCount = 4;
var lists = numbers.Groupem(groupCount, (e, i) =>
{
// In what group do i wanna have this element.
int divider = numbers.Count / groupCount;
int overflow = numbers.Count % divider;
int index = (i - overflow) / divider;
return index < 0 ? 0 : index;
});
Console.WriteLine("numbers: {0}", numbers.ShowContent());
Console.WriteLine("Parts");
foreach (IEnumerable<int> list in lists)
{
Console.WriteLine("{0}", list.ShowContent());
}
}
}
public static class EnumerableExtensions
{
private static List<T>[] CreateGroups<T>(int size)
{
List<T>[] groups = new List<T>[size];
for (int i = 0; i < groups.Length; i++)
{
groups[i] = new List<T>();
}
return groups;
}
public static void Each<T>(this IEnumerable<T> source, Action<T, int> action)
{
var i = 0;
foreach (var e in source) action(e, i++);
}
public static IEnumerable<IEnumerable<T>> Groupem<T>(this IEnumerable<T> source, int groupCount, Func<T, int, int> groupPicker, bool failOnOutOfBounds = true)
{
if (groupCount <= 0) throw new ArgumentOutOfRangeException("groupCount", "groupCount must be a integer greater than zero.");
List<T>[] groups = CreateGroups<T>(groupCount);
source.Each((element, index) =>
{
int groupIndex = groupPicker(element, index);
if (groupIndex < 0 || groupIndex >= groups.Length)
{
// When allowing some elements to fall out, set failOnOutOfBounds to false
if (failOnOutOfBounds)
{
throw new Exception("Some better exception than this");
}
}
else
{
groups[groupIndex].Add(element);
}
});
return groups;
}
public static string ShowContent<T>(this IEnumerable<T> list)
{
return "[" + string.Join(", ", list) + "]";
}
}
}
How about this, includes parameter checking, works with an emtpy set.
Completes in two passes, should be fast, I haven't tested.
public static IList<Ilist<T>> Segment<T>(
this IEnumerable<T> source,
int segments)
{
if (segments < 1)
{
throw new ArgumentOutOfRangeException("segments");
}
var list = source.ToList();
var result = new IList<T>[segments];
// In case the source is empty.
if (!list.Any())
{
for (var i = 0; i < segments; i++)
{
result[i] = new T[0];
}
return result;
}
int remainder;
var segmentSize = Math.DivRem(list.Count, segments, out remainder);
var postion = 0;
var segment = 0;
while (segment < segments)
{
var count = segmentSize;
if (remainder > 0)
{
remainder--;
count++;
}
result[segment] = list.GetRange(position, count);
segment++;
position += count;
}
return result;
}
Here is an optimized and lightweight O(N) extension method solution
public static void Bifurcate<T>(this IEnumerable<T> _list, int amountOfListsOutputted, IList<IList<T>> outLists)
{
var list = _list;
var index = 0;
outLists = new List<IList<T>>(amountOfListsOutputted);
for (int i = 0; i < amountOfListsOutputted; i++)
{
outLists.Add(new List<T>());
}
foreach (var item in list)
{
outLists[index % amountOfListsOutputted].Add(item);
++index;
}
}
Simply use it like this:
public static void Main()
{
var list = new List<int>(1000);
//Split into 2
list.Bifurcate(2, out var twoLists);
var splitOne = twoLists[0];
var splitTwo = twoLists[1];
// splitOne.Count == 500
// splitTwo.Count == 500
//Split into 3
list.Bifurcate(3, out var threeLists);
var _splitOne = twoLists[0];
var _splitTwo = twoLists[1];
var _splitThree = twoLists[2];
// _splitOne.Count == 334
// _splitTwo.Count = 333
// _splitThree.Count == 333
}

Find the first two digits which their sum is equal to 10

I have an array of integers intx[]:
int[] intx = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
I need to find the first two digits which their sum is equal to 10.
Here's the code:
Output should like (4 and 6).
Output should like (3 and 7).
Output should like (2 and 8).
Output should like (1 and 9).
public string Test()
{
int[] intx = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int i, j = intx.Length-1;
string s = "";
for (i = 0; i < 4; i++)
{
if ((intx[i] + intx[j - 1]) == 10)
{
s = (intx[i].ToString() + " and " + intx[j - 1].ToString());
}
j--;
}
return s;
}
You could use LINQ:
int[] intx = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var twoDigitsSumEquals10 = intx
.SelectMany((i1, index) =>
intx.Skip(index + 1)
.Select(i2 => Tuple.Create(i1, i2)))
.Where(t => t.Item1 + t.Item2 == 10);
SelectMany builds a cartesian product between all ints in the array and all ints in the array with a greater index than the first(to prevent repetition).
Test:
foreach (var x in twoDigitsSumEquals10)
Console.WriteLine(string.Join(",", x));
Output:
(1, 9)
(2, 8)
(3, 7)
(4, 6)
or only the first with "and" between like (1 and 9):
var firstCombi = twoDigitsSumEquals10.First();
Console.Write("({0} and {1})", firstCombi.Item1, firstCombi.Item2);
Update: here's the same without LINQ:
List<Tuple<int, int>> pairs = new List<Tuple<int, int>>();
for (int i = 0; i < intx.Length - 1; i++)
{
for (int ii = i + 1; ii < intx.Length; ii++)
{
if(i + ii == 10)
pairs.Add(Tuple.Create(i, ii));
}
}
You don't do anything with s you just re assign it. Try adding the results to a list and return the list
public List<string> Test()
{
int[] intx = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int j = intx.Length-1;
List<string> result = new List<string>();
for (int i = 0; i < 4; i++)
{
if ((intx[i] + intx[j - 1]) == 10)
{
result.Add(intx[i].ToString() + " and " + intx[j--].ToString());
}
}
return result;
}
foreach(string s in Test())
Console.WriteLine(s);
To just return the first, then exit the loop early
public string Test()
{
int[] intx = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int j = intx.Length-1;
for (int i = 0; i < 4; i++)
{
if ((intx[i] + intx[j - 1]) == 10)
{
return (intx[i].ToString() + " and " + intx[j--].ToString());
}
}
return "";
}

Categories

Resources