Permutation of string without recursion - c#

Here is the recursive code.
Can you guys give inputs on how I can implement this using iterative method?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PermAndComb
{
class Program
{
static void Main(string[] args)
{
string s = "abcd";
Permutation(s);
Console.ReadKey();
}
public static void Permutation(string s)
{
int len = s.Length;
char [] inStr = s.ToCharArray();
StringBuilder outStr = new StringBuilder();
bool[] used = new bool[len];
doPermute(inStr, outStr,used, len, 0);
}
public static void doPermute(char[] instr, StringBuilder outStr,bool [] used, int len, int level)
{
if (level == len)
{
Console.WriteLine(outStr.ToString());
return;
}
for (int i = 0; i < len; i++)
{
if (used[i]) continue;
outStr.Append(instr[i]);
used[i] = true;
doPermute(instr, outStr, used, len, level + 1);
used[i] = false;
outStr.Length = outStr.Length - 1;
}
}
}
}

This article is rather heavy on the math, but might help out:
http://msdn.microsoft.com/en-us/magazine/cc163513.aspx
In summary, you use factoradics to enumerate the permutation in lexical order. And if that sounds like Greek to you, you're not alone.
Now, that's the correct way to do it (at least until a math PhD figures out something better). But I doubt it's what they're looking for in an interview. More likely, they're looking for an understanding that any recursive problem is also a stack problem that just uses the program's call stack rather than building it's own.
So you can convert any recursive code to iterative by taking a stack, pushing the initial value, then looping while the stack is not empty. Inside the loop you pop the next value, make the same calculation you would have made in your recursive function and push everywhere you would have made a recursive call.

the factoradics approach is less work than you'd be led to expect based on the article. I've had to use similar approach on many a Project Euler problem.
string str = "abcd";
Func<int, int> factorial = n =>
Enumerable.Range(1, n)
.Aggregate((i, j) => i * j);
Func<int, int, int[]> tofactoradic = (n, strLength) =>
Enumerable.Range(1, strLength)
.Reverse()
.Select(i => { var m = n; n /= i; return m % i; })
.ToArray();
Func<int[], string, string> Apply = (f, s) => {
var chars = s.ToList();
var result = "";
for (int i = 0; i < s.Length; i++) {
result += chars[f[i]];
chars.RemoveAt(f[i]);
}
return result;
};
int max = factorial(str.Length);
for (int i = 0; i < max; i++ ) {
var f = tofactoradic(i, str.Length);
Console.WriteLine(Apply(f, str));
}

Related

Cycling the elements of one C# List within another List [duplicate]

