Two Sum Problem with HashSet not working with duplicates - c#

I am working on an assignment where I have to find pairs of numbers summing up to "x" with average/best O(n) or linear runtime complexity. I can not use brute force as it will increase the complexity.
I am using HashSet and using contains method I am checking If I can find (x - array[i]) and printing it. But contains method checks for the whole HashSet where I want to start that search after "i"th position at each iteration. Also, I can not sort them as I have to print them in an order they appear in the input array.
if (hSet.Contains(x - array[i]))
{
Console.Write("(" + array[i] + "," + (x - array[i]) + ")");
hSet.Add(array[i]);
}
}
With Input array { 1, 6, 3, 2, 5, 5, 7, 8, 4, 8, 2, 5, 9, 9, 1 };
My Output (1,9)(6,4)(3,7)(2,8)(5,5)(5,5)(7,3)(8,2)(4,6)(8,2)(2,8)(5,5)(9,1)(9,1)
Expected output: (1,9), (1,9), (6,4), (3,7), (2,8), (2,8), (5,5), (5,5), (5,5), (8,2), (8,2), (9,1), (9,1)

This code work as your expectation with O(n) complexity (in most of case). Using a Dictionary, not a HashSet.
First, build the dictionary from array with the key is the item, the value is the count of the item.
After that, iterate over items, check it with the dictionary and produce the output. Also reduce the count of this item in the Dictionary to avoid unnecessary output later.
Here is the code:
using System;
using System.Collections.Generic;
class MainClass {
public static void Main (string[] args) {
int[] array = { 1, 6, 3, 2, 5, 5, 7, 8, 4, 8, 2, 5, 9, 9, 1 };
int x = 10;
// build dictionary
Dictionary<int,int> dict = new Dictionary<int,int>();
for(int i=0; i< array.Length; i+=1){
if(dict.ContainsKey(array[i])){
dict[array[i]] += 1;
} else {
dict.Add(array[i], 1);
}
}
// using dictionary
for(int i=0; i< array.Length; i+=1){
if(dict.ContainsKey(x - array[i])) {
int count = dict[x - array[i]];
if(x - array[i] == array[i]){
count -= 1;
}
for(int j = 0; j< count; j+=1 ) {
Console.Write("(" + array[i] + "," + (x - array[i]) + ")");
}
dict[array[i]] -=1;
if(dict[array[i]] == 0){
dict.Remove(array[i]);
}
}
}
Console.WriteLine();
}
}

Here is my easy solution using Dictionary. O(n) time.
namespace TwoSumLeetCode
{
class Program
{
static void Main(string[] args)
{
int[] arr = { 1, 2, 7, 9, 4 };
int target = 13;
Console.WriteLine(TwoSum(arr, target));
Console.ReadLine();
}
// assuming array and target are provided.
public static int[] TwoSum(int[] nums, int target)
{
Dictionary<int, int> dict = new Dictionary<int, int>();
for (int i = 0; i < nums.Length(); ++i)
{
if (dict.ContainsKey(target - nums[i]))
{
return new int[] { dict[target - nums[i]], i };
}
else
{
dict[nums[i]] = i;
}
}
return null;
}
}
}

Related

C# How to print combinations that add upto given number?

