Related
How can I quickly shift all the items in an array one to the left, padding the end with null?
For example, [0,1,2,3,4,5,6] would become [1,2,3,4,5,6,null]
Edit: I said quickly but I guess I meant efficiently. I need to do this without creating a List or some other data structure. This is something I need to do several hundred thousand times in as short amount of time as possible.
Here's my test harness...
var source = Enumerable.Range(1, 100).Cast<int?>().ToArray();
var destination = new int?[source.Length];
var s = new Stopwatch();
s.Start();
for (int i = 0; i < 1000000;i++)
{
Array.Copy(source, 1, destination, 0, source.Length - 1);
}
s.Stop();
Console.WriteLine(s.Elapsed);
Here are the performance results for 1 million iterations of each solution (8 Core Intel Xeon E5450 # 3.00GHz)
100 elements 10000 elements
For Loop 0.390s 31.839s
Array.Copy() 0.177s 12.496s
Aaron 1 3.789s 84.082s
Array.ConstrainedCopy() 0.197s 17.658s
Make the choice for yourself :)
The quickest way to do this is to use Array.Copy, which in the final implementation uses a bulk memory transfer operation (similar to memcpy):
var oldArray = new int?[] { 1, 2, 3, 4, 5, 6 };
var newArray = new int?[oldArray.Length];
Array.Copy(oldArray, 1, newArray, 0, oldArray.Length - 1);
// newArray is now { 2, 3, 4, 5, 6, null }
Edited: according to the documentation:
If sourceArray and destinationArray overlap, this method behaves as if the original values of sourceArray were preserved in a temporary location before destinationArray is overwritten.
So if you don't want to allocate a new array, you can pass in the original array for both source and destination--although I imagine the tradeoff will be a somewhat slower performance since the values go through a temporary holding position.
I suppose, as in any investigation of this kind, you should do some quick benchmarking.
Here is my solution, similar to Task's in that it is a simple Array wrapper and that it takes O(1) time to shift the array to the left.
public class ShiftyArray<T>
{
private readonly T[] array;
private int front;
public ShiftyArray(T[] array)
{
this.array = array;
front = 0;
}
public void ShiftLeft()
{
array[front++] = default(T);
if(front > array.Length - 1)
{
front = 0;
}
}
public void ShiftLeft(int count)
{
for(int i = 0; i < count; i++)
{
ShiftLeft();
}
}
public T this[int index]
{
get
{
if(index > array.Length - 1)
{
throw new IndexOutOfRangeException();
}
return array[(front + index) % array.Length];
}
}
public int Length { get { return array.Length; } }
}
Running it through Jason Punyon's test code...
int?[] intData = Enumerable.Range(1, 100).Cast<int?>().ToArray();
ShiftyArray<int?> array = new ShiftyArray<int?>(intData);
Stopwatch watch = new Stopwatch();
watch.Start();
for(int i = 0; i < 1000000; i++)
{
array.ShiftLeft();
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
Takes ~29ms, regardless of the array size.
Use the Array.Copy() method as in
int?[] myArray = new int?[]{0,1,2,3,4};
Array.Copy(myArray, 1, myArray, 0, myArray.Length - 1);
myArray[myArray.Length - 1] = null
The Array.Copy is probably the way, Microsoft wanted us to copy array elements...
Couldn't you use a System.Collections.Generic.Queue instead of an array ?
I feel like you need to perform actions on your value the discard it, thus using a queue seems to be more appropriate :
// dummy initialization
System.Collections.Generic.Queue<int> queue = new Queue<int>();
for (int i = 0; i < 7; ++i ) { queue.Enqueue(i); }// add each element at the end of the container
// working thread
if (queue.Count > 0)
doSomething(queue.Dequeue());// removes the last element of the container and calls doSomething on it
For any pour soul finding this thread and about to implement one of the highly rated answers. All of them are trash, I'm not sure why that is. Maybe Dested asked for a new array implementation at first or something that has now been removed from the question. Well if you simply want to shift the array and don't need a new one, see an answer like tdaines's answer. And read up on things like the Circular Buffer / Ring Buffer : http://en.wikipedia.org/wiki/Circular_buffer. No moving of the actual data is necessary. The performance of shifting an array should not be tied to the size of the array.
If it absolutely has to be in an array, then I would recommend the most obvious code possible.
for (int index = startIndex; index + 1 < values.Length; index++)
values[index] = values[index + 1];
values[values.Length - 1] = null;
This gives the optimizer the most opportunities to find the best way on whatever target platform the program is installed on.
EDIT:
I just borrowed Jason Punyon's test code, and I'm afraid he's right. Array.Copy wins!
var source = Enumerable.Range(1, 100).Cast<int?>().ToArray();
int indexToRemove = 4;
var s = new Stopwatch();
s.Start();
for (int i = 0; i < 1000000; i++)
{
Array.Copy(source, indexToRemove + 1, source, indexToRemove, source.Length - indexToRemove - 1);
//for (int index = indexToRemove; index + 1 < source.Length; index++)
// source[index] = source[index + 1];
}
s.Stop();
Console.WriteLine(s.Elapsed);
Array.Copy takes between 103 and 150 ms on my machine.
for loop takes between 269 and 338 ms on my machine.
Can't you
allocate the array with an extra 1000 elements
have an integer variable int base = 0
instead of accessing a[i] access a[base+i]
to do your shift, just say base++
Then after you've done this 1000 times, copy it down and start over.
That way, you only do the copy once per 1000 shifts.
Old joke:
Q: How many IBM 360s does it take to shift a register by 1 bit?
A: 33. 32 to hold the bits in place, and 1 to move the register. (or some such...)
You can use the same array as source and destination for fast in-place copy:
static void Main(string[] args)
{
int[] array = {0, 1, 2, 3, 4, 5, 6, 7};
Array.ConstrainedCopy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = 0;
}
You might do it like this:
var items = new int?[] { 0, 1, 2, 3, 4, 5, 6 }; // Your array
var itemList = new List<int?>(items); // Put the items in a List<>
itemList.RemoveAt(1); // Remove the item at index 1
itemList.Add(null); // Add a null to the end of the list
items = itemList.ToArray(); // Turn the list back into an array
Of course, it would be more efficient to get rid of the array entirely and just use a List<>. You could then forget the first line and last line and do it like this:
var itemList = new List<int?> { 0, 1, 2, 3, 4, 5, 6 };
itemList.RemoveAt(1); // Remove the item at index 1
itemList.Add(null); // Add a null to the end of the list
The best and most efficient method I believe is using Buffer.BlockCopy function.
You will set both source and destination to your array, the offset of the source is 1. Depending on your array type (I assume it is int), 1 int = 4 bytes, so you must pass in 4 as the second parameter of this function. Note that the offset is byte offset.
So it looks like this:
int bytes2copy = yourArray.length - 4;
Buffer.BlockCopy(yourArray, 4, yourArray, 0, bytes2copy);
yourArray[yourArray.length-1] = null;
Try this! using Linq. No need of second Array.
var i_array = new int?[] {0, 1, 2, 3, 4, 5, 6 };
i_array = i_array.Select((v, k) => new { v = v, k = k }).
Where(i => i.k > 0).Select(i => i.v).ToArray();
Array.Resize(ref i_array, i_array.Length + 1);
Output:
[0,1,2,3,4,5,6] would become [1,2,3,4,5,6,null]
If you own the memory you could consider using Unsafe Code and good old fashioned pointers.
Make yourself a memory stream and lock it down or use Marshal.AllocHGlobal
Construct all your arrays in it with a little bit of padding at the beginning and end.
increment or decrement all of the array pointers at once. You'll still need to loop back and set your nulls.
If you need to selectively increment or decrement the arrays you would have to add padding between them.
Arrays are incredibly low level data structures, if you treat them in a low level way you can get huge performance out of them.
A baytrail doing this could outperform Jason's with all its copying 8 Core Intel Xeon E5450 # 3.00GHz
Not tested this code, but it should shifts all the values to right by one. Note that the last three lines of code is all you require to efficiently shift the array.
public class Shift : MonoBehaviour {
//Initialize Array
public int[] queue;
void Start () {
//Create Array Rows
queue = new int[5];
//Set Values to 1,2,3,4,5
for (int i=0; i<5;i++)
{
queue[i] = i + 1;
}
//Get the integer at the first index
int prev = queue[0];
//Copy the array to the new array.
System.Array.Copy(queue, 1, queue, 0, queue.Length - 1);
//Set the last shifted value to the previously first value.
queue[queue.Length - 1] = prev;
Implementation with Extension methods passing shifting direction as Enum.
"for" statements and indexers only (don't use Array.Copy method).
using System;
namespace ShiftArrayElements
{
public static class EnumShifter
{
public static int[] Shift(int[] source, Direction[] directions)
{
for (var i = 0; i < directions.Length; i++)
{
var direction = directions[i];
if (direction == Direction.Left)
{
source.LeftShift();
}
else if (direction == Direction.Right)
{
source.RightShift();
}
else
{
throw new InvalidOperationException("Direction is invalid");
}
}
return source;
}
public static void LeftShift(this int[] source)
{
var lastIndex = source?.Length - 1 ?? 0;
var temp = source[0];
for (int j = 0; j + 1 < source.Length; j++)
{
source[j] = source[j + 1];
}
source[lastIndex] = temp;
}
public static void RightShift(this int[] source)
{
var lastIndex = source?.Length - 1 ?? 0;
var temp = source[lastIndex];
for (int j = lastIndex; j > 0; j--)
{
source[j] = source[j - 1];
}
source[0] = temp;
}
}
}
Array copying is an O(n) operation and creates a new array.
While array copying can certainly be done quickly and efficiently, the problem you've stated can actually be solved in an entirely different way without (as you've requested) creating a new array/data structure and only creating one small wrapping object instance per array:
using System;
using System.Text;
public class ArrayReindexer
{
private Array reindexed;
private int location, offset;
public ArrayReindexer( Array source )
{
reindexed = source;
}
public object this[int index]
{
get
{
if (offset > 0 && index >= location)
{
int adjustedIndex = index + offset;
return adjustedIndex >= reindexed.Length ? "null" : reindexed.GetValue( adjustedIndex );
}
return reindexed.GetValue( index );
}
}
public void Reindex( int position, int shiftAmount )
{
location = position;
offset = shiftAmount;
}
public override string ToString()
{
StringBuilder output = new StringBuilder( "[ " );
for (int i = 0; i < reindexed.Length; ++i)
{
output.Append( this[i] );
if (i == reindexed.Length - 1)
{
output.Append( " ]" );
}
else
{
output.Append( ", " );
}
}
return output.ToString();
}
}
By wrapping and controlling access to the array in this manner, we can now demonstrate how the problem was solved with an O(1) method call...
ArrayReindexer original = new ArrayReindexer( SourceArray );
Console.WriteLine( " Base array: {0}", original.ToString() );
ArrayReindexer reindexed = new ArrayReindexer( SourceArray );
reindexed.Reindex( 1, 1 );
Console.WriteLine( "Shifted array: {0}", reindexed.ToString() );
Will produce the output:
Base array: [ 0, 1, 2, 3, 4, 5, 6 ]
Shifted array: [ 0, 2, 3, 4, 5, 6, null ]
I'm willing to bet that there will be a reason that such a solution won't work for you, but I believe this does match your initial stated requirements. 8 )
It's often helpful to think about all the different kinds of solutions to a problem before implementing a specific one, and perhaps that might be the most important thing that this example can demonstrate.
Hope this helps!
Incorrect and slightly amusing answer (thanks, i'll be here all night !)
int?[] test = new int?[] {0,1,2,3,4,5,6 };
int?[] t = new int?[test.Length];
t = test.Skip(1).ToArray();
t[t.Length - 1] = null;
In the spirit of still using Skip (dont ask me, i know worst usage of LINQ extension methods ever), the only way I thought of rewriting it would be
int?[] test = new int?[] { 0, 1, 2, 3, 4, 5, 6 };
int?[] t = new int?[test.Length];
Array.Copy(test.Skip(1).ToArray(), t, t.Length - 1);
But it's in NO WAY faster than the other options.
I know this is an old question but coming from Google there was no simple example so thanks to this is the easiest way to reorder a list, and you don't have to supply the type it will work it out at runtime,
private static List<T> reorderList<T>(List<T> list){
List<T> newList = new List<T>();
list.ForEach(delegate(T item)
{
newList.Add(item);
});
return newList;
}
using System;
using System.Threading;
namespace ShiftMatrix
{
class Program
{
static void Main(string[] args)
{
MatrixOperation objMatrixOperation = new MatrixOperation();
//Create a matrix
int[,] mat = new int[,]
{
{1, 2},
{3,4 },
{5, 6},
{7,8},
{8,9},
};
int type = 2;
int counter = 0;
if (type == 1)
{
counter = mat.GetLength(0);
}
else
{
counter = mat.GetLength(1);
}
while (true)
{
for (int i = 0; i < counter; i++)
{
ShowMatrix(objMatrixOperation.ShiftMatrix(mat, i, type));
Thread.Sleep(TimeSpan.FromSeconds(2));
}
}
}
public static void ShowMatrix(int[,] matrix)
{
int rows = matrix.GetLength(0);
int columns = matrix.GetLength(1);
for (int k = 0; k < rows; k++)
{
for (int l = 0; l < columns; l++)
{
Console.Write(matrix[k, l] + " ");
}
Console.WriteLine();
}
}
}
class MatrixOperation
{
public int[,] ShiftMatrix(int[,] origanalMatrix, int shift, int type)
{
int rows = origanalMatrix.GetLength(0);
int cols = origanalMatrix.GetLength(1);
int[,] _tmpMatrix = new int[rows, cols];
if (type == 2)
{
for (int x1 = 0; x1 < rows; x1++)
{
int y2 = 0;
for (int y1 = shift; y2 < cols - shift; y1++, y2++)
{
_tmpMatrix[x1, y2] = origanalMatrix[x1, y1];
}
y2--;
for (int y1 = 0; y1 < shift; y1++, y2++)
{
_tmpMatrix[x1, y2] = origanalMatrix[x1, y1];
}
}
}
else
{
int x2 = 0;
for (int x1 = shift; x2 < rows - shift; x1++, x2++)
{
for (int y1 = 0; y1 < cols; y1++)
{
_tmpMatrix[x2, y1] = origanalMatrix[x1, y1];
}
}
x2--;
for (int x1 = 0; x1 < shift; x1++, x2++)
{
for (int y1 = 0; y1 < cols; y1++)
{
_tmpMatrix[x2, y1] = origanalMatrix[x1, y1];
}
}
}
return _tmpMatrix;
}
}
}
See C# code below to remove space from string. That shift character in array. Performance is O(n). No other array is used. So no extra memory either.
static void Main(string[] args)
{
string strIn = System.Console.ReadLine();
char[] chraryIn = strIn.ToCharArray();
int iShift = 0;
char chrTemp;
for (int i = 0; i < chraryIn.Length; ++i)
{
if (i > 0)
{
chrTemp = chraryIn[i];
chraryIn[i - iShift] = chrTemp;
chraryIn[i] = chraryIn[i - iShift];
}
if (chraryIn[i] == ' ') iShift++;
if (i >= chraryIn.Length - 1 - iShift) chraryIn[i] = ' ';
}
System.Console.WriteLine(new string(chraryIn));
System.Console.Read();
}
a is array of ints & d is number of times array has to shift left.
static int[] rotLeft(int[] a, int d)
{
var innerLoop = a.Length - 1;
for(var loop=0; loop < d; loop++)
{
var res = a[innerLoop];
for (var i= innerLoop; i>=0; i--)
{
var tempI = i-1;
if (tempI < 0)
{
tempI = innerLoop;
}
var yolo = a[tempI];
a[tempI] = res;
res = yolo;
}
}
return a;
}
Simple way to do it when you need to resize the same array.
var nLength = args.Length - 1;
Array.Copy(args, 1, args, 0, nLength);
Array.Resize(ref args, nLength);
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.
Following are two pieces of code I used to compute power sets of elements in a list
code 1)
public static List<List<int>> getCpower(List<int> list)
{
var result = new List<List<int>>();
for (int i = 0; i < (1 << list.Count); i++)
{
var sublist = new List<int>();
for (int j = 0; j < list.Count; j++)
{ if ((i & (1 << j)) != 0)
{ sublist.Add(list[j]);
}
}
result.Add(sublist);
}
return result;
}
code 2)
public static List<List<int>> getCpower(List<int> list)
{
var result = new List<List<int>>();var sublist = new List<int>();
for (int i = 0; i < (1 << list.Count); i++)
{
sublist.Clear();sublist.TrimExcess();
for (int j = 0; j < list.Count; j++)
{ if ((i & (1 << j)) != 0)
{ sublist.Add(list[j]);
}
}
result.Add(sublist);
}
return result;
}
The first code used a new statement and if i try to find out powersets of list with count 30 then OutOfMemoryException arises.So to save memory i used Clear() and TrimExcess() to get the list as if it were initialized using a new statement in code2. But these two codes return different results. I do not get why is this happening. Please help.
Are the two following two pieces not doing the same thing
for(....)
{
var sublist = new List<int>();
for(......)
{
//some code
}
}
and
var sublist = new List<int>();
for(.....)
{
sublist.Clear();sublist.TrimExcess();
for(.... )
{
//some code
}
}
In your second code, you only have a single nested list - you're adding several references referring to the same sublist, which is pointless.
Have you considered that maybe the reason you're running out of space with your first code is because you're fundamentally trying to hold too much data in memory at a time?
You could consider returning an IEnumerable<List<int>> like this:
public static IEnumerable<List<int>> getCpower(List<int> list)
{
for (int i = 0; i < (1 << list.Count); i++)
{
var sublist = new List<int>();
for (int j = 0; j < list.Count; j++)
{ if ((i & (1 << j)) != 0)
{
sublist.Add(list[j]);
}
}
yield return sublist;
}
}
This will now be lazily evaluated - so you could iterate over the top-level sequence, but unless the lists are retained by the caller, you'll only have a single list in memory at a time.
In the second piece of code you are clearing the list of results. This alters the outcome of your algorithm. You are throwing away your results because you are reusing the same list instance for all iterations.
In the second code example, you only ever have a single sublist instance. That same instance is cleared and added to the list again every time you loop through. Here's an example to help you understand:
var sublist = new List<int> { 1, 2, 3 };
var result = new List<List<int>> { sublist };
//result[0] is now {1, 2, 3}
sublist.Clear();
//result[0] is now {}
result.Add(sublist);
//result[0], result[1], and sublist are the same instance
I have an List<int> which contains 1,2,4,7,9 for example.
I have a range from 0 to 10.
Is there a way to determine what numbers are missing in that sequence?
I thought LINQ might provide an option but I can't see one
In the real world my List could contain 100,000 items so performance is key
var list = new List<int>(new[] { 1, 2, 4, 7, 9 });
var result = Enumerable.Range(0, 10).Except(list);
Turn the range you want to check into a HashSet:
public IEnumerable<int> FindMissing(IEnumerable<int> values)
{
HashSet<int> myRange = new HashSet<int>(Enumerable.Range(0,10));
myRange.ExceptWith(values);
return myRange;
}
Will return the values that aren't in values.
Using Unity i have tested two solutions on set of million integers. Looks like using Dictionary and two "for" loops gives better result than Enumerable.Except
FindMissing1 Total time: 0.1420 (Enumerable.Except)
FindMissing2 Total time: 0.0621 (Dictionary and two for loops)
public static class ArrayExtension
{
public static T[] FindMissing1<T>(T[] range, T[] values)
{
List<T> result = Enumerable.Except<T>(range, values).ToList<T>();
return result.ToArray<T>();
}
public static T[] FindMissing2<T>(T[] range, T[] values)
{
List<T> result = new List<T>();
Dictionary<T, T> hash = new Dictionary<T, T>(values.Length);
for (int i = 0; i < values.Length; i++)
hash.Add(values[i], values[i]);
for (int i = 0; i < range.Length; i++)
{
if (!hash.ContainsKey(range[i]))
result.Add(range[i]);
}
return result.ToArray<T>();
}
}
public class ArrayManipulationTest : MonoBehaviour
{
void Start()
{
int rangeLength = 1000000;
int[] range = Enumerable.Range(0, rangeLength).ToArray();
int[] values = new int[rangeLength / 5];
int[] missing;
float start;
float duration;
for (int i = 0; i < rangeLength / 5; i ++)
values[i] = i * 5;
start = Time.realtimeSinceStartup;
missing = ArrayExtension.FindMissing1<int>(range, values);
duration = Time.realtimeSinceStartup - start;
Debug.Log($"FindMissing1 Total time: {duration:0.0000}");
start = Time.realtimeSinceStartup;
missing = ArrayExtension.FindMissing2<int>(range, values);
duration = Time.realtimeSinceStartup - start;
Debug.Log($"FindMissing2 Total time: {duration:0.0000}");
}
}
List<int> selectedNumbers = new List<int>(){8, 5, 3, 12, 2};
int firstNumber = selectedNumbers.OrderBy(i => i).First();
int lastNumber = selectedNumbers.OrderBy(i => i).Last();
List<int> allNumbers = Enumerable.Range(firstNumber, lastNumber - firstNumber + 1).ToList();
List<int> missingNumbers = allNumbers.Except(selectedNumbers).ToList();
foreach (int i in missingNumbers)
{
Response.Write(i);
}
LINQ's Except method would be the most readable. Whether it performs adequately for you or not would be a matter for testing.
E.g.
range.Except(listOfValues);
Edit
Here's the program I used for my mini-benchmark, for others to plug away with:
static void Main()
{
var a = Enumerable.Range(0, 1000000);
var b = new List<int>();
for (int i = 0; i < 1000000; i += 10)
{
b.Add(i);
}
Stopwatch sw = new Stopwatch();
sw.Start();
var c = a.Except(b).ToList();
sw.Stop();
Console.WriteLine("Milliseconds {0}", sw.ElapsedMilliseconds );
sw.Reset();
Console.ReadLine();
}
An alternative method which works in general for any two IEnunumerable<T> where T :IComparable. If the IEnumerables are both sorted, this works in O(1) memory (i.e. there is no creating another ICollection and subtracting, etc.) and in O(n) time.
The use of IEnumerable<IComparable> and GetEnumerator makes this a little less readable, but far more general.
Implementation
/// <summary>
/// <para>For two sorted IEnumerable<T> (superset and subset),</para>
/// <para>returns the values in superset which are not in subset.</para>
/// </summary>
public static IEnumerable<T> CompareSortedEnumerables<T>(IEnumerable<T> superset, IEnumerable<T> subset)
where T : IComparable
{
IEnumerator<T> supersetEnumerator = superset.GetEnumerator();
IEnumerator<T> subsetEnumerator = subset.GetEnumerator();
bool itemsRemainingInSubset = subsetEnumerator.MoveNext();
// handle the case when the first item in subset is less than the first item in superset
T firstInSuperset = superset.First();
while ( itemsRemainingInSubset && supersetEnumerator.Current.CompareTo(subsetEnumerator.Current) >= 0 )
itemsRemainingInSubset = subsetEnumerator.MoveNext();
while ( supersetEnumerator.MoveNext() )
{
int comparison = supersetEnumerator.Current.CompareTo(subsetEnumerator.Current);
if ( !itemsRemainingInSubset || comparison < 0 )
{
yield return supersetEnumerator.Current;
}
else if ( comparison >= 0 )
{
while ( itemsRemainingInSubset && supersetEnumerator.Current.CompareTo(subsetEnumerator.Current) >= 0 )
itemsRemainingInSubset = subsetEnumerator.MoveNext();
}
}
}
Usage
var values = Enumerable.Range(0, 11);
var list = new List<int> { 1, 2, 4, 7, 9 };
var notIncluded = CompareSortedEnumerables(values, list);
If the range is predictable I suggest the following solution:
public static void Main()
{
//set up the expected range
var expectedRange = Enumerable.Range(0, 10);
//set up the current list
var currentList = new List<int> {1, 2, 4, 7, 9};
//get the missing items
var missingItems = expectedRange.Except(currentList);
//print the missing items
foreach (int missingItem in missingItems)
{
Console.WriteLine(missingItem);
}
Console.ReadLine();
}
Regards,
y00daa
This does not use LINQ but it works in linear time.
I assume that input list is sorted.
This takes O(list.Count).
private static IEnumerable<int> get_miss(List<int> list,int length)
{
var miss = new List<int>();
int i =0;
for ( i = 0; i < list.Count - 1; i++)
{
foreach (var item in
Enumerable.Range(list[i] + 1, list[i + 1] - list[i] - 1))
{
yield return item;
}
}
foreach (var item in Enumerable.Range(list[i]+1,length-list[i]))
{
yield return item;
}
}
This should take O(n) where n is length of full range.
static void Main()
{
List<int> identifiers = new List<int>() { 1, 2, 4, 7, 9 };
Stopwatch sw = new Stopwatch();
sw.Start();
List<int> miss = GetMiss(identifiers,150000);
sw.Stop();
Console.WriteLine("{0}",sw.ElapsedMilliseconds);
}
private static List<int> GetMiss(List<int> identifiers,int length)
{
List<int> miss = new List<int>();
int j = 0;
for (int i = 0; i < length; i++)
{
if (i < identifiers[j])
miss.Add(i);
else if (i == identifiers[j])
j++;
if (j == identifiers.Count)
{
miss.AddRange(Enumerable.Range(i + 1, length - i));
break;
}
}
return miss;
}
Ok, really, create a new list which parallels the initial list and run the method Except over it...
I have created a fully linq answer using the Aggregate method instead to find the missings:
var list = new List<int>(new[] { 1, 2, 4, 7, 9 }); // Assumes list is ordered at this point
list.Insert(0, 0); // No error checking, just put in the lowest and highest possibles.
list.Add(10); // For real world processing, put in check and if not represented then add it/them.
var missing = new List<int>(); // Hold any missing values found.
list.Aggregate ((seed, aggr) => // Seed is the previous #, aggr is the current number.
{
var diff = (aggr - seed) -1; // A difference between them indicates missing.
if (diff > 0) // Missing found...put in the missing range.
missing.AddRange(Enumerable.Range((aggr - diff), diff));
return aggr;
});
The missing list has this after the above code has been executed:
3, 5, 6, 8
for a List L a general solution (works in all programming languages) would be simply
L.Count()*(L.Count()+1)/2 - L.Sum();
which returns the expected sum of series minus the actual series.
for a List of size n the missing number is:
n(n+1)/2 - (sum of list numbers)
this method here returns the number of missing elements ,sort the set , add all elements from range 0 to range max , then remove the original elements , then you will have the missing set
int makeArrayConsecutive(int[] statues)
{
Array.Sort(statues);
HashSet<int> set = new HashSet<int>();
for(int i = statues[0]; i< statues[statues.Length -1]; i++)
{
set.Add(i);
}
for (int i = 0; i < statues.Length; i++)
{
set.Remove(statues[i]);
}
var x = set.Count;
return x;
// return set ; // use this if you need the actual elements + change the method return type
}
Create an array of num items
const int numItems = 1000;
bool found[numItems] = new bool[numItems];
List<int> list;
PopulateList(list);
list.ForEach( i => found[i] = true );
// now iterate found for the numbers found
for(int count = 0; i < numItems; ++numItems){
Console.WriteList("Item {0} is {1}", count, found[count] ? "there" : "not there");
}
This method does not use LINQ and works in general for any two IEnunumerable<T> where T :IComparable
public static IEnumerable<T> FindMissing<T>(IEnumerable<T> superset, IEnumerable<T> subset) where T : IComparable
{
bool include = true;
foreach (var i in superset)
{
foreach (var j in subset)
{
include = i.CompareTo(j) == 0;
if (include)
break;
}
if (!include)
yield return i;
}
}
int sum = 0,missingNumber;
int[] arr = { 1,2,3,4,5,6,7,8,9};
for (int i = 0; i < arr.Length; i++)
{
sum += arr[i];
}
Console.WriteLine("The sum from 1 to 10 is 55");
Console.WriteLine("Sum is :" +sum);
missingNumber = 55 - sum;
Console.WriteLine("Missing Number is :-"+missingNumber);
Console.ReadLine();
How can I quickly shift all the items in an array one to the left, padding the end with null?
For example, [0,1,2,3,4,5,6] would become [1,2,3,4,5,6,null]
Edit: I said quickly but I guess I meant efficiently. I need to do this without creating a List or some other data structure. This is something I need to do several hundred thousand times in as short amount of time as possible.
Here's my test harness...
var source = Enumerable.Range(1, 100).Cast<int?>().ToArray();
var destination = new int?[source.Length];
var s = new Stopwatch();
s.Start();
for (int i = 0; i < 1000000;i++)
{
Array.Copy(source, 1, destination, 0, source.Length - 1);
}
s.Stop();
Console.WriteLine(s.Elapsed);
Here are the performance results for 1 million iterations of each solution (8 Core Intel Xeon E5450 # 3.00GHz)
100 elements 10000 elements
For Loop 0.390s 31.839s
Array.Copy() 0.177s 12.496s
Aaron 1 3.789s 84.082s
Array.ConstrainedCopy() 0.197s 17.658s
Make the choice for yourself :)
The quickest way to do this is to use Array.Copy, which in the final implementation uses a bulk memory transfer operation (similar to memcpy):
var oldArray = new int?[] { 1, 2, 3, 4, 5, 6 };
var newArray = new int?[oldArray.Length];
Array.Copy(oldArray, 1, newArray, 0, oldArray.Length - 1);
// newArray is now { 2, 3, 4, 5, 6, null }
Edited: according to the documentation:
If sourceArray and destinationArray overlap, this method behaves as if the original values of sourceArray were preserved in a temporary location before destinationArray is overwritten.
So if you don't want to allocate a new array, you can pass in the original array for both source and destination--although I imagine the tradeoff will be a somewhat slower performance since the values go through a temporary holding position.
I suppose, as in any investigation of this kind, you should do some quick benchmarking.
Here is my solution, similar to Task's in that it is a simple Array wrapper and that it takes O(1) time to shift the array to the left.
public class ShiftyArray<T>
{
private readonly T[] array;
private int front;
public ShiftyArray(T[] array)
{
this.array = array;
front = 0;
}
public void ShiftLeft()
{
array[front++] = default(T);
if(front > array.Length - 1)
{
front = 0;
}
}
public void ShiftLeft(int count)
{
for(int i = 0; i < count; i++)
{
ShiftLeft();
}
}
public T this[int index]
{
get
{
if(index > array.Length - 1)
{
throw new IndexOutOfRangeException();
}
return array[(front + index) % array.Length];
}
}
public int Length { get { return array.Length; } }
}
Running it through Jason Punyon's test code...
int?[] intData = Enumerable.Range(1, 100).Cast<int?>().ToArray();
ShiftyArray<int?> array = new ShiftyArray<int?>(intData);
Stopwatch watch = new Stopwatch();
watch.Start();
for(int i = 0; i < 1000000; i++)
{
array.ShiftLeft();
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
Takes ~29ms, regardless of the array size.
Use the Array.Copy() method as in
int?[] myArray = new int?[]{0,1,2,3,4};
Array.Copy(myArray, 1, myArray, 0, myArray.Length - 1);
myArray[myArray.Length - 1] = null
The Array.Copy is probably the way, Microsoft wanted us to copy array elements...
Couldn't you use a System.Collections.Generic.Queue instead of an array ?
I feel like you need to perform actions on your value the discard it, thus using a queue seems to be more appropriate :
// dummy initialization
System.Collections.Generic.Queue<int> queue = new Queue<int>();
for (int i = 0; i < 7; ++i ) { queue.Enqueue(i); }// add each element at the end of the container
// working thread
if (queue.Count > 0)
doSomething(queue.Dequeue());// removes the last element of the container and calls doSomething on it
For any pour soul finding this thread and about to implement one of the highly rated answers. All of them are trash, I'm not sure why that is. Maybe Dested asked for a new array implementation at first or something that has now been removed from the question. Well if you simply want to shift the array and don't need a new one, see an answer like tdaines's answer. And read up on things like the Circular Buffer / Ring Buffer : http://en.wikipedia.org/wiki/Circular_buffer. No moving of the actual data is necessary. The performance of shifting an array should not be tied to the size of the array.
If it absolutely has to be in an array, then I would recommend the most obvious code possible.
for (int index = startIndex; index + 1 < values.Length; index++)
values[index] = values[index + 1];
values[values.Length - 1] = null;
This gives the optimizer the most opportunities to find the best way on whatever target platform the program is installed on.
EDIT:
I just borrowed Jason Punyon's test code, and I'm afraid he's right. Array.Copy wins!
var source = Enumerable.Range(1, 100).Cast<int?>().ToArray();
int indexToRemove = 4;
var s = new Stopwatch();
s.Start();
for (int i = 0; i < 1000000; i++)
{
Array.Copy(source, indexToRemove + 1, source, indexToRemove, source.Length - indexToRemove - 1);
//for (int index = indexToRemove; index + 1 < source.Length; index++)
// source[index] = source[index + 1];
}
s.Stop();
Console.WriteLine(s.Elapsed);
Array.Copy takes between 103 and 150 ms on my machine.
for loop takes between 269 and 338 ms on my machine.
Can't you
allocate the array with an extra 1000 elements
have an integer variable int base = 0
instead of accessing a[i] access a[base+i]
to do your shift, just say base++
Then after you've done this 1000 times, copy it down and start over.
That way, you only do the copy once per 1000 shifts.
Old joke:
Q: How many IBM 360s does it take to shift a register by 1 bit?
A: 33. 32 to hold the bits in place, and 1 to move the register. (or some such...)
You can use the same array as source and destination for fast in-place copy:
static void Main(string[] args)
{
int[] array = {0, 1, 2, 3, 4, 5, 6, 7};
Array.ConstrainedCopy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = 0;
}
You might do it like this:
var items = new int?[] { 0, 1, 2, 3, 4, 5, 6 }; // Your array
var itemList = new List<int?>(items); // Put the items in a List<>
itemList.RemoveAt(1); // Remove the item at index 1
itemList.Add(null); // Add a null to the end of the list
items = itemList.ToArray(); // Turn the list back into an array
Of course, it would be more efficient to get rid of the array entirely and just use a List<>. You could then forget the first line and last line and do it like this:
var itemList = new List<int?> { 0, 1, 2, 3, 4, 5, 6 };
itemList.RemoveAt(1); // Remove the item at index 1
itemList.Add(null); // Add a null to the end of the list
The best and most efficient method I believe is using Buffer.BlockCopy function.
You will set both source and destination to your array, the offset of the source is 1. Depending on your array type (I assume it is int), 1 int = 4 bytes, so you must pass in 4 as the second parameter of this function. Note that the offset is byte offset.
So it looks like this:
int bytes2copy = yourArray.length - 4;
Buffer.BlockCopy(yourArray, 4, yourArray, 0, bytes2copy);
yourArray[yourArray.length-1] = null;
Try this! using Linq. No need of second Array.
var i_array = new int?[] {0, 1, 2, 3, 4, 5, 6 };
i_array = i_array.Select((v, k) => new { v = v, k = k }).
Where(i => i.k > 0).Select(i => i.v).ToArray();
Array.Resize(ref i_array, i_array.Length + 1);
Output:
[0,1,2,3,4,5,6] would become [1,2,3,4,5,6,null]
If you own the memory you could consider using Unsafe Code and good old fashioned pointers.
Make yourself a memory stream and lock it down or use Marshal.AllocHGlobal
Construct all your arrays in it with a little bit of padding at the beginning and end.
increment or decrement all of the array pointers at once. You'll still need to loop back and set your nulls.
If you need to selectively increment or decrement the arrays you would have to add padding between them.
Arrays are incredibly low level data structures, if you treat them in a low level way you can get huge performance out of them.
A baytrail doing this could outperform Jason's with all its copying 8 Core Intel Xeon E5450 # 3.00GHz
Not tested this code, but it should shifts all the values to right by one. Note that the last three lines of code is all you require to efficiently shift the array.
public class Shift : MonoBehaviour {
//Initialize Array
public int[] queue;
void Start () {
//Create Array Rows
queue = new int[5];
//Set Values to 1,2,3,4,5
for (int i=0; i<5;i++)
{
queue[i] = i + 1;
}
//Get the integer at the first index
int prev = queue[0];
//Copy the array to the new array.
System.Array.Copy(queue, 1, queue, 0, queue.Length - 1);
//Set the last shifted value to the previously first value.
queue[queue.Length - 1] = prev;
Implementation with Extension methods passing shifting direction as Enum.
"for" statements and indexers only (don't use Array.Copy method).
using System;
namespace ShiftArrayElements
{
public static class EnumShifter
{
public static int[] Shift(int[] source, Direction[] directions)
{
for (var i = 0; i < directions.Length; i++)
{
var direction = directions[i];
if (direction == Direction.Left)
{
source.LeftShift();
}
else if (direction == Direction.Right)
{
source.RightShift();
}
else
{
throw new InvalidOperationException("Direction is invalid");
}
}
return source;
}
public static void LeftShift(this int[] source)
{
var lastIndex = source?.Length - 1 ?? 0;
var temp = source[0];
for (int j = 0; j + 1 < source.Length; j++)
{
source[j] = source[j + 1];
}
source[lastIndex] = temp;
}
public static void RightShift(this int[] source)
{
var lastIndex = source?.Length - 1 ?? 0;
var temp = source[lastIndex];
for (int j = lastIndex; j > 0; j--)
{
source[j] = source[j - 1];
}
source[0] = temp;
}
}
}
Array copying is an O(n) operation and creates a new array.
While array copying can certainly be done quickly and efficiently, the problem you've stated can actually be solved in an entirely different way without (as you've requested) creating a new array/data structure and only creating one small wrapping object instance per array:
using System;
using System.Text;
public class ArrayReindexer
{
private Array reindexed;
private int location, offset;
public ArrayReindexer( Array source )
{
reindexed = source;
}
public object this[int index]
{
get
{
if (offset > 0 && index >= location)
{
int adjustedIndex = index + offset;
return adjustedIndex >= reindexed.Length ? "null" : reindexed.GetValue( adjustedIndex );
}
return reindexed.GetValue( index );
}
}
public void Reindex( int position, int shiftAmount )
{
location = position;
offset = shiftAmount;
}
public override string ToString()
{
StringBuilder output = new StringBuilder( "[ " );
for (int i = 0; i < reindexed.Length; ++i)
{
output.Append( this[i] );
if (i == reindexed.Length - 1)
{
output.Append( " ]" );
}
else
{
output.Append( ", " );
}
}
return output.ToString();
}
}
By wrapping and controlling access to the array in this manner, we can now demonstrate how the problem was solved with an O(1) method call...
ArrayReindexer original = new ArrayReindexer( SourceArray );
Console.WriteLine( " Base array: {0}", original.ToString() );
ArrayReindexer reindexed = new ArrayReindexer( SourceArray );
reindexed.Reindex( 1, 1 );
Console.WriteLine( "Shifted array: {0}", reindexed.ToString() );
Will produce the output:
Base array: [ 0, 1, 2, 3, 4, 5, 6 ]
Shifted array: [ 0, 2, 3, 4, 5, 6, null ]
I'm willing to bet that there will be a reason that such a solution won't work for you, but I believe this does match your initial stated requirements. 8 )
It's often helpful to think about all the different kinds of solutions to a problem before implementing a specific one, and perhaps that might be the most important thing that this example can demonstrate.
Hope this helps!
Incorrect and slightly amusing answer (thanks, i'll be here all night !)
int?[] test = new int?[] {0,1,2,3,4,5,6 };
int?[] t = new int?[test.Length];
t = test.Skip(1).ToArray();
t[t.Length - 1] = null;
In the spirit of still using Skip (dont ask me, i know worst usage of LINQ extension methods ever), the only way I thought of rewriting it would be
int?[] test = new int?[] { 0, 1, 2, 3, 4, 5, 6 };
int?[] t = new int?[test.Length];
Array.Copy(test.Skip(1).ToArray(), t, t.Length - 1);
But it's in NO WAY faster than the other options.
I know this is an old question but coming from Google there was no simple example so thanks to this is the easiest way to reorder a list, and you don't have to supply the type it will work it out at runtime,
private static List<T> reorderList<T>(List<T> list){
List<T> newList = new List<T>();
list.ForEach(delegate(T item)
{
newList.Add(item);
});
return newList;
}
using System;
using System.Threading;
namespace ShiftMatrix
{
class Program
{
static void Main(string[] args)
{
MatrixOperation objMatrixOperation = new MatrixOperation();
//Create a matrix
int[,] mat = new int[,]
{
{1, 2},
{3,4 },
{5, 6},
{7,8},
{8,9},
};
int type = 2;
int counter = 0;
if (type == 1)
{
counter = mat.GetLength(0);
}
else
{
counter = mat.GetLength(1);
}
while (true)
{
for (int i = 0; i < counter; i++)
{
ShowMatrix(objMatrixOperation.ShiftMatrix(mat, i, type));
Thread.Sleep(TimeSpan.FromSeconds(2));
}
}
}
public static void ShowMatrix(int[,] matrix)
{
int rows = matrix.GetLength(0);
int columns = matrix.GetLength(1);
for (int k = 0; k < rows; k++)
{
for (int l = 0; l < columns; l++)
{
Console.Write(matrix[k, l] + " ");
}
Console.WriteLine();
}
}
}
class MatrixOperation
{
public int[,] ShiftMatrix(int[,] origanalMatrix, int shift, int type)
{
int rows = origanalMatrix.GetLength(0);
int cols = origanalMatrix.GetLength(1);
int[,] _tmpMatrix = new int[rows, cols];
if (type == 2)
{
for (int x1 = 0; x1 < rows; x1++)
{
int y2 = 0;
for (int y1 = shift; y2 < cols - shift; y1++, y2++)
{
_tmpMatrix[x1, y2] = origanalMatrix[x1, y1];
}
y2--;
for (int y1 = 0; y1 < shift; y1++, y2++)
{
_tmpMatrix[x1, y2] = origanalMatrix[x1, y1];
}
}
}
else
{
int x2 = 0;
for (int x1 = shift; x2 < rows - shift; x1++, x2++)
{
for (int y1 = 0; y1 < cols; y1++)
{
_tmpMatrix[x2, y1] = origanalMatrix[x1, y1];
}
}
x2--;
for (int x1 = 0; x1 < shift; x1++, x2++)
{
for (int y1 = 0; y1 < cols; y1++)
{
_tmpMatrix[x2, y1] = origanalMatrix[x1, y1];
}
}
}
return _tmpMatrix;
}
}
}
See C# code below to remove space from string. That shift character in array. Performance is O(n). No other array is used. So no extra memory either.
static void Main(string[] args)
{
string strIn = System.Console.ReadLine();
char[] chraryIn = strIn.ToCharArray();
int iShift = 0;
char chrTemp;
for (int i = 0; i < chraryIn.Length; ++i)
{
if (i > 0)
{
chrTemp = chraryIn[i];
chraryIn[i - iShift] = chrTemp;
chraryIn[i] = chraryIn[i - iShift];
}
if (chraryIn[i] == ' ') iShift++;
if (i >= chraryIn.Length - 1 - iShift) chraryIn[i] = ' ';
}
System.Console.WriteLine(new string(chraryIn));
System.Console.Read();
}
a is array of ints & d is number of times array has to shift left.
static int[] rotLeft(int[] a, int d)
{
var innerLoop = a.Length - 1;
for(var loop=0; loop < d; loop++)
{
var res = a[innerLoop];
for (var i= innerLoop; i>=0; i--)
{
var tempI = i-1;
if (tempI < 0)
{
tempI = innerLoop;
}
var yolo = a[tempI];
a[tempI] = res;
res = yolo;
}
}
return a;
}
Simple way to do it when you need to resize the same array.
var nLength = args.Length - 1;
Array.Copy(args, 1, args, 0, nLength);
Array.Resize(ref args, nLength);