Lists say I have a list List<int> {1,2,3,4,5}
Rotate means:
=> {2,3,4,5,1} => {3,4,5,1,2} => {4,5,1,2,3}
Maybe rotate is not the best word for this, but hope you understand what I means
My question, whats the easiest way (in short code, c# 4 Linq ready), and will not be hit by performance (reasonable performance)
Thanks.
List<T>
The simplest way (for a List<T>) is to use:
int first = list[0];
list.RemoveAt(0);
list.Add(first);
Performance is nasty though - O(n).
Array
This is basically equivalent to the List<T> version, but more manual:
int first = array[0];
Array.Copy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = first;
LinkedList<T>
If you could use a LinkedList<T> instead, that would be much simpler:
int first = linkedList.First;
linkedList.RemoveFirst();
linkedList.AddLast(first);
This is O(1) as each operation is constant time.
Queue<T>
cadrell0's solution of using a queue is a single statement, as Dequeue removes the element and returns it:
queue.Enqueue(queue.Dequeue());
While I can't find any documentation of the performance characteristic of this, I'd expect Queue<T> to be implemented using an array and an index as the "virtual starting point" - in which case this is another O(1) solution.
Note that in all of these cases you'd want to check for the list being empty first. (You could deem that to be an error, or a no-op.)
You could implement it as a queue. Dequeue and Enqueue the same value.
**I wasn't sure about performance in converting a List to a Queue, but people upvoted my comment, so I'm posting this as an answer.
I use this one:
public static List<T> Rotate<T>(this List<T> list, int offset)
{
return list.Skip(offset).Concat(list.Take(offset)).ToList();
}
It seems like some answerers have treated this as a chance to explore data structures. While those answers are informative and useful, they are not very Linq'ish.
The Linq'ish approach is: You get an extension method which returns a lazy IEnumerable that knows how to build what you want. This method doesn't modify the source and should only allocate a copy of the source if necessary.
public static IEnumerable<IEnumerable<T>> Rotate<T>(this List<T> source)
{
for(int i = 0; i < source.Count; i++)
{
yield return source.TakeFrom(i).Concat(source.TakeUntil(i));
}
}
//similar to list.Skip(i-1), but using list's indexer access to reduce iterations
public static IEnumerable<T> TakeFrom<T>(this List<T> source, int index)
{
for(int i = index; i < source.Count; i++)
{
yield return source[i];
}
}
//similar to list.Take(i), but using list's indexer access to reduce iterations
public static IEnumerable<T> TakeUntil<T>(this List<T> source, int index)
{
for(int i = 0; i < index; i++)
{
yield return source[i];
}
}
Used as:
List<int> myList = new List<int>(){1, 2, 3, 4, 5};
foreach(IEnumerable<int> rotation in myList.Rotate())
{
//do something with that rotation
}
How about this:
var output = input.Skip(rot)
.Take(input.Count - rot)
.Concat(input.Take(rot))
.ToList();
Where rot is the number of spots to rotate - which must be less than the number of elements in the input list.
As #cadrell0 answer shows if this is all you do with your list, you should use a queue instead of a list.
My solution maybe too basic (I wouldn't like to say it's lame...) and not LINQ'ish.
However, it has a pretty good performance.
int max = 5; //the fixed size of your array.
int[] inArray = new int[5] {0,0,0,0,0}; //initial values only.
void putValueToArray(int thisData)
{
//let's do the magic here...
Array.Copy(inArray, 1, inArray, 0, max-1);
inArray[max-1] = thisData;
}
Try
List<int> nums = new List<int> {1,2,3,4,5};
var newNums = nums.Skip(1).Take(nums.Count() - 1).ToList();
newNums.Add(nums[0]);
Although, I like Jon Skeet's answer better.
My solution for Arrays:
public static void ArrayRotate(Array data, int index)
{
if (index > data.Length)
throw new ArgumentException("Invalid index");
else if (index == data.Length || index == 0)
return;
var copy = (Array)data.Clone();
int part1Length = data.Length - index;
//Part1
Array.Copy(copy, 0, data, index, part1Length);
//Part2
Array.Copy(copy, part1Length, data, 0, index);
}
I've used the following extensions for this:
static class Extensions
{
public static IEnumerable<T> RotateLeft<T>(this IEnumerable<T> e, int n) =>
n >= 0 ? e.Skip(n).Concat(e.Take(n)) : e.RotateRight(-n);
public static IEnumerable<T> RotateRight<T>(this IEnumerable<T> e, int n) =>
e.Reverse().RotateLeft(n).Reverse();
}
They're certainly easy (OP title request), and they've got reasonable performance (OP write-up request). Here's a little demo I ran in LINQPad 5 on an above-average-powered laptop:
void Main()
{
const int n = 1000000;
const int r = n / 10;
var a = Enumerable.Range(0, n);
var t = Stopwatch.StartNew();
Console.WriteLine(a.RotateLeft(r).ToArray().First());
Console.WriteLine(a.RotateLeft(-r).ToArray().First());
Console.WriteLine(a.RotateRight(r).ToArray().First());
Console.WriteLine(a.RotateRight(-r).ToArray().First());
Console.WriteLine(t.ElapsedMilliseconds); // e.g. 236
}
You can use below code for left Rotation.
List<int> backUpArray = array.ToList();
for (int i = 0; i < array.Length; i++)
{
int newLocation = (i + (array.Length - rotationNumber)) % n;
array[newLocation] = backUpArray[i];
}
You can play nice in .net framework.
I understand that what you want to do is more up to be an iteration behavior than a new collection type; so I would suggest you to try this extension method based on IEnumerable, which will work with Collections, Lists and so on...
class Program
{
static void Main(string[] args)
{
int[] numbers = { 1, 2, 3, 4, 5, 6, 7 };
IEnumerable<int> circularNumbers = numbers.AsCircular();
IEnumerable<int> firstFourNumbers = circularNumbers
.Take(4); // 1 2 3 4
IEnumerable<int> nextSevenNumbersfromfourth = circularNumbers
.Skip(4).Take(7); // 4 5 6 7 1 2 3
}
}
public static class CircularEnumerable
{
public static IEnumerable<T> AsCircular<T>(this IEnumerable<T> source)
{
if (source == null)
yield break; // be a gentleman
IEnumerator<T> enumerator = source.GetEnumerator();
iterateAllAndBackToStart:
while (enumerator.MoveNext())
yield return enumerator.Current;
enumerator.Reset();
if(!enumerator.MoveNext())
yield break;
else
yield return enumerator.Current;
goto iterateAllAndBackToStart;
}
}
Reasonable performance
Flexible
If you want go further, make a CircularList and hold the same enumerator to skip the Skip() when rotating like in your sample.
below is my approach. Thank you
public static int[] RotationOfArray(int[] A, int k)
{
if (A == null || A.Length==0)
return null;
int[] result =new int[A.Length];
int arrayLength=A.Length;
int moveBy = k % arrayLength;
for (int i = 0; i < arrayLength; i++)
{
int tmp = i + moveBy;
if (tmp > arrayLength-1)
{
tmp = + (tmp - arrayLength);
}
result[tmp] = A[i];
}
return result;
}
public static int[] RightShiftRotation(int[] a, int times) {
int[] demo = new int[a.Length];
int d = times,i=0;
while(d>0) {
demo[d-1] = a[a.Length - 1 - i]; d = d - 1; i = i + 1;
}
for(int j=a.Length-1-times;j>=0;j--) { demo[j + times] = a[j]; }
return demo;
}
Using Linq,
List<int> temp = new List<int>();
public int[] solution(int[] array, int range)
{
int tempLength = array.Length - range;
temp = array.Skip(tempLength).ToList();
temp.AddRange(array.Take(array.Length - range).ToList());
return temp.ToArray();
}
If you're working with a string you can do this quite efficiently using ReadOnlySpans:
ReadOnlySpan<char> apiKeySchema = "12345";
const int apiKeyLength = 5;
for (int i = 0; i < apiKeyLength; i++)
{
ReadOnlySpan<char> left = apiKeySchema.Slice(start: i, length: apiKeyLength - i);
ReadOnlySpan<char> right = apiKeySchema.Slice(start: 0, length: i);
Console.WriteLine(string.Concat(left, right));
}
Output:
12345
23451
34512
45123
51234
I was asked to reverse a character array with minimal memory usage.
char[] charArray = new char[]{'C','o','w','b','o','y'};
Method:
static void Reverse(ref char[] s)
{
for (int i=0; i < (s.Length-i); i++)
{
char leftMost = s[i];
char rightMost = s[s.Length - i - 1];
s[i] = rightMost;
s[s.Length - i - 1] = leftMost;
}
}
How about using modular arithmetic :
public void UsingModularArithmetic()
{
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int k = Convert.ToInt32(tokens_n[1]);
int[] a = new int[n];
for(int i = 0; i < n; i++)
{
int newLocation = (i + (n - k)) % n;
a[newLocation] = Convert.ToInt32(Console.ReadLine());
}
foreach (int i in a)
Console.Write("{0} ", i);
}
So basically adding the values to the array when I am reading from console.

What optimization is the compiler doing for my string reverse method with a classic swapping?

Question Background
I read this question that is about how to reverse a string as fast as possible. I found that one of the answers was comparing different methods. In one of them, they just run a loop swapping elements from position i with the one at position string.Length-1-i but they use the known tricky swap via XOR. I was wondering how faster is reversing the string using the swap via XOR in comparison with the same method using the classic swap via a temporal variable. Surprisingly I'm getting almost a 50% improvement over the XOR one.
The Question
Is the compiler doing something magic behind the scenes, why I'm I getting this result?
The modified code with the Benchmarks
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ContestLibrary
{
public class Problem
{
delegate string StringDelegate(string s);
static void Benchmark(string description, StringDelegate d, int times, string text)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int j = 0; j < times; j++)
{
d(text);
}
sw.Stop();
Console.WriteLine("{0} Ticks {1} : called {2} times.", sw.ElapsedTicks, description, times);
}
public static string ReverseXor(string s)
{
char[] charArray = s.ToCharArray();
int len = s.Length - 1;
for (int i = 0; i < len; i++, len--)
{
charArray[i] ^= charArray[len];
charArray[len] ^= charArray[i];
charArray[i] ^= charArray[len];
}
return new string(charArray);
}
public static string ReverseClassic(string s)
{
char[] charArray = s.ToCharArray();
int len = s.Length-1;
for (int i = 0; i < len; i++, len--)
{
char temp = charArray[len];
charArray[len] = charArray[i];
charArray[i] = temp;
}
return new string(charArray);
}
public static string StringOfLength(int length)
{
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++)
{
sb.Append(Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))));
}
return sb.ToString();
}
static void Main(string[] args)
{
int[] lengths = new int[] {1,10,100,1000, 10000, 100000};
foreach (int l in lengths)
{
int iterations = 10000;
string text = StringOfLength(l);
Benchmark(String.Format("Classic (Length: {0})", l), ReverseClassic, iterations, text);
Benchmark(String.Format("Xor (Length: {0})", l), ReverseXor, iterations, text);
Console.WriteLine();
}
Console.Read();
}
}
}
The reason is very simple, lets check how many operations in IL code each function has.
But first, lets see the real difference in time of both functions. You said that the XOR function is almost 50% slower than the other, when I run the code in Debug mode I have that results, but you must run the code in Release mode to fully allow the optimizer do its job :). In release mode the XOR functions is almost 3x slower.
The pictures have the IL code of the part inside the for loop, that is the only piece that changes.
The first picture is the function with the temp variable
The second picture is the function with the XOR
As you can see the difference in the number of instructions is huge, 14 against 34. The 3x difference in time come from some operations like conv.u2 that are a little expensive.
I agree with Harold. XOR swap is not faster than using a temporary variable.
I think that the myth of XOR swap dates back to the days where allocating memory for new variables was a time consuming job.
Initially I thought there is a chance that this might have something to do with the type, and maybe using XOR swap in int arrays would give a better results than on char arrays, so I've built upon your benchmark one for int arrays just to text - turns out the same results (more or less) for int XOR swap is just slower than using a temporary variable.
Update:
As Damien_The_Unbeliever wrote in his comment to your question, The answer given by R. Martinho Fernandes in the question you've linked to is actually the only answer in the first page that correctly reverse a string, even with languages other then English.
In fact, Based on that answer and one of it's comments I've written an extension method to correctly reverse a string.
In my native language (Hebrew) we have all kinds of dots and symbols to specify vowels, and the simple reverse of an array (or IEnumerable) is doing it wrong, just like in the French example.
It's significantly slower than the regular swap based implementation (And about 10 times slower than the XOR based swap), but I hardly think that's going to be an issue, since reversing a string is not something you do very often, and reversing many strings in a tight loop even less.
Tested based on your benchmark method, reversing 10,000 string of length 10,000 with this method took approximately 13.5 seconds.
If anyone would ever write a program that actually needs to do so many reverses for such long strings, I would be very surprised.
So here is my international safe string reverse implementation, I hope someone would benefit from it:
public static string Reverse(this string source)
{
if (string.IsNullOrEmpty(source))
{
return source;
}
var info = new StringInfo(source);
var sb = new StringBuilder();
for (int i = info.LengthInTextElements - 1; i > -1; i--)
{
sb.Append(info.SubstringByTextElements(i, 1));
}
return sb.ToString();
}
You can test below code with Array.Reverse, It will more efficient than other approaches which you are mentioned, Array.Reverse is coded natively and it is very simple to maintain and understand.
public static string ReverseArray(string text)
{
if (text == null) return null;
char[] array = text.ToCharArray();
Array.Reverse(array);
return new String(array);
}
Below is a complete code to demonstrate,
delegate string StringDelegate(string s);
static void Benchmark(string description, StringDelegate d, int times, string text)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int j = 0; j < times; j++)
{
d(text);
}
sw.Stop();
Console.WriteLine("{0} Ticks {1} : called {2} times.", sw.ElapsedTicks, description, times);
}
public static string ReverseArray(string text)
{
if (text == null) return null;
// this was posted by petebob as well
char[] array = text.ToCharArray();
Array.Reverse(array);
return new String(array);
}
public static string ReverseXor(string s)
{
char[] charArray = s.ToCharArray();
int len = s.Length - 1;
for (int i = 0; i < len; i++, len--)
{
charArray[i] ^= charArray[len];
charArray[len] ^= charArray[i];
charArray[i] ^= charArray[len];
}
return new string(charArray);
}
public static string ReverseClassic(string s)
{
char[] charArray = s.ToCharArray();
int len = s.Length-1;
for (int i = 0; i < len; i++, len--)
{
char temp = charArray[len];
charArray[len] = charArray[i];
charArray[i] = temp;
}
return new string(charArray);
}
public static string StringOfLength(int length)
{
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++)
{
sb.Append(Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))));
}
return sb.ToString();
}
static void Main(string[] args)
{
int[] lengths = new int[] { 1, 10, 100, 1000, 10000, 100000 };
foreach (int l in lengths)
{
int iterations = 10000;
string text = StringOfLength(l);
Benchmark(String.Format("Classic (Length: {0})", l), ReverseClassic, iterations, text);
Benchmark(String.Format("Array (Length: {0})", l), ReverseArray, iterations, text);
Benchmark(String.Format("Xor (Length: {0})", l), ReverseXor, iterations, text);
Console.WriteLine();
}
Console.Read();
}
Note: I have corrected your code for reversing the string, it was not correctly reverse the string as your post