I am trying to implement "Count of different ways to express N as the sum of other numbers" problem with C# using dynamic progamming.
My method looks like:
static int howManyWays(int n)
{
int [] safe= new int[n + 1];
// base cases
safe[0] = safe[1] = safe[2] = 1;
safe[3] = 2;
// iterate for all values from 4 to n
for (int i = 4; i <= n; i++)
safe[i] = safe[i - 1] + safe[i - 3]
+ safe[i - 4];
return safe[n];
}
For example, if i select n as n = 4, then my results are:
4
I want to print out those 4 combinations of sums:
1+1+1+1
1+3
3+1
4
Is there any way to do that either recursively or using dynamic programming?
My try is to get set of combinations recursively :
static int[] Combs(int n)
{
int[] tusc = { };
if (n < 0)
yield break;
if (n == 0)
yield return tusc;
int[] X = { 1, 3, 4 };
for(int i = 0; i < X.Length; i++)
{
for(j = 0; j <= Combs(n-X[i]).Length; j++)
{
yield return X + j;
}
}
}
Original code that works in python, but don't know how to translate into C#:
def combis(n):
if n < 0:
return
if n == 0:
yield []
for x in (1, 3, 4):
for combi in combis(n-x):
yield [x] + combi
>>> list(combis(5))
[[1, 1, 1, 1, 1], [1, 1, 3], [1, 3, 1], [1, 4], [3, 1, 1], [4, 1]]
Here's a pretty direct translation:
using System;
using System.Collections.Generic;
class MainClass
{
static IEnumerable<List<int>> Combs(int n)
{
if (n < 0)
{
yield break;
}
else if (n == 0)
{
yield return new List<int>();
}
foreach (int x in new List<int>() {1, 3, 4})
{
foreach (IEnumerable<int> combi in Combs(n - x))
{
var result = new List<int>() {x};
result.AddRange(combi);
yield return result;
}
}
}
public static void Main(string[] args)
{
foreach (IEnumerable<int> nums in Combs(5))
{
foreach (var i in nums)
{
Console.Write(i + ", ");
}
Console.WriteLine();
}
}
}
Output:
1, 1, 1, 1, 1,
1, 1, 3,
1, 3, 1,
1, 4,
3, 1, 1,
4, 1,
Remarks:
Since you're using yield, change the Combs header to return an IEnumerable<int> rather than int[].
Use lists rather than fixed-length arrays and List.AddRange to translate the + list concatenation operation from Python.
There is some confusion about translating X. In the Python version, x is just a single element in the {1, 3, 4} options list but in the C# version, it's the whole array.
Combs(n-X[i]).Length doesn't make sense--it calls Combs, takes the length of the results and then throws all of the results away, so it's like a really expensive counter. j gives you a counter index, not one of the elements from the child Combs call as intended. foreach is the most accurate translation of Python's for .. in loops.
The {1, 3, 4} list should probably be made into a parameter to allow the caller to control its behavior.
Efficiency is poor because overlapping subproblems are recomputed. Improving it is left as an exercise (this was probably your next step anyway).

Split the array into two to find the best solution in getting equal or nearly equal sum of integers

I need to solve a problem in which I need to split arrays into two sub-arrays such that the sum of their weights will be equal or "nearly equal".
Explanation
If I have an array [1,2,3,4,5] so I can possibly make two subsets of [1,2,4] = 7 and [3,5] = 8 OR [2,5] = 7 and [1,3,4] = 8.
I have done that part but by dry run i got to know that if i have even number of digits in the set of array then it always gives me wrong answers.
This program only works for odd number of digits. What am i missing?
using System.IO;
using System;
class Program
{
static void Main()
{
int[] a = {1,2,3,4};
int t;
Console.WriteLine("Original array :");
foreach (int aa in a)
Console.Write(aa + " ");
for (int p = 0; p <= a.Length - 2; p++)
{
for (int i = 0; i <= a.Length - 2; i++)
{
if (a[i] > a[i + 1])
{
t = a[i + 1];
a[i + 1] = a[i];
a[i] = t;
}
}
}
Console.WriteLine("\n" + "Sorted array :");
foreach (int aa in a)
Console.Write(aa + " ");
Console.Write("\n");
// int[] arr = new int[5] { 99, 95, 93, 89, 87 };
int z, max, min, n;
// size of the array
n = 4;
max = a[0];
min = a[0];
for (z = 1; z < n; z++)
{
if (a[z] > max)
{
max = a[z];
}
if (a[z] < min)
{
min = a[z];
}
}
Console.Write("Maximum element = {0}\n", max);
Console.Write("Minimum element = {0}\n\n", min);
int e = 0;
int f = 0;
int g = 0;
for(int i = 0; i < n; i++)
{
g = f - e;
int mm = max - min;
{
if(g > mm)
{
e += a[i];
}
else if(g < mm)
{
f += a[i];
}
}
min++;
}
Console.Write("The possible solution is:\n ");
Console.Write("First array = {0}\n", e);
Console.Write("Second array = {0}\n\n", f);
Console.ReadLine();
}
}
Here's a code snippet that might help:
var arr = new[] { 1, 2, 3, 4 };
var lst1 = new List<int>();
var lst2 = new List<int>();
var div = Math.DivRem(arr.Sum(), 2, out _);
foreach (var i in arr.OrderByDescending(x => x))
{
if (lst1.Sum() + i <= div)
lst1.Add(i);
else
lst2.Add(i);
}
Console.WriteLine(string.Join(", ", lst1.OrderBy(x => x)));
Console.WriteLine(string.Join(", ", lst2.OrderBy(x => x)));
Some outputs of:
{ 1, 2, 3, 4 }
1, 4
2, 3
{ 1, 2, 3, 4, 5 }
2, 5
1, 3, 4
{ 1, 2, 3, 4, 5, 6 }
4, 6
1, 2, 3, 5
So we iterated through the source array (arr) in a descending order to add numbers into lst1 if the sum of it's contents still less than or equal to the quotient of dividing the sum of the main array by 2, otherwise we add them (the numbers) into lst2 where the sum of it's numbers is equal or nearly equal to the mentioned quotient.
As a result, you have two lists where the sum of their contents are equal or nearly equal.
Below code will split array into 2 with equal sum or least difference in sum.
Apologies for lengthy solution, but it works perfectly for all combinations of odd and even.
Explicit names of variables and functions will help you to understand the logic.
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main(string[] input)
{
int[] a = {1, 2, 9, 26, 3, 4, 12, 7, 5};
int t;
Console.WriteLine("Original array :" + string.Join(", ", a));
for (int p = 0; p <= a.Length - 2; p++)
{
for (int i = 0; i <= a.Length - 2; i++)
{
if (a[i] > a[i + 1])
{
t = a[i + 1];
a[i + 1] = a[i];
a[i] = t;
}
}
}
Console.WriteLine("\n\nSorted array :" + string.Join(", ", a));
// Newly added code starts
int[] sortedArray = a;
List<int> array1 = new List<int>();
List<int> array2 = new List<int>();
for (int index = sortedArray.Length-1 ; index >=0 ; index-- )
{
if (array1.Sum() < array2.Sum())
{
array1.Add(sortedArray[index]);
}
else if (array1.Sum() > array2.Sum())
{
array2.Add(sortedArray[index]);
}
else
{
array1.Add(sortedArray[index]);
}
}
BalanceArray(array1, array2);
array1.Sort();
array2.Sort();
Console.WriteLine("\n\nArray1 { " + string.Join(", ", array1) + " }\tSum => " + array1.Sum());
Console.WriteLine("\n\nArray2 { " + string.Join(", ", array2) + " }\tSum => " + array2.Sum());
}
private static void BalanceArray(List<int> array1, List<int> array2)
{
int sumOfArray1 = array1.Sum();
int sumOfArray2= array2.Sum();
int difference = (sumOfArray1 < sumOfArray2) ? sumOfArray2- sumOfArray1 : sumOfArray1 - sumOfArray2;
if ( sumOfArray1 < sumOfArray2 )
{
SwapNumber(array2, array1, difference);
}
else if ( sumOfArray1 > sumOfArray2 )
{
SwapNumber(array1, array2, difference);
}
}
private static void SwapNumber(List<int> biggerArray,List<int> smallerArray, int difference)
{
//Console.Write("\n Difference :" + difference);
int expectedDifference = difference /2;
//Console.Write("\n Expected Difference :" + expectedDifference );
int lowerNoToSwap = 0;
int higherNoToSwap = 0;
for(int i=0; i < biggerArray.Count(); i++ )
{
if(biggerArray[i] <= expectedDifference)
{
lowerNoToSwap = biggerArray[i];
}
else if(biggerArray[i] > expectedDifference)
{
higherNoToSwap = biggerArray[i];
break;
}
}
if(lowerNoToSwap <= higherNoToSwap)
{
bool swapLower = (expectedDifference - lowerNoToSwap) < (higherNoToSwap - expectedDifference) ? true : false;
int numberToSwap = swapLower ? lowerNoToSwap : higherNoToSwap;
if(numberToSwap != 0)
{
smallerArray.Add(numberToSwap);
smallerArray.Sort();
biggerArray.Remove(numberToSwap);
}
}
}
}
Example 1
Original array :1, 2, 3, 4
Sorted array :1, 2, 3, 4
before Array1 { 4, 1 } Sum => 5
before Array2 { 3, 2 } Sum => 5
Array1 { 1, 4 } Sum => 5
Array2 { 2, 3 } Sum => 5
Example 2
Original array :1, 2, 3, 4, 5
Sorted array :1, 2, 3, 4, 5
Array1 { 3, 5 } Sum => 8
Array2 { 1, 2, 4 } Sum => 7
Example 3
Original array :1, 2, 9, 26, 3, 4, 12, 7, 5
Sorted array :1, 2, 3, 4, 5, 7, 9, 12, 26
Array1 { 1, 3, 5, 26 } Sum => 35
Array2 { 2, 4, 7, 9, 12 } Sum => 34

How to find the longest sequence of equal elements in an array of integers?

I want to write a program that finds the longest sequence of equal elements in an array of integers. If several longest sequences exist, we should print the leftmost one. e.g. Input: 0 1 1 5 2 2 6 3 3
Output: 1 1
I know that my code doesn't work correctly, but I don't know how to fix it. I should solve the problem using only arrays because I don't know how to use lists.
int[] numbers = Console.ReadLine().Split().Select(int.Parse).ToArray();
for (int i = 0; i < numbers.Length; i++)
{
int[] currentSequenceOfEqualElements = new int[numbers.Length];
for (int j = i + 1; j < numbers.Length; j++)
{
if (numbers[i] == numbers[j])
{
if (currentSequenceOfEqualElements[0] == 0)
{
currentSequenceOfEqualElements[0] = numbers[i];
currentSequenceOfEqualElements[1] = numbers[i];
}
else
{
currentSequenceOfEqualElements[i + 2] = numbers[i];
}
}
else
{
break;
}
}
Console.WriteLine(string.Join(' ', currentSequenceOfEqualElements));
}
I will be very grateful if you can explain to me how to do it.
Here is the solution using the MoreLinq library (https://morelinq.github.io/) that mjwills suggested.
Once you get used to linq and morelinq methods the code is easier to understand than custom algo with nested loops and if.
var numbers = new int[]{ 0, 1, 1, 5, 2, 2, 6, 3, 3};
var result = numbers.GroupAdjacent(x => x)
.MaxBy(x => x.Count())
.FirstOrDefault();
foreach (var i in result)
{
Console.Write($"{i} ");
}
Here's a simple solution, using only loops and no linq. It should be nice and easy to understand.
int[] numbers = new[] { 0, 1, 1, 5, 2, 2, 6, 3, 3 };
// Some variables to keep track of the sequence we're currently looking
// at, and the longest sequence we've found so far. We're going to start
// the loop at the 2nd number, so we'll initialize these as if we've
// already processed the first number (which is 0, so we've seen the
// first number of a sequence of 0's).
// Number of numbers in the current sequence
int count = 1;
// Number which is part of the longest sequence so faar
int longestNum = numbers[0];
// Number of numbers in the longest sequence we've seen so far
int longestCount = 1;
for (int i = 1; i < numbers.Length; i++)
{
// We're starting a new sequence
if (numbers[i] != numbers[i-1])
{
count = 0;
}
count++;
// Have we just found a new longest sequence?
if (count > longestCount)
{
longestCount = count;
longestNum = numbers[i];
}
}
// longestNum = 1 and longestCount = 2 (because the longest sequence
// had 2 1's in it). Turn this into the string "1 1".
Console.WriteLine(
string.Join(" ", Enumerable.Repeat(longestNum, longestCount)));
// If you wanted to end up with an array containing [1, 1], then:
int[] result = new int[longestCount];
Array.Fill(result, longestNum);
I will illustrate a recursive answer for your question, below is the code, I kept some if-else statements that there is no need to have them, but at least the code shows the idea.
The code has a basic method that should be exposed as public and a private recursive method that does the heavy lifting. The longest sequence is the empty array(list)
var longSequenceEqualElem = new List<int>();
Later on the recursion, you pass all the elems of the array through all the recursion calls to keep querying the positions, the pos parameter indicates the position level of the recursion.
if (pos < elems.Length) //stop the recursion here, the position will fall out of the indexes of the array, just return what you have in sequence that should be the longest.
The following statement if (sequence.Contains(elems[pos])) means that you found the same number you were carrying on the sequence in the position pos, so you can add it to the sequence and call the recursion with the adjacent position(pos + 1)
If the element in position pos is not part of the sequence you had, then you need to call the recursion with a new sequence containing elems[pos] and later compare the result of that recursion call with the sequence you had to see which of them is the longest one.
Hope this helps
class Program
{
static void Main(string[] args)
{
var elemts = new int[] { 0, 1, 1, 5, 2, 2, 6, 3, 3 };
var result = LongestSequence(elemts);
foreach (var i in result)
{
Console.Write(i + "\t");
}
Console.ReadLine();
}
public static int[] LongestSequence(int[] elems)
{
var longSequenceEqualElem = new List<int>();
return LongestSequenceRec(elems, longSequenceEqualElem, 0);
}
private static int[] LongestSequenceRec(int[] elems, List<int> sequence, int pos)
{
if (pos < elems.Length)
{
if (sequence.Contains(elems[pos]))
{
sequence.Add(elems[pos]);
return LongestSequenceRec(elems, sequence, pos + 1);
}
else
{
var newSeq = LongestSequenceRec(elems, new List<int> { elems[pos] }, pos + 1);
return (newSeq.Length > sequence.Count) ? newSeq.ToArray() : sequence.ToArray();
}
}
return sequence.ToArray();
}
}
static void Main()
{
int[] array1 = new int[9] {0, 1, 1, 5, 2, 2, 6, 3, 3};
int[] array2 = new int[9] {0, 0, 0, 0, 0, 0, 0, 0, 0};
int max_count = 1;
int tempCount = 1;
int num = 0;
for (int i = 0; i < array1.Length - 1; i++)
{
if (array1[i] == array1[i + 1]) tempCount++;
else tempCount = 1;
if (tempCount > max_count)
{
max_count = tempCount;
num = array1[i];
}
}
for (int i = 0; i < max_count; i++) array2[i] = num;
for (int i = 0; i < max_count; i++) Console.Write(array2[i] + " ");
Console.ReadKey();
}

C# For Loop and Array (practice exercise)

I'm trying to pick up C# and have been doing some practice programs. In this one, I try to transfer the integers in practiceArray to practiceArray2 but am unsuccessful, instead obtaining this as the output:
System.Int32[]
System.Int32[]
The code of my program is as follows:
static void Main(string[] args)
{
int[] practiceArray = new int[10] {2,4,6,8,10,12,14,16,18,20 };
int[] practiceArray2 = new int[practiceArray.Length];
for (int index = 0; index < practiceArray.Length; index++)
{
practiceArray2[index] = practiceArray[index];
}
Console.WriteLine(practiceArray);
Console.WriteLine(practiceArray2);
}
Console.WriteLine doesn't have any complicated logic for outputting complex objects, it just calls ToString() if it's not a string. You need to concatenate the values in the arrays manually, using string.Join etc.
For instance: Console.WriteLine(string.Join(", ", practiceArray));
int[] practiceArray = new int[10] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
int[] practiceArray2 = new int[practiceArray.Length];
for (int index = 0; index < practiceArray.Length; index++)
{
practiceArray2[index] = practiceArray[index];
}
foreach (int pArray in practiceArray)
Console.Write(pArray + " ");
foreach (int pArray2 in practiceArray2)
Console.Write(pArray2 + " ");
Console.Read();

How do I find duplicates in an array and display how many times they occurred?

I'm working on a code that prints out duplicated integers from an array with the number of their occurrence. I'm not allowed to use LINQ, just a simple code. I think I'm so close but confused about how to get a correct output:
class Program
{
static void Main(string[] args)
{
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
int count = 1;
for (int i = 0; i < array.Length; i++)
{
for (int j = i; j < array.Length - 1 ; j++)
{
if(array[j] == array[j+1])
count = count + 1;
}
Console.WriteLine("\t\n " + array[i] + "occurse" + count);
Console.ReadKey();
}
}
}
Since you can't use LINQ, you can do this with collections and loops instead:
static void Main(string[] args)
{
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
var dict = new Dictionary<int, int>();
foreach(var value in array)
{
// When the key is not found, "count" will be initialized to 0
dict.TryGetValue(value, out int count);
dict[value] = count + 1;
}
foreach(var pair in dict)
Console.WriteLine("Value {0} occurred {1} times.", pair.Key, pair.Value);
Console.ReadKey();
}
Use Group by:
int[] values = new []{1,2,3,4,5,4,4,3};
var groups = values.GroupBy(v => v);
foreach(var group in groups)
Console.WriteLine("Value {0} has {1} items", group.Key, group.Count());
Let's take a look at a simpler example. Let's say we have the array {0, 0, 0, 0}.
What will your code do?
It will first look to see how many items after the first item are equal to it. There are three items after the first that are equal to it.
Then it goes to the next item, and looks for all items after it that are equal to it. There are two. So far we're at 5, and we haven't even finished yet (we have one more to add), but there are only four items in the whole array.
Clearly we have an issue here. We need to ensure that when we've searched the array for duplicates of a given item that we don't search through it again for that same item. While there are ways of doing that, this fundamental approach is looking to be quite a lot of work.
Of course, there are different approaches entirely that we can take. Rather that going through each item and searching for others like it, we can loop through the array once, and add to a count of number of times we've found that character. The use of a Dictionary makes this easy:
var dictionary = new Dictionary<int, int>();
foreach (int n in array)
{
if (!dictionary.ContainsKey(n))
dictionary[n] = 0;
dictionary[n]++;
}
Now we can just loop through the dictionary and see which values were found more than once:
foreach(var pair in dictionary)
if(pair.Value > 1)
Console.WriteLine(pair.Key);
This makes the code clear to read, obviously correct, and (as a bonus) quite a lot more efficient than your code, as you can avoid looping through the collection multiple times.
Here is an answer that avoids using Dictionaries. Since the OP said he is not familiar with them, this might give him a little insight into what Dictionaries do.
The downside to this answer is you have to enforce a limit on the max number in the array, and you can't have negative numbers. You'd never actually use this version in real code.
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
int[] count = new int[13];
foreach(int number in array) {
// using the index of count same way you'd use a key in a dictionary
count[number]++;
}
foreach(int c in count) {
int numberCount = count[c];
if(numberCount > 0) {
Console.WriteLine(c + " occurs " + numberCount + " times");
}
}
int[] arr = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
var result = arr.GroupBy(x => x).Select(x => new { key = x.Key, val = x.Count() });
foreach (var item in result)
{
if(item.val > 1)
{
Console.WriteLine("Duplicate value : {0}", item.key);
Console.WriteLine("MaxCount : {0}", item.val);
}
}
Console.ReadLine();
Ok I have modified your code. This should do the job:
class Program
{
static void Main(string[] args)
{
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
for (int i = 0; i < array.Length; i++)
{
int count = 0;
for (int j = 0; j < array.Length; j++)
{
if (array[i] == array[j])
count = count + 1;
}
Console.WriteLine("\t\n " + array[i] + " occurs " + count + " times");
}
Console.ReadKey();
}
}
/This is the answer that helps you to find the duplicate integer values using Forloop and it will return only the repeated values apart from its times of occurences/
public static void Main(string[] args)
{
//Array list to store all the duplicate values
int[] ary = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
ArrayList dup = new ArrayList();
for (int i = 0; i < ary.Length; i++)
{
for (int j = i + 1; j < ary.Length; j++)
{
if (ary[i].Equals(ary[j]))
{
if (!dup.Contains(ary[i]))
{
dup.Add(ary[i]);
}
}
}
}
Console.WriteLine("The numbers which duplicates are");
DisplayArray(dup);
}
public static void DisplayArray(ArrayList ary)
{
//loop through all the elements
for (int i = 0; i < ary.Count; i++)
{
Console.Write(ary[i] + " ");
}
Console.WriteLine();
Console.ReadKey();
}
public static void FindRepeating(int[] input)
{
for (var i = 0; i < input.Length; i++)
{
var abs = Math.Abs(input[i]);
if (input[abs] >= 0)
input[abs] = -input[abs];
else
Console.Write(abs + " ");
}
}
You made a minor mistake of using J instead of i ...
class Program
{
static void Main(string[] args)
{
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
int count = 1;
for (int i = 0; i < array.Length; i++)
{
for (int j = i; j < array.Length - 1 ; j++)
{
if(array[i] == array[j+1])
count = count + 1;
}
Console.WriteLine("\t\n " + array[i] + "occurse" + count);
Console.ReadKey();
}
}
}
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 7, 7, 8, 9, 7, 12, 12 };
Dictionary<int, int> duplicateNumbers = new Dictionary<int, int>();
int count=1;
for (int i = 0; i < array.Length; i++)
{
count=1;
if(!duplicateNumbers.ContainsKey(array[i]))
{
for (int j = i; j < array.Length-1; j++)
{
if (array[i] == array[j+1])
{
count++;
}
}
if (count > 1)
{
duplicateNumbers.Add(array[i], count);
}
}
}
foreach (var num in duplicateNumbers)
{
Console.WriteLine("Duplicate numbers, NUMBER-{0}, OCCURRENCE- {1}",num.Key,num.Value);
}
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
/// <summary>
/// How do you find the duplicate number on a given integer array?
/// </summary>
class Program
{
static void Main(string[] args)
{
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
Dictionary<int, int> duplicates = FindDuplicate(array);
Display(duplicates);
Console.ReadLine();
}
private static Dictionary<T, int> FindDuplicate<T>(IEnumerable<T> source)
{
HashSet<T> set = new HashSet<T>();
Dictionary<T, int> duplicates = new Dictionary<T, int>();
foreach (var item in source)
{
if (!set.Add(item))
{
if (duplicates.ContainsKey(item))
{
duplicates[item]++;
}
else
{
duplicates.Add(item, 2);
}
}
}
return duplicates;
}
private static void Display(Dictionary<int, int> duplicates)
{
foreach (var item in duplicates)
{
Console.WriteLine($"{item.Key}:{item.Value}");
}
}
}
}
int[] arr = { 1, 2, 3, 2, 4, 5, 2, 4 };
var duplicates = arr.GroupBy(x => x)
.Where(g => g.Count() > 1)
.Select(y => new { Item = y.Key, Count = y.Count() })
.ToList();
Console.WriteLine(String.Join("\n", duplicates));
This approach, fixed up, will give the correct output (it's highly inefficient, but that's not a problem unless you're scaling up dramatically.)
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
for (int i = 0; i < array.Length; i++)
{
int count = 0;
for (int j = 0; j < array.Length ; j++)
{
if(array[i] == array[j])
count = count + 1;
}
Console.WriteLine("\t\n " + array[i] + " occurs " + count);
Console.ReadKey();
}
I counted 5 errors in the OP code, noted below.
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
int count = 1; // 1. have to put "count" in the inner loop so it gets reset
// 2. have to start count at 0
for (int i = 0; i < array.Length; i++)
{
for (int j = i; j < array.Length - 1 ; j++) // 3. have to cover the entire loop
// for (int j=0 ; j<array.Length ; j++)
{
if(array[j] == array[j+1]) // 4. compare outer to inner loop values
// if (array[i] == array[j])
count = count + 1;
}
Console.WriteLine("\t\n " + array[i] + "occurse" + count);
// 5. It's spelled "occurs" :)
Console.ReadKey();
}
Edit
For a better approach, use a Dictionary to keep track of the counts. This allows you to loop through the array just once, and doesn't print duplicate counts to the console.
var counts = new Dictionary<int, int>();
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
for (int i = 0; i < array.Length; i++)
{
int currentVal = array[i];
if (counts.ContainsKey(currentVal))
counts[currentVal]++;
else
counts[currentVal] = 1;
}
foreach (var kvp in counts)
Console.WriteLine("\t\n " + kvp.Key + " occurs " + kvp.Value);
class Program
{
static void Main(string[] args)
{
int[] arr = { 2, 3, 2, 4, 5, 12, 2, 3, 3, 3, 12 };
List<int> nums = new List<int>();
List<int> count = new List<int>();
nums.Add(arr[0]);
count.Add(1);
for (int i = 1; i < arr.Length; i++)
{
if(nums.Contains(arr[i]))
{
count[nums.IndexOf(arr[i])] += 1;
}
else
{
nums.Add(arr[i]);
count.Add(1);
}
}
for(int x =0; x<nums.Count;x++)
{
Console.WriteLine("number:"+nums[x] +"Count :"+ count[x]);
}
Console.Read();
}
}

Categories