The question is there is and unsorted array and the maximum value should be smaller than the length. I have to find the duplicate record in the array. The condition is to use a loop only once. This is what i have achieved so far. I wanted to know if there was any other approach through which i can achieve this.
int[] Arr = { 9, 5, 6, 3, 8, 2, 5, 1, 7, 4 };
int[] Arr2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (int i = 0; i < Arr.Length; i++)
{
if (Arr2[Arr[i]] == 0)
{
Arr2[Arr[i]] = Arr[i];
}
else
{
Console.WriteLine("duclicate found");
}
}
Use any Set implementation, say HashSet<T>, e.g.
HashSet<int> hs = new HashSet<int>();
int[] Arr = { 9, 5, 6, 3, 8, 2, 5, 1, 7, 4 };
foreach (item in Arr)
if (hs.Contains(item)) {
Console.WriteLine("duplicate found");
// break; // <- uncomment this if you want one message only
}
else
hs.Add(item);
Edit: since hs.Add returns bool a shorter and more efficient code can be put:
HashSet<int> hs = new HashSet<int>();
int[] Arr = { 9, 5, 6, 3, 8, 2, 5, 1, 7, 4 };
foreach (item in Arr)
if (!hs.Add(item)) {
Console.WriteLine("duplicate found");
// break; // <- uncomment this if you want one message only
}
Since you have this condition :
The question is there is and unsorted array and the maximum value should be smaller than the length.
Also assuming only positive numbers, which in your example applies
This can be done using O(n) time and O(1) space without using any LINQ, Dictionary, Hashing etc.
int[] arr = { 9, 5, 6, 3, 8, 2, 5, 1, 7, 4 };
for (int i = 0; i < arr.Length; i++)
{
if (arr[Math.Abs(arr[i])] >= 0)
arr[Math.Abs(arr[i])] = -arr[Math.Abs(arr[i])];
else
Console.WriteLine("Duplicate found " + Math.Abs(arr[i]).ToString() + "\n");
}
This is the Element Distinctness Problem.
This problem cannot be solved strictly linearly without additional space.
The two common approaches to solve the problem are:
Using a HashSet - populate it while iterating and abort if you find a match - O(n) time on average and O(n) space
Sort and iterate, after the array is sorted, duplicates will be adjacent to each other and easy to detect. This is O(nlogn) time and very little extra space.
The fastest way to obtain all duplicates, using LINQ, is this:
var duplicates = Arr.GroupBy(s => s).SelectMany(d => d.Skip(1));
This will return an IEnumerable of all duplicate elements in Arr, and you can use the following check to contain if there were any duplicates:
if (duplicates.Any())
{
// We have a duplicate!
}
This will work if only array a[] contains numbers in range [0,n-1] {as in your question} and n is not very large to avoid integer range overflow .
for(i=0;i<n;i++)
{
if(a[a[i]%n]>=n)
**duplicate is a[i]** !
else
a[a[i]%n]+=n;
}
Time complexity : O(N)
Space complexity : O(1) !
try this code using LINQ
int[] listOfItems = new[] { 4, 2, 3, 1, 6, 4, 3 };
var duplicates = listOfItems
.GroupBy(i => i)
.Where(g => g.Count() > 1)
.Select(g => g.Key);
foreach (var d in duplicates)
Console.WriteLine("The duplicate is "+d);
Related
For example, I have n number of integer array elements in c#. Can we access the last 3 elements of the array and modify these elements for instance multiple each element by 4. Can we achieve this in a single statement instead of using foreach/for loop(can we use the regular expression)?
Before operation
arr[0] = 3
..
..
arr[n-3] = 1
arr[n-2] = 5
arr[n-1] = 6
After operation
arr[0] = 3
..
..
arr[n-3] = 4
arr[n-2] = 20
arr[n-1] = 24
You can do this:
var arr = new int[] {1, 2, 3, 4, 5};
var result = arr.TakeLast(3).Select(x => x * 4).ToArray();
p.s. this is done in .NET 6
With C# 8 (i.e. dotnet core 3) and later you can also use Ranges to write as a one-liner:
int[] a = { 3, 4, 5, 6, 7, 8, 9, 1, 5, 6 };
var result = a[..^3].Concat(a[^3..].Select(e => e * 4));
a[..^3] does return all elements except the last 3.
a[^3..] does return the last 3 elements, which are then multiplied by 4.
The two arrays are then concatenated.
If you want to use result as an array, add ToArray().
If you do not have a formula that applies to all of them you could use tuples:
int []x = new[] {10, 20, 30, 40, 50, 60};
var len =x.Length;
(x[len-3], x[len-2], x[len-1]) = (6, 7659, 854);
Of course, this only works if the array has at least 3 elements. If you have a formula and need to select a dynamic number of items for update, then #Jim de Vries' answer works best.
You can use arr.Length and sub by 3, 2, 1 Like:
int[] arr = new int[] { 1, 2, 3, 4, 5, 6 };
int arrLength = arr.Length;
Console.WriteLine("Before Operation: {0}", string.Join(", ", arr));
arr[arrLength - 3] *= 4;
arr[arrLength - 2] *= 4;
arr[arrLength - 1] *= 4;
Console.WriteLine("After operation: {0}", string.Join(", ", arr));
You can use LINQ for same. Below is the sample code.
int[] arr = new[] { 1, 3, 3, 3, 5 };
int elementsCount = 3;
int multiplier = 4;
var result = arr.Take(arr.Length - elementsCount).Concat(arr.Skip(arr.Length - elementsCount).Select(a => a * multiplier)).ToArray();
I have an array. I need to find biggest element of it. If element repeats in array once again, I need to output and it. What is the program to output all biggest elements, if they repeats?
I tried to create new array, but somehow it did not work.
For example
int[] array = { 15, 2, 16, 16, 7, 3, 16};
And expected output
16 16 16
int[] array = { 1, 2, 1, 16, 7, 3, 15 };
expected output
16
A more "old fashioned" approach would be to walk through the array and keep track of the largest item (and the number of times you encounter it) as you go:
var items = new[] {15, 2, 16, 16, 7, 3, 16};
var largest = int.MinValue;
var count = 0;
// Walk through each item in the array, and compare it to the largest one found
// If it equals the largest, then increment our count. If it's greater than
// the largest, then set largest equal to this item and set count equal to 1.
foreach (var item in items)
{
if (item == largest)
{
count++;
}
else if (item > largest)
{
largest = item;
count = 1;
}
}
// Output the largest item 'count' times
for (int i = 0; i < count; i++)
{
Console.Write(largest + " ");
}
I have an unsorted array of numbers. Most numbers in this array are consecutive (1, 2, 3, 4, 5,...) but sometimes there's a number in it that's higher than the rest.
int highestNumber = int.MinValue;
int secondHighestNumber = int.MinValue;
int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 1207, 7, 8, 9, 1803, 10, 11, , 9000, 9001 };
int counter = 0;
foreach (int number in arr) {
if (number > highestNumber) {
secondHighestNumber = highestNumber;
highestNumber = number;
}
else if (number > secondHighestNumber) secondHighestNumber = number;
}
When I run the code, it'll tell me 9001 is the highest number and 9000 the second highest. But I want to change it so that I get an array of all the numbers from 1 to 11, with all the consecutive numbers that only have a difference of one, and a second array with all the larger numbers: 1207, 1803, 9000 and 9001.
9000 and 9001 shouldn't be in the first array, because the difference between these numbers and the rest is too high. So the end result should look like this:
int[] arr1 = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
int[] arr2 = new int[] { 1207, 1803, 9000, 9001 };
Some background info on what the purpose of this is:
Cient creates articles and each article has an article number that is created by looking up what the highest article number is in the "articles" table so far (e.g. 20), then the number of the new article is that number + 1 (e.g. 21); So an increment per number. However the client wishes to be able to sometimes add articles and input the article number he desires for the article, so let's say for the last article he created he inputted 7000 as article number. If he he then creates another article after that, I have to continue with that list of incrementing numbers. So unless the client changes the value of the next article again, the next new article should have 22 as article number (and not 7001).
Any help would be greatly appreciated as I've been stuck on trying to figure this out for a while now.
I'm not sure if you are just wanting to get the next number you should use or you want the 2 sets. If you want the two sets, I would do this:
int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 1207, 7, 8, 9, 1803, 10, 11, , 9000, 9001 };
int counter = 0;
List<int> l1 = new List<int>();
List<int> l2 = new List<int>();
foreach (int number in arr) {
if(l1.Count==0 || l1[l1.Count-1] == (number -1))
l1.Add(number);
else
l2.Add(number);
}
int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 1207, 7, 8, 9, 1803, 10, 11, 9000, 9001 };
// Sort the array
Array.Sort(arr);
// Start at the beginning and check if the index matches the actual number.
// Computer begins at 0, so fix that
for (int index=0;index<arr.Length; index++)
{
if (arr[index] != index+1)
{
Console.WriteLine("Next ID is " +(index+1));
break;
}
}
This question already has answers here:
c# Array.FindAllIndexOf which FindAll IndexOf
(10 answers)
Closed 5 years ago.
For example, I have an array
arr[5] = {1, 5, 2, 3, 5}
and the highest number is obviously 5.
My question is how do I get both the indices of the highest number (which is 5).
The expected result is 1 and 4.
var arr = new int[] { 1, 5, 2, 3, 5 };
int max = arr.Max();
List<int> indexes = new List<int>();
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] == max)
indexes.Add(i);
}
int highindex = indexes.LastOrDefault();
Thats how you get all indexes of your highest number
var numbers = new int[] { 1, 5, 2, 3, 5 };
int max = numbers.Max();
var indexes = numbers.Select((c, i) => new
{
character = c, index = i
})
.Where(list => list.character == max)
.ToList();
You can use a LINQ query to find the numbers and index that equal the maximum number :
var arr=new[] {1, 5, 2, 3, 5};
var max = arr.Max();
var indexes= arr.Select( (n,idx)=>n==max?idx:-1)
.Where(idx=>idx!=-1)
.ToArray();
This will return {1,4}.
This query uses the Enumerable.Select overload that provides the index of the current element and returns that index if the number is equal to the maximum.
The original title was a bit confusing - how to find the two largest values. You can use a similar query to get the N largest values by selecting the value and index, ordering the results and taking first N items:
var indexes = arr.Select( (val,idx)=> (val:val,idx:idx) )
.OrderByDescending(p=>p.val)
.Take(2)
.Select(p=>p.idx);
This query uses C# 7 tuples to hold the intermediate results and give them a name
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have two array objects
int[] arr1= new int[] {1,2,5,6,7,9,3,5,6,7}
int[] arr2 = new int[] {5,6,7}
Now, how to find the no of occurrences of arr2 in arr1?
Perhaps not very elegant, but it should work.
This selects all subarrays in a having the same length of b, and checks how many are equal to b.
int[] a = {1, 2, 3, 4, 5};
int[] b = {2, 3};
int count = 0;
int bl = b.Length;
for (int i = 0; i <= a.Length - bl; i++)
{
var suba = a.Skip(i).Take(bl);
if (suba.SequenceEqual(b))
count++;
}
N.B.: this solution considers overlapping subarrays, therefore if a = {2, 2, 2} and b = {2, 2}, the count will be 2.
you may use arr2.Intersect(arr1).Count()
So in your case it will return 3, as 3 elements in arr2 are present in arr1.
If this is not what you're asking for, please clarify.
Use the intersect. This code snippet will solve your problem and print all duplicates, and show the count of each in arr1. Note that I am also using the Linq Distinct(), so that when looping common occurrences, I only check once and not more.
int[] arr1= new int[] {1,2,5,6,7,9,3,5,6,7};
int[] arr2 = new int[] {5,6,7};
var listCommon = arr1.AsEnumerable().Where(arr2.AsEnumerable().Contains);
foreach (var x in listCommon.Distinct()) {
var numberOfOccurencesInArr1 = arr1.Where(y => y == x).Count();
Console.WriteLine(x + " is : " + numberOfOccurencesInArr1.ToString() + " times in arr1");
}
Console.ReadLine();
See MSDN for more information; http://msdn.microsoft.com/en-us/library/system.linq.enumerable.intersect(v=vs.110).aspx
The listCommon will be the number of common items in both arrays.
Try This
string result = string.Empty; ;
int[] arr1 = new int[] { 1, 2, 5, 6, 7, 9, 3, 5, 6, 7 };
int[] arr2 = new int[] { 5, 6, 7 };
int count = arr2.Intersect(arr1).Count();
if (count == arr2.Length)
{
result = "Found";
}
else
{
result = "Not Found";
}
If you want to count how many occurences of an integer of the second array are present in the first array then you could write
int[] arr1 = new int[] {1,2,5,6,7,9,3,5,6,7};
int[] arr2 = new int[] {5,6,7};
Dictionary<int, int> counter = new Dictionary<int, int>();
foreach(int x in arr1)
{
if(arr2.Contains(x))
{
if(counter.ContainsKey(x))
counter[x]++;
else
counter[x] = 1;
}
}
foreach(KeyValuePair<int, int> kvp in counter)
Console.WriteLine("Key=" + kvp.Key.ToString() + " is present " + kvp.Value.ToString() + " times");
int[] arr1 = new int[] { 1, 2, 5, 6, 7, 9, 3, 5, 6, 7 };
int[] arr2 = new int[] { 5, 6, 7 };
how to find the no of occurrences of arr2 in arr1?
If you are expecting the result to be 2. Since the 5,6,7 appears twice in the arr1
try this
var res = arr1.Where(x => arr2.Contains(x)).Count()/arr2.Count();
Try this one:
var results = (from a1 in arr1
join a2 in arr2
on a1 equals a2
group arr1 by a1 into Group
select new
{
Number = Group.Key,
Times = Group.Count()
});
foreach(var result in results)
Console.WriteLine(result.Number+" "+result.Times);
Please check this solution using the following fiddle .NET fiddle
You can use ToLookup on the ints in the first count which are also in the second array. Then you just have to take the min-count of all groups since that's the greatest intersection:
var subsetGroups = arr1.Where(i1 => arr2.Contains(i1)).ToLookup(i => i);
int minGroupCount = 0;
// check if all integers from the array are in the first at all
if(arr2.All(i => subsetGroups.Contains(i)))
{
minGroupCount = subsetGroups.Min(g => g.Count()); // 2
}
Note that this approach doesn't care about the order and it also doesn't care about the number of duplicates in the second array. This might be desired or not.
As you input is arrays you can use indexing to effectively count the number of occurrences of the subarrays in the main array:
var count = 0;
for (var i = 0; i < arr1.Length - arr2.Length + 1; i += 1) {
if (arr1[i] != arr2[0])
continue;
var isSubarray = true;
for (var j = 0; j < arr2.Length; ++j)
if (arr1[i + j] != arr2[j]) {
isSubarray = false;
break;
}
if (isSubarray)
count += 1;
}
The result will be 2 because 567 is found two times in 1256793567.
If the subarray can "overlap" itself (e.g. 11 in 111) all "overlaps" will be counted (e.g. the result will be 2 for this example). If that is not the intention you simply have to advance the index i at the end of the main loop to skip the found subarray.