Most efficient way to parse a dynamic List of int from string

Out of curiosity, is there a faster/more efficient way to parse a dynamic list of ints from a string?
Currently I have this, and it works absolutely fine; I was just thinking there might be a better way as this seems a little overly complex for something so simple.
public static void Send(string providerIDList)
{
String[] providerIDArray = providerIDList.Split('|');
var providerIDs = new List<int>();
for (int counter = 0; counter < providerIDArray.Count(); counter++)
{
providerIDs.Add(int.Parse(providerIDArray[counter].ToString()));
}
//do some stuff with the parsed list of int
Edit: Perhaps I should have said a more simple way to parse out my list from the string. But since the original question did state faster and more efficient the chosen answer will reflect that.
There's definitely a better way. Use LINQ:
var providerIDs = providerIDList.Split('|')
.Select(x => int.Parse(x))
.ToList();
Or using a method group conversion instead of a lambda expression:
var providerIDs = providerIDList.Split('|')
.Select(int.Parse)
.ToList();
This is not the most efficient way it can be done, but it's quite possibly the simplest. It's about as efficient as your approach - though that could be made slightly more efficient fairly easily, e.g. giving the List an initial capacity.
The difference in performance is likely to be irrelevant, so I'd stick with this simple code until you've got evidence that it's a bottleneck.
Note that if you don't need a List<int> - if you just need something you can iterate over once - you can kill the ToList call and use providerIDs as an IEnumerable<int>.
EDIT: If we're in the efficiency business, then here's an adaptation of the ForEachChar method, to avoid using int.Parse:
public static List<int> ForEachCharManualParse(string s, char delim)
{
List<int> result = new List<int>();
int tmp = 0;
foreach(char x in s)
{
if(x == delim)
{
result.Add(tmp);
tmp = 0;
}
else if (x >= '0' && x <= '9')
{
tmp = tmp * 10 + x - '0';
}
else
{
throw new ArgumentException("Invalid input: " + s);
}
}
result.Add(tmp);
return result;
}
Notes:
This will add zeroes for any consecutive delimiters, or a delimiter at the start or end
It doesn't handle negative numbers
It doesn't check for overflow
As noted in comments, using a switch statement instead of the x >= '0' && x <= '9' can improve the performance further (by about 10-15%)
If none of those are a problem for you, it's about 7x faster than ForEachChar on my machine:
ListSize 1000 : StringLen 10434
ForEachChar1000 Time : 00:00:02.1536651
ForEachCharManualParse1000 Time : 00:00:00.2760543
ListSize 100000 : StringLen 1048421
ForEachChar100000 Time : 00:00:02.2169482
ForEachCharManualParse100000 Time : 00:00:00.3087568
ListSize 10000000 : StringLen 104829611
ForEachChar10000000 Time : 00:00:22.0803706
ForEachCharManualParse10000000 Time : 00:00:03.1206769
The limitations can be worked around, but I haven't bothered... let me know if they're significant concerns for you.
I don't like any of the answers so far. So to actually answer the question the OP posed "fastest/most efficient" String.Split with Int.Parse, I wrote and tested some code.
Using Mono on an Intel 3770k.
I found that using String.Split + IEnum.Select is not the fastest (maybe the prettiest) solution. In fact it's the slowest.
Here's some benchmark results
ListSize 1000 : StringLen 10468
SplitForEach1000 Time : 00:00:02.8704048
SplitSelect1000 Time : 00:00:02.9134658
ForEachChar1000 Time : 00:00:01.8254438
SplitParallelSelectr1000 Time : 00:00:07.5421146
ForParallelForEachChar1000 Time : 00:00:05.3534218
ListSize 100000 : StringLen 1048233
SplitForEach100000 Time : 00:00:01.9500846
SplitSelect100000 Time : 00:00:02.2662606
ForEachChar100000 Time : 00:00:01.2554577
SplitParallelSelectr100000 Time : 00:00:02.6509969
ForParallelForEachChar100000 Time : 00:00:01.5842131
ListSize 10000000 : StringLen 104824707
SplitForEach10000000 Time : 00:00:18.2658261
SplitSelect10000000 Time : 00:00:20.6043874
ForEachChar10000000 Time : 00:00:10.0555613
SplitParallelSelectr10000000 Time : 00:00:18.1908017
ForParallelForEachChar10000000 Time : 00:00:08.6756213
Here's the code to get the benchmark results
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
namespace FastStringSplit
{
class MainClass
{
public static void Main (string[] args)
{
Random rnd = new Random();
char delim = ':';
int[] sizes = new int[]{1000, 100000, 10000000 };
int[] iters = new int[]{10000, 100, 10};
Stopwatch sw;
List<int> list, result = new List<int>();
string str;
for(int s=0; s<sizes.Length; s++) {
list = new List<int>(sizes[s]);
for(int i=0; i<sizes[s]; i++)
list.Add (rnd.Next());
str = string.Join(":", list);
Console.WriteLine(string.Format("\nListSize {0} : StringLen {1}", sizes[s], str.Length));
////
sw = new Stopwatch();
for(int i=0; i<iters[s]; i++) {
sw.Start();
result = SplitForEach(str, delim);
sw.Stop();
}
Console.WriteLine("SplitForEach" + result.Count + " Time : " + sw.Elapsed.ToString());
////
sw = new Stopwatch();
for(int i=0; i<iters[s]; i++) {
sw.Start();
result = SplitSelect(str, delim);
sw.Stop();
}
Console.WriteLine("SplitSelect" + result.Count + " Time : " + sw.Elapsed.ToString());
////
sw = new Stopwatch();
for(int i=0; i<iters[s]; i++) {
sw.Start();
result = ForEachChar(str, delim);
sw.Stop();
}
Console.WriteLine("ForEachChar" + result.Count + " Time : " + sw.Elapsed.ToString());
////
sw = new Stopwatch();
for(int i=0; i<iters[s]; i++) {
sw.Start();
result = SplitParallelSelect(str, delim);
sw.Stop();
}
Console.WriteLine("SplitParallelSelectr" + result.Count + " Time : " + sw.Elapsed.ToString());
////
sw = new Stopwatch();
for(int i=0; i<iters[s]; i++) {
sw.Start();
result = ForParallelForEachChar(str, delim);
sw.Stop();
}
Console.WriteLine("ForParallelForEachChar" + result.Count + " Time : " + sw.Elapsed.ToString());
}
}
public static List<int> SplitForEach(string s, char delim) {
List<int> result = new List<int>();
foreach(string x in s.Split(delim))
result.Add(int.Parse (x));
return result;
}
public static List<int> SplitSelect(string s, char delim) {
return s.Split(delim)
.Select(int.Parse)
.ToList();
}
public static List<int> ForEachChar(string s, char delim) {
List<int> result = new List<int>();
int start = 0;
int end = 0;
foreach(char x in s) {
if(x == delim || end == s.Length - 1) {
if(end == s.Length - 1)
end++;
result.Add(int.Parse (s.Substring(start, end-start)));
start = end + 1;
}
end++;
}
return result;
}
public static List<int> SplitParallelSelect(string s, char delim) {
return s.Split(delim)
.AsParallel()
.Select(int.Parse)
.ToList();
}
public static int NumOfThreads = Environment.ProcessorCount > 2 ? Environment.ProcessorCount : 2;
public static List<int> ForParallelForEachChar(string s, char delim) {
int chunkSize = (s.Length / NumOfThreads) + 1;
ConcurrentBag<int> result = new ConcurrentBag<int>();
int[] chunks = new int[NumOfThreads+1];
Task[] tasks = new Task[NumOfThreads];
for(int x=0; x<NumOfThreads; x++) {
int next = chunks[x] + chunkSize;
while(next < s.Length) {
if(s[next] == delim)
break;
next++;
}
//Console.WriteLine(next);
chunks[x+1] = Math.Min(next, s.Length);
tasks[x] = Task.Factory.StartNew((o) => {
int chunkId = (int)o;
int start = chunks[chunkId];
int end = chunks[chunkId + 1];
if(start >= s.Length)
return;
if(s[start] == delim)
start++;
//Console.WriteLine(string.Format("{0} {1}", start, end));
for(int i = start; i<end; i++) {
if(s[i] == delim || i == end-1) {
if(i == end-1)
i++;
result.Add(int.Parse (s.Substring(start, i-start)));
start = i + 1;
}
}
}, x);
}
Task.WaitAll(tasks);
return result.ToList();
}
}
}
Here's the function I recommend
public static List<int> ForEachChar(string s, char delim) {
List<int> result = new List<int>();
int start = 0;
int end = 0;
foreach(char x in s) {
if(x == delim || end == s.Length - 1) {
if(end == s.Length - 1)
end++;
result.Add(int.Parse (s.Substring(start, end-start)));
start = end + 1;
}
end++;
}
return result;
}
Why it's faster?
It doesn't split the string into an array first. It does the splitting and parsing at the same time so there is no added overhead of iterating over the string to split it and then iterating over the array to parse it.
I also threw in a parallel-ized version using tasks, but it is only faster in the case with very large strings.
This appears cleaner:
var providerIDs = providerIDList.Split('|').Select(x => int.Parse(x)).ToList();
if you really want to know the most efficent way, then use unsafe code, define char pointer from string, iterate all chars incrementing char pointer, buffer read chars until the next '|', convert buffered chars to int32. if you want to be really fast then do it manually (begin with last char, substruct value of '0' char, multiply it 10, 100, 1000... accoring to iteration variable, then add it to the sum variable. i dont have time to write code but hopefully you get the idea

Easiest way to Rotate a List in c#

Lists say I have a list List<int> {1,2,3,4,5}
Rotate means:
=> {2,3,4,5,1} => {3,4,5,1,2} => {4,5,1,2,3}
Maybe rotate is not the best word for this, but hope you understand what I means
My question, whats the easiest way (in short code, c# 4 Linq ready), and will not be hit by performance (reasonable performance)
Thanks.
List<T>
The simplest way (for a List<T>) is to use:
int first = list[0];
list.RemoveAt(0);
list.Add(first);
Performance is nasty though - O(n).
Array
This is basically equivalent to the List<T> version, but more manual:
int first = array[0];
Array.Copy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = first;
LinkedList<T>
If you could use a LinkedList<T> instead, that would be much simpler:
int first = linkedList.First;
linkedList.RemoveFirst();
linkedList.AddLast(first);
This is O(1) as each operation is constant time.
Queue<T>
cadrell0's solution of using a queue is a single statement, as Dequeue removes the element and returns it:
queue.Enqueue(queue.Dequeue());
While I can't find any documentation of the performance characteristic of this, I'd expect Queue<T> to be implemented using an array and an index as the "virtual starting point" - in which case this is another O(1) solution.
Note that in all of these cases you'd want to check for the list being empty first. (You could deem that to be an error, or a no-op.)
You could implement it as a queue. Dequeue and Enqueue the same value.
**I wasn't sure about performance in converting a List to a Queue, but people upvoted my comment, so I'm posting this as an answer.
I use this one:
public static List<T> Rotate<T>(this List<T> list, int offset)
{
return list.Skip(offset).Concat(list.Take(offset)).ToList();
}
It seems like some answerers have treated this as a chance to explore data structures. While those answers are informative and useful, they are not very Linq'ish.
The Linq'ish approach is: You get an extension method which returns a lazy IEnumerable that knows how to build what you want. This method doesn't modify the source and should only allocate a copy of the source if necessary.
public static IEnumerable<IEnumerable<T>> Rotate<T>(this List<T> source)
{
for(int i = 0; i < source.Count; i++)
{
yield return source.TakeFrom(i).Concat(source.TakeUntil(i));
}
}
//similar to list.Skip(i-1), but using list's indexer access to reduce iterations
public static IEnumerable<T> TakeFrom<T>(this List<T> source, int index)
{
for(int i = index; i < source.Count; i++)
{
yield return source[i];
}
}
//similar to list.Take(i), but using list's indexer access to reduce iterations
public static IEnumerable<T> TakeUntil<T>(this List<T> source, int index)
{
for(int i = 0; i < index; i++)
{
yield return source[i];
}
}
Used as:
List<int> myList = new List<int>(){1, 2, 3, 4, 5};
foreach(IEnumerable<int> rotation in myList.Rotate())
{
//do something with that rotation
}
How about this:
var output = input.Skip(rot)
.Take(input.Count - rot)
.Concat(input.Take(rot))
.ToList();
Where rot is the number of spots to rotate - which must be less than the number of elements in the input list.
As #cadrell0 answer shows if this is all you do with your list, you should use a queue instead of a list.
My solution maybe too basic (I wouldn't like to say it's lame...) and not LINQ'ish.
However, it has a pretty good performance.
int max = 5; //the fixed size of your array.
int[] inArray = new int[5] {0,0,0,0,0}; //initial values only.
void putValueToArray(int thisData)
{
//let's do the magic here...
Array.Copy(inArray, 1, inArray, 0, max-1);
inArray[max-1] = thisData;
}
Try
List<int> nums = new List<int> {1,2,3,4,5};
var newNums = nums.Skip(1).Take(nums.Count() - 1).ToList();
newNums.Add(nums[0]);
Although, I like Jon Skeet's answer better.
My solution for Arrays:
public static void ArrayRotate(Array data, int index)
{
if (index > data.Length)
throw new ArgumentException("Invalid index");
else if (index == data.Length || index == 0)
return;
var copy = (Array)data.Clone();
int part1Length = data.Length - index;
//Part1
Array.Copy(copy, 0, data, index, part1Length);
//Part2
Array.Copy(copy, part1Length, data, 0, index);
}
I've used the following extensions for this:
static class Extensions
{
public static IEnumerable<T> RotateLeft<T>(this IEnumerable<T> e, int n) =>
n >= 0 ? e.Skip(n).Concat(e.Take(n)) : e.RotateRight(-n);
public static IEnumerable<T> RotateRight<T>(this IEnumerable<T> e, int n) =>
e.Reverse().RotateLeft(n).Reverse();
}
They're certainly easy (OP title request), and they've got reasonable performance (OP write-up request). Here's a little demo I ran in LINQPad 5 on an above-average-powered laptop:
void Main()
{
const int n = 1000000;
const int r = n / 10;
var a = Enumerable.Range(0, n);
var t = Stopwatch.StartNew();
Console.WriteLine(a.RotateLeft(r).ToArray().First());
Console.WriteLine(a.RotateLeft(-r).ToArray().First());
Console.WriteLine(a.RotateRight(r).ToArray().First());
Console.WriteLine(a.RotateRight(-r).ToArray().First());
Console.WriteLine(t.ElapsedMilliseconds); // e.g. 236
}
You can use below code for left Rotation.
List<int> backUpArray = array.ToList();
for (int i = 0; i < array.Length; i++)
{
int newLocation = (i + (array.Length - rotationNumber)) % n;
array[newLocation] = backUpArray[i];
}
You can play nice in .net framework.
I understand that what you want to do is more up to be an iteration behavior than a new collection type; so I would suggest you to try this extension method based on IEnumerable, which will work with Collections, Lists and so on...
class Program
{
static void Main(string[] args)
{
int[] numbers = { 1, 2, 3, 4, 5, 6, 7 };
IEnumerable<int> circularNumbers = numbers.AsCircular();
IEnumerable<int> firstFourNumbers = circularNumbers
.Take(4); // 1 2 3 4
IEnumerable<int> nextSevenNumbersfromfourth = circularNumbers
.Skip(4).Take(7); // 4 5 6 7 1 2 3
}
}
public static class CircularEnumerable
{
public static IEnumerable<T> AsCircular<T>(this IEnumerable<T> source)
{
if (source == null)
yield break; // be a gentleman
IEnumerator<T> enumerator = source.GetEnumerator();
iterateAllAndBackToStart:
while (enumerator.MoveNext())
yield return enumerator.Current;
enumerator.Reset();
if(!enumerator.MoveNext())
yield break;
else
yield return enumerator.Current;
goto iterateAllAndBackToStart;
}
}
Reasonable performance
Flexible
If you want go further, make a CircularList and hold the same enumerator to skip the Skip() when rotating like in your sample.
below is my approach. Thank you
public static int[] RotationOfArray(int[] A, int k)
{
if (A == null || A.Length==0)
return null;
int[] result =new int[A.Length];
int arrayLength=A.Length;
int moveBy = k % arrayLength;
for (int i = 0; i < arrayLength; i++)
{
int tmp = i + moveBy;
if (tmp > arrayLength-1)
{
tmp = + (tmp - arrayLength);
}
result[tmp] = A[i];
}
return result;
}
public static int[] RightShiftRotation(int[] a, int times) {
int[] demo = new int[a.Length];
int d = times,i=0;
while(d>0) {
demo[d-1] = a[a.Length - 1 - i]; d = d - 1; i = i + 1;
}
for(int j=a.Length-1-times;j>=0;j--) { demo[j + times] = a[j]; }
return demo;
}
Using Linq,
List<int> temp = new List<int>();
public int[] solution(int[] array, int range)
{
int tempLength = array.Length - range;
temp = array.Skip(tempLength).ToList();
temp.AddRange(array.Take(array.Length - range).ToList());
return temp.ToArray();
}
If you're working with a string you can do this quite efficiently using ReadOnlySpans:
ReadOnlySpan<char> apiKeySchema = "12345";
const int apiKeyLength = 5;
for (int i = 0; i < apiKeyLength; i++)
{
ReadOnlySpan<char> left = apiKeySchema.Slice(start: i, length: apiKeyLength - i);
ReadOnlySpan<char> right = apiKeySchema.Slice(start: 0, length: i);
Console.WriteLine(string.Concat(left, right));
}
Output:
12345
23451
34512
45123
51234
I was asked to reverse a character array with minimal memory usage.
char[] charArray = new char[]{'C','o','w','b','o','y'};
Method:
static void Reverse(ref char[] s)
{
for (int i=0; i < (s.Length-i); i++)
{
char leftMost = s[i];
char rightMost = s[s.Length - i - 1];
s[i] = rightMost;
s[s.Length - i - 1] = leftMost;
}
}
How about using modular arithmetic :
public void UsingModularArithmetic()
{
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int k = Convert.ToInt32(tokens_n[1]);
int[] a = new int[n];
for(int i = 0; i < n; i++)
{
int newLocation = (i + (n - k)) % n;
a[newLocation] = Convert.ToInt32(Console.ReadLine());
}
foreach (int i in a)
Console.Write("{0} ", i);
}
So basically adding the values to the array when I am reading from console.

Refactoring Fibonacci Algorithm

I haven't used a statically typed language in many years and have set myself the task of getting up to speed with C#. I'm using my usual trick of following the fifteen exercises here http://www.jobsnake.com/seek/articles/index.cgi?openarticle&8533 as my first task.
I've just finished the second Fibonacci task which didn't take to long and works just fine but in my opinion looks ugly and I'm sure could be achieved in far fewer lines of more elegant code.
I usually like to learn by pair programming with someone who already knows what they're doing, but that option isn't open to me today, so I'm hoping posting here will be the next best thing.
So to all the C# Jedi's out there, if you were going to refactor the code below, what would it look like?
using System;
using System.Collections;
namespace Exercises
{
class MainClass
{
public static void Main(string[] args)
{
Console.WriteLine("Find all fibinacci numbers between:");
int from = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("And:");
int to = Convert.ToInt32(Console.ReadLine());
Fibonacci fibonacci = new Fibonacci();
fibonacci.PrintArrayList(fibonacci.Between(from, to));
}
}
class Fibonacci
{
public ArrayList Between(int from, int to)
{
int last = 1;
int penultimate = 0;
ArrayList results = new ArrayList();
results.Add(penultimate);
results.Add(last);
while(last<to)
{
int fib = last + penultimate;
penultimate = last;
last = fib;
if (fib>from && fib<to) results.Add(fib.ToString());
}
return results;
}
public void PrintArrayList(ArrayList arrayList)
{
Console.WriteLine("Your Fibonacci sequence:");
Console.Write(arrayList[0]);
for(int i = 1; i<arrayList.Count; i++)
{
Console.Write("," + arrayList[i]);
}
Console.WriteLine("");
}
}
}
Regards,
Chris
As an iterator block:
using System;
using System.Collections.Generic;
using System.Linq;
static class Program {
static IEnumerable<long> Fibonacci() {
long n = 0, m = 1;
yield return 0;
yield return 1;
while (true) {
long tmp = n + m;
n = m;
m = tmp;
yield return m;
}
}
static void Main() {
foreach (long i in Fibonacci().Take(10)) {
Console.WriteLine(i);
}
}
}
This is now fully lazy, and using LINQ's Skip/Take etc allows you to control the start/end easily. For example, for your "between" query:
foreach (long i in Fibonacci().SkipWhile(x=>x < from).TakeWhile(x=>x <= to)) {...}
If you prefer recursion instead of the loop:
public static void Main(string[] args)
{
Func<int, int> fib = null;
fib = n => n > 1 ? fib(n - 1) + fib(n - 2) : n;
int start = 1;
int end = 10;
var numbers = Enumerable.Range(start, end).Select(fib);
foreach (var number in numbers)
{
Console.WriteLine(number);
}
}
I would change the IEnumerable<int> type to IEnumerable<Int64> as it will start to overflow from 50
For those who haven't yielded to Linq-ed in like me, the 'Simple Jack' Version. i'm SO banned out of the Jedi club ;)
static List<int> GetAllFibonacciNumbersUpto(int y)
{
List<int> theFibonacciSeq = new List<int>();
theFibonacciSeq.Add(0); theFibonacciSeq.Add(1);
int F_of_n_minus_2 = 0; int F_of_n_minus_1 = 1;
while (F_of_n_minus_2 <= y)
{
theFibonacciSeq.Add(F_of_n_minus_1 + F_of_n_minus_2);
F_of_n_minus_2 = F_of_n_minus_1;
F_of_n_minus_1 = theFibonacciSeq.Last<int>();
}
return theFibonacciSeq;
}
now that we have that out of the way...
// read in some limits
int x = 0; int y = 6785;
foreach (int iNumber in GetAllFibonacciNumbersUpto(y).FindAll(element => (element >= x) && (element <= y)))
Console.Write(iNumber + ",");
Console.WriteLine();

Categories

Resources