I want to move all duplicate numbers at the end of array like this.
{4,1,5,4,3,1,6,5}
{4,1,5,3,6,4,1,5}
also i want to know number of dups. that i will use to resize array.
here is the code i tried but this code is not compatible when i insert more than 2 dups at starting.
static void RemoveRepeated(ref int[] array)
{
int count = 0; bool flag;
for (int i = 0; i < array.Length; i++)
{
flag = true;
for (int j = i+1; j < array.Length-1; j++)
{
if (array[i] == array[j] )
{
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
if (flag)
{
count++;
flag = false;
}
}
}
}
Array.Resize(ref array,array.Length-count);
}
Thanks in advance :)
A good solution will be to use a fitting data-structure. It will not fix your algorithm but replace it. Here a HashSet<T> is perfect. A HashSet<T> remove itself all duplicate. Check the msdn for more informations.
Demo on .NETFiddle
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var array = new int[]{ 4,1,5,4,3,1,6,5 };
RemoveRepeated(ref array);
foreach (var item in array)
Console.WriteLine(item);
}
static void RemoveRepeated(ref int[] array)
{
array = new HashSet<int>(array).ToArray();
}
}
By the way you don't really need ref here. I would remove it and change void RemoveRepeated(ref int[] array) to int[] RemoveRepeated(int[] array). See ref parameter or return value?
What you are doing is equivalent to leaving only the unique elements in their original order. Here is simpler way to do this:
static void RemoveRepeated(ref int[] array)
{
HashSet<int> seen = new HashSet<int>();
List<int> newArray = new List<int>(array.Length);
foreach(int x in array)
{
if(!seen.Contains(x))
{
seen.Add(x);
newArray.Add(x);
}
}
array = newArray.ToArray();
}
Don't use an array here. You can try to (just one example) group a List<int> and Count() all groups that have more than one element. When you have the count, you can use Distinct() to get only the distinct elements.
In my opinion, resizing an array like this is always a very bad idea.
Edit:
Well, like the other answers already stated, a HashSet is a even better way of doing it.
class Program
{
static void Main(string[] args)
{
int[] arr = new int[] { 4, 1, 5, 4, 3, 1, 6, 5 };
RemoveRepeated(ref arr);
foreach (int i in arr)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
private static void RemoveRepeated(ref int[] array)
{
int count =0;
for (int i = 0; i < array.Length; i++)
{
for (int j = i + 1; j < array.Length; j++)
{
if (array[i] == array[j])
{
int temp = array[j];
count++;
for (int k = j; k < array.Length-1; k++)
{
array[k] = array[k + 1];
}
array[array.Length - 1] = temp;
j = array.Length;
}
}
}
Array.Resize(ref array, array.Length - count);
}
}
Try this:
class Program
{
static void Main(string[] args)
{
int[] ints = {4,1,5,4,3,1,6,5};
var query = ints.GroupBy(x => x).OrderBy(x => x.Count()).Select(x => x);
// print ordered array showing dupes are last
query.ToList().ForEach(x => Console.WriteLine(x.Key.ToString()));
// Get number of dupes
int dupeCount = query.Where(x => x.Count() > 1).Count();
// put unique items into a new array
var newArray = query.Where(x => x.Count() == 1).Select(x => x.Key).ToArray();
// put distinct items into an array
var distinctArray = ints.Distinct().ToArray();
Console.ReadKey();
}
}
Edit: Added distinct elements
If you want to move the duplicates to the end of array (but preserve order) you can do this:
static void RemoveRepeated(ref int[] array)
{
var lookup = array.ToLookup(x => x);
var maxdupes = lookup.Select(x => x.Count()).Max();
var reordered =
Enumerable
.Range(0, maxdupes)
.SelectMany(x => lookup.SelectMany(y => y.Skip(x).Take(1)))
.ToArray();
Array.Copy(reordered, array, reordered.Length);
}
This would turn { 4, 1, 5, 4, 3, 1, 6, 5 } into { 4, 1, 5, 3, 6, 4, 1, 5 }
You can easily get the number of duplicates by doing this:
lookup
.Select(x => new
{
Value = x.Key,
Count = x.Count(),
});
This returns:
4 2
1 2
5 2
3 1
6 1
Related
I have an array of for example
int[] array = new int[] {1, 3, 2, 3};
and problem is with getting index of multiple max values from an array.
First get the max:
int max = array.Max();
Now get the indices of the elements that have that value:
var indices = array.Select((x, i) => new { Index = i, Value = x })
.Where(x => x.Value == max)
.Select(x => x.Index);
Here's how you can do that in one loop.
var indices = new List<int>();
int max = int.MinValue;
for(int i = 0; i < array.Length; i++)
{
if(array[i] > max)
{
max = array[i];
indices.Clear();
}
if(array[i] == max)
{
indices.Add(i);
}
}
Basically you keep track of the max and a list of indices. When you see a value greater than the max you set it to max and clear the list since any indices in there are no longer pointing at the max. Then just check if the value equals the max and add the index to the list if it does.
Linq approach
int[] array = new int[] { 1, 3, 2, 3 };
int[] result = array.Select((x, i) => new { index = i, value = x })
.GroupBy(x => x.value)
.OrderByDescending(x => x.Key)
.First()
.Select(x => x.index)
.ToArray();
With an extention method given that you already have the maxValue you are looking for:
public static IEnumerable<int> AllIndexesOf(this List<T> list, T searchValue)
{
int minIndex = list.IndexOf(searchValue);
while (minIndex != -1)
{
yield return minIndex;
minIndex = list.IndexOf(searchValue, minIndex + 1);
}
}
You can have :
int[] array = new int[] {1, 3, 2, 3};
int maxValue = array.Max();
int[] indexesOfMax = array.AllIndexesOf(maxValue).ToArray();
As a counter to #HimBromBeere's answer
We can use a dictionary for every unique number and then a list of integers for every index it showed up.
var intArray = new int[5];
var dictionary = new Dictionary<int, List<int>>();
for (int i = 0; i < intArray.Length; i++)
{
var num = intArray[i];
if (!dictionary.ContainsKey(num))
{
dictionary.Add(num, new List<int>());
}
dictionary[num].Add(i);
}
var max = dictionary.Keys.Max();
return dictionary[max];
This has less overall operations but is a bit more terse.
Using yield return and looping through the array you can do this:
using Linq;
using System.Collections.Generic;
public static class IEnumerableExtensions
{
// Extension method for IEnumerable
public static IEnumerable<int> AllIndexesOf<T>(this IEnumerable<T> list, T searchValue)
{
for (int i = 0; i < list.Count(); i++)
{
if (list.ElementAt(i) == searchValue)
{
yield return i;
}
}
}
}
Then find the max value in the array using LINQ and call the method:
using Linq; // include this at the top of your file, if not already present.
// ...
int[] array = new int[] {1, 3, 2, 3};
IEnumerable<int> matchingIndexes = array.AllIndexesOf(array.Max());
// Convert to array if you need one
int[] matchingIndexesArr = matchingIndexes.ToArray();
You can find more information about extension methods in the docs.
I want to pass an array to a function, reverse it without using the Array.Reverse() method and return the reversed array. I am actually trying to do it without using the temp variable in this case.
Below is my code snippet. Please correct me where I am getting it wrong.
class Program
{
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 4, 5 };
int[] reverse = new int[5];
reverse = ReverseArray(array, reverse);
foreach (int item in reverse)
{
Console.WriteLine(reverse);
}
}
public static int[] ReverseArray(int[] arr, int[] rev)
{
int x = arr.Length - 1;
for (int i = 0; i <= x; i++)
{
rev[i] = arr[x];
x--;
}
return rev;
}
}
I am actually trying to do it without using the temp variable in this case.
Let's ignore this bit first, and use a temp variable where it makes sense. We can come back to it.
There are a few different ways in which we can deal with the general problem of "reverse an array". We can reverse the array itself in-place, we can create a new array that is the reverse of the array we were given, or we can fill in another array we are given to be the reverse of the first array we were given. Your solution has a mixture of the three, and hence manages to do none of them properly.
To fill in a second array we are given we do not need a temp, as we aren't swapping, and we do not want to stop at a middle point:
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 4, 5 };
int[] reverse = new int[5];
ReverseArray(array, reverse);
foreach (int item in reverse)
{
Console.WriteLine(item);
}
}
public static void ReverseArray(int[] arr, int[] rev)
{
int x = arr.Length - 1;
for (int i = 0; i < arr.Length; i++, x--)
{
rev[i] = arr[x];
}
}
We've gone through every single element in arr and put it in the relevant position in rev.
To return a new array we do much the same thing, but creating the new array within the method itself:
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 4, 5 };
int[] reverse = ReverseArray(array);
foreach (int item in reverse)
{
Console.WriteLine(item);
}
}
public static int[] ReverseArray(int[] arr)
{
int[] rev = new int[arr.Length];
int x = arr.Length - 1;
for (int i = 0; i < arr.Length; i++, x--)
{
rev[i] = arr[x];
}
return rev;
}
A variant of this doesn't create a new array at all, but just iterates through it, producing an IEnumerable<int>. This is faster to return the first result and doesn't use as much memory with large arrays, but re-does the reversing every time it's used, so it varies in how useful it is accordingly:
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 4, 5 };
IEnumerable<int> reverse = ReverseArray(array);
foreach (int item in reverse)
{
Console.WriteLine(item);
}
}
public static IEnumerable<int> ReverseArray(int[] arr)
{
for (int i = arr.Length - 1; i >= 0; i--)
{
yield return arr[i];
}
}
To reverse an array in-place we want to work our way from the outside to the middle swapping elements:
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 4, 5 };
ReverseArray(array);
foreach (int item in array)
{
Console.WriteLine(item);
}
}
public static void ReverseArray(int[] arr)
{
int x = arr.Length - 1;
for (int i = 0; i < x; i++, x--)
{
int temp = arr[x];
arr[x] = arr[i];
arr[i] = temp;
}
}
This breaks your arbitrary no-temp-variable rule. We can get around this with a little trick of bit-twiddling, though there's no real value in doing that.
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 4, 5 };
ReverseArray(array);
foreach (int item in array)
{
Console.WriteLine(item);
}
}
public static void ReverseArray(int[] arr)
{
int x = arr.Length - 1;
for (int i = 0; i < x; i++, x--)
{
arr[x] ^= arr[i];
arr[i] ^= arr[x];
arr[x] ^= arr[i];
}
}
There's really no value in not using a 4-byte temporary variable though.
The x might not need to decrement, you can use arr.Length - 1 - i instead of x for array index otherwise, you will only revered half array.
public static int[] ReverseArray(int[] arr, int[] rev)
{
int x = arr.Length - 1;
for (int i = 0; i <= x; i++)
{
rev[i] = arr[arr.Length - 1 - i];
}
return rev;
}
and I would only pass one array be for method and you can declare the reverse array in the method.
public static int[] ReverseArray(int[] arr)
{
int[] reverse = new int[arr.Length];
int x = arr.Length - 1;
for (int i = 0; i <= x; i++)
{
reverse[i] = arr[arr.Length - 1 - i];
}
return reverse;
}
c# online
Result
5
4
3
2
1
I want to sort only odd numbers without moving even numbers. For example, if my input is:
[5, 3, 2, 8, 1, 4]
The expected result is:
[1, 3, 2, 8, 5, 4]
I am new to C# and I came across a challenge on the Internet that has me perplexed. I have tried for hours and I would like to learn this concept in
The challenge states:
You have an array of numbers. Your task is to sort ascending odd numbers but even numbers must be on their places. Zero isn't an odd number and you don't need to move it. If you have an empty array, you need to return it.
Here is my code so far, please take it easy on me I am in the beginning stages of programming.
public static int[] SortArray(int[] array)
{
var dict = new Dictionary<int, int>();
var dict2 = new Dictionary<int, int>();
for (int i = 0; i < array.Length; i++)
{
int j =0;
if (array[i] % 2 != 0)
{
dict.Add(array[i], i+1);
}
else
{
dict2.Add(array[i], i+1);
}
}
var result = dict.OrderBy(x => x.Key);
Dictionary<int, int> resultDic = result.Union(dict2)
.GroupBy(x => x.Key).ToDictionary(o => o.Key, o => o.Key);
}
public static void Main()
{
SortArray(new int[] { 5, 3, 2, 8, 1, 4});
}
Check this code. Explanations added as comments
public static int[] SortArray(int[] array)
{
//temp variable for holding larger value for switching
int temp = 0;
for (int i = 0; i < array.Length; i++)
{
//If the value is 'even' continue with outer loop
if(array[i] % 2 == 0)
continue;
//Inner loop to compare array values
for(int j = (i + 1); j < array.Length; j++)
{
//If this value is not even do comparison
if(array[j] % 2 != 0)
{
//If the left value is greater than the right value
//swap them
if(array[i] > array[j])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
return array;
}
public static void Main()
{
SortArray(new int[] { 5, 3, 2, 8, 1, 4});
}
You can do this with linq by indexing the numbers before you start:
var nums = new[] { 5, 3, 2, 8, 1, 4 };
var indexedNums = nums.Select((num, idx) => new { num, idx }).ToList();
Then sorting these indexed numbers into evens and odds:
var evens = indexedNums.Where(x => x.num % 2 == 0);
var odds = indexedNums.Where(x => x.num % 2 == 1);
Sorting the odd (indexed) numbers by their value:
var sortedOdds = odds.OrderBy(x => x.num); //sort the odd numbers by their value
Zipping this sequence with the odds sequence (which is sorted by index), taking the number from sortedOdds and the index from odds
var reindexedOdds = sortedOdds.Zip(odds, (o1, o2) => new { o1.num, o2.idx });
...and throwing these reindexedOdds into a sequence with the indexed evens from above, sorting by index and then selecting out the number.
var endSequence = evens.Concat(reindexedOdds).OrderBy(x => x.idx).Select(x => x.num);
While the other solutions are formally correct, most of them are not efficient, being with O(n^2) time complexity.
Another (and more time efficient) approach should imply the use of two lists: the first will contain the indexes of odd numbers, and the second will store the sorted odd numbers.
public static int[] SortArray(int[] array)
{
var sortedOdds = new List<int>(array.Length);
var oddsIndexes = new List<int>(array.Length);
var newArray = new int[array.Length];
for(var i = 0; i < array.Length; i++) // O(n)
{
var value = array[i];
if(value % 2 == 1)
{
sortedOdds.Add(value);
oddsIndexes.Add(i);
} else
{
newArray[i] = value;
}
}
sortedOdds.Sort(); // average complexity O(n log n)
for(var j = 0; j < sortedOdds.Count; j++) // O(n)
{
var value = sortedOdds[j];
var index = oddsIndexes[j];
newArray[index] = value;
}
return newArray;
}
This will reduce the complexity to an average of O(n log n) time.
This is a basic question ( I am new to C#), but is there an efficient way to move the first element to the end of the array in C#?
I found this question, which describes the .rotate method in ruby, but I have been unable to find a similar method in C#.
If I have an array:
[1, 2, 3, 4, 5]
Is there a function in C# that returns:
[2, 3, 4, 5, 1]
Thanks in advance!
EDIT: Answer
The best solution is to use LinkedList<T> as many of you suggested and as shown in Alex's answer. His suggested solution was using:
list.AddLast(list.RemoveFirst());
which can be run in a for loop:
void func<T>(LinkedList<T> list, int rotate) {
for(var i = 0; i < rotate; i++) {
list.AddLast(list.RemoveFirst());
}
}
Thank you all for your help!
There are many ways to achieve this. One way would be:
var result = arr.Skip(1).Concat(arr.Take(1))
If you use LinkedList<T> instead of array<T> you could just use this:
list.AddLast(list.RemoveAndGetFirst());
Edit: RemoveAndGetFirst() can be an extension like:
LinkedListNode<T> elem = list.First;
list.RemoveFirst();
return elem;
Complexity O(1). When you perform this multiple times:
void func<T>(LinkedList<T> list, int rotate) {
for(var i = 0; i < rotate; i++) {
list.AddLast(list.RemoveFirst());
}
}
You will have a complexity of O(N) [where N is the number of rotations]. This is, performance wise, the best solution.
If you really need to use arrays this could be a naiv solution:
var tmp = list[0];
for(var i = 1; i < list.Length; i++) {
list[i - 1] = list[i];
}
list[list.Length - 1] = tmp;
(Be aware there are no range checks)
But this will be very time consuming if you need to do this often. If you perform this multiple times:
void func<T>(T[] list, int rotate) {
for(var j = 0; j < rotate; j++) {
var tmp = list[0];
for(var i = 1; i < list.Length; i++) {
list[i - 1] = list[i];
}
list[list.Length - 1] = tmp;
}
}
You will end up with O(N^2) = O(N * M) [where N is the number of elements and M the number of rotations]. This would be really bad. A better approach, if you know in advance you'll perform this often would be:
void func<T>(T[] list, int rotate {
for(var j = 0; j < list.Length; j++) {
var tmp = list[j];
var ix = (rotate + j) % list.Length;
list[j] = list[ix];
list[ix] = tmp;
}
}
Which will result in O(N) [where N is the number of elements].
As others already suggested, it's a good idea to write an extension method if you need this at multiple locations.
Using Array.Copy to copy elements to itself just shifted ;)
var array = new int[]{1, 2, 3, 4, 5};
var head = array[0];
Array.Copy(array, 1, array, 0, array.Length- 1);
array[array.Length - 1] = head;
And as an extension method returning a new array just like the Ruby version
static class ArrayRotateExtensions {
public static int[] Rotate(this int[] arr, int offset) {
var l = arr.Length;
var rot = new int[l];
if (offset == 0) {
Array.Copy(arr, 0, rot, 0, l);
return rot;
}
// constrain rotations greater than array length, it's the same result anyway
offset = offset % l;
// negative rotation is equal to positive rotation length - offset
if (offset < 0) {
offset += l;
}
Array.Copy(arr, offset, rot, 0, l - offset);
Array.Copy(arr, 0, rot, l - offset, offset);
return rot;
}
}
This will allow you to do
var array = new int[]{1, 2, 3, 4, 5};
var rotated = array.Rotate(1);
Plus rotation by any arbitrary amount.
Only downside is you'd have to add a version for every array type you'd like to use it on.
It's starting to look like Code Golf now :-) so here's my contribution:
var x = new[] { 1, 2, 3, 4, 5 };
var y = Enumerable.Range(1, x.Length).Select(i => x[i % x.Length]).ToArray();
The reason why there is no function like that in LINQ is most likely that people who developed LINQ didn't think it's something that is an absolute must...
If you really need that you can create an extension method.
Something along the lines of:
public static IEnumerable<T> Rotate<T>(this IEnumerable<T> elements, int number)
{
var elemetsList = elements as IList<T> ?? elements.ToList();
var list = new List<T>(elemetsList.Count);
if (number > elemetsList.Count - 1)
{
throw new ArgumentException(nameof(number));
}
for (int i = number; i < elemetsList.Count; i++)
{
list.Add(elemetsList[i]);
}
for (int i = 0; i < number; i++)
{
list.Add(elemetsList[i]);
}
return list;
}
And use it:
var arr = new int[] {1, 2, 3, 4, 5};
int[] result = arr.Rotate(1).ToArray();
int[] result2 = arr.Rotate(3).ToArray();
Output:
2 3 4 5 1
4 5 1 2 3
This solution is fairly efficient.
For an array 500 000 in length it took only 7ms on my machine to execute.
Try this one..
using System;
public class Program
{
public static int[] arrData = new int[5]{1,2,3,4,5};
public static void Main()
{
Console.WriteLine("\nOriginal array\n");
foreach(var item in arrData)
{
Console.WriteLine(item.ToString());
}
Console.WriteLine("\nShift to last\n");
arrData = shiftLast(arrData);
foreach(var item in arrData)
{
Console.WriteLine(item.ToString());
}
}
public static int[] shiftLast(int[] arr)
{
int last = arr[arr.Length - 1];
int first= arr[0];
arr[arr.Length - 1] = first;
arr[0] = last;
return arr;
}
}
Try to run here
Cheers
Maybe like this -
static void Main( string[] args ) {
Console.WriteLine(string.Join(", ", getArray(new int[] { 1, 2, 3, 4, 5 })));
Console.Read();
return;
}
static int[] getArray( int[] arr ) {
List<int> O = new List<int>();
for (int x = 1, l = arr.Length; x < l; x++) {
O.Add(arr[x]);
}
O.Add(arr[0]);
return O.ToArray();
}
As far as I know there isn't such method for an array. If you do this often perhaps you should consider using a different object (List<T>, Stack<T>, etc).
But even with an array you can implement simple functionality like this using extension methods:
public static int[] MoveFirstToLast (this int[] obj)
{
int movedValue = obj[0];
(int i = 1; i < obj.Length; i++)
{
obj[i - 1] = obj[i];
}
obj[obj.Length - 1] = movedValue;
return obj;
}
And then the use is just:
int[] myArray = //whatever;
int[] changedArray = myArray.MoveFirstToLast();
I have an array of ints
int[] RowOfints = 1,2,3,4,5,6,7,8,9;
if i enter for example value 4 i want to remove 1,2,3 from array and return what's left.
How to do that?
If you don't want to use LINQ:
int[] newRowOfInts = new int[RowOfInts.Length - index];
Array.Copy(RowOfInts, index, newRowOfInts, 0, newRowOfInts.Length);
Using Skip extension in LINQ.
int[] newArray = RowOfInts.Skip(value).ToArray();
I'm interpreting your question that you want to find the index for the value 4 and then take everything starting from that index position.
var result = RowOfInts.SkipWhile(item => item != 4); // optionally, .ToArray()
result will be an IEnumerable<int> consisting of 4 .. 9. If you want a concrete array, you can use the optional ToArray() extension method as well. If no elements in the array match the given criteria, you will get a zero-length sequence.
OK, now that I understand the question better, I will post my version of the actual requirements (again perversely emphasising effeciency over readability):
private static int[] RemoveBeforeValue(int[] source, int value)
{
if (source == null)
return null;
int valueIndex = 0;
while (valueIndex < source.Length && source[valueIndex] != value)
valueIndex++;
if (valueIndex == 0)
return source;
int[] result = new int[source.Length - valueIndex];
Array.Copy(source, valueIndex, result, 0, result.Length);
return result;
}
OLD ANSWER
If you want to do it the hard (but efficient!) way, then you can do this (assuming you want to remove values less than the supplied value):
private static int[] RemoveValuesLessThan(int[] source, int newMinimum)
{
if (source == null)
return null;
int lessThanCount = 0;
for (int index = 0; index < source.Length; index++)
if (source[index] < newMinimum)
lessThanCount++;
if (lessThanCount == 0)
return source;
int[] result = new int[source.Length - lessThanCount];
int targetIndex = 0;
for (int index = 0; index < source.Length; index++)
if (source[index] >= newMinimum)
result[targetIndex++] = source[index];
return result;
}
For a sequential array of ints
public static void RemoveIntsBefore(int i)
{
int[] RowOfints = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (int k = 0; k < RowOfints.Length; k++)
{
if (RowOfints.ElementAt(k) < i)
{
RowOfints[k] = i;
}
}
RowOfints = RowOfints.Distinct().ToArray();
//this part is to write it on console
//foreach (var item in RowOfints)
//{
// Console.WriteLine(item);
//}
//Console.ReadLine();
}
with this one your array does not have to be sequential
public static void RemoveIntsBefore(int i)
{
int[] RowOfints = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 1,2 };
Console.WriteLine("OUTPUT");
foreach (var item in Enumerable.Range(i-1, RowOfints.Length + 1 - i).ToArray())
{
Console.WriteLine(RowOfints[item]);
}
Console.ReadLine();
}
using System.Linq;
....
int[] RowOfints = {1,2,3,4,5,6,7,8,9};
int[] Answer = RowOfints.Where(x => x != 1 && x != 2 && x != 3).ToArray()