I am trying to find index of an array.Probably doing this is easy but I couldn't do that.I tried to add a function(findIndex),looking at a website but I am getting an error.How can I find the index?
namespace exmple.Filters
{
class dnm2
{
public static byte[] Shape(byte[] data)
{
byte[] shape = new byte[data.Length];
byte count = 0;
for (int i = 0; i < data.Length; i++)
{
if (data[i] == 0)
{
shape[i] = (data[i]);
int index = shape.findIndex(count);
int[] a = {1, 2, 3};
int index = a.Indexof((int)3);
count += 1;
}
}
return shape;
}
public static int findIndex<T>(this T[] array, T item)
{
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < array.Length; i++)
{
if (comparer.Equals(array[i], item)) {
return i;
}
}
return -1;
}
}
Array.IndexOf() gives you the index of an object in an array. Just make sure you use the same data types, i.e. byte here.
This is the full code, tested in .NET 4.5.2
using System;
namespace ConsoleApp2
{
class Program
{
static void Main()
{
byte[] data = { 5, 4, 3, 2, 1 };
Console.WriteLine(Array.IndexOf(data, (byte)2));
Console.ReadLine();
}
}
}
Alternate way is to use Array.FindIndex(array, predicate)
var zeroBasedIndex = Array.FindIndex(data, x => x == (byte)2);
Not sure what you are trying to do but I have fixed your code.
namespace Exmple.Filters
{
public static class DNM
{
public static byte[] Shape(byte[] data)
{
byte[] shape = new byte[data.Length];
byte count = 0;
for (int i = 0; i < data.Length; i++)
{
if (data[i] == 0)
{
shape[i] = (data[i]);
int index = shape.FindIndex1(count);
int[] a = { 1, 2, 3 };
int index1 = Array.IndexOf(a, (int)3);
count += 1;
}
}
return shape;
}
public static int FindIndex1(this byte[] array, byte item)
{
EqualityComparer<byte> comparer = EqualityComparer<byte>.Default;
for (int i = 0; i < array.Length; i++)
{
if (comparer.Equals(array[i], item))
{
return i;
}
}
return -1;
}
}
}
there were few issues in your code
Naming rule violations
byte[] already has an FindIndex so compiler was getting confused which one to use (I just removed the generic things and changed the name)
array object doesn't have a IndexOf Method, Array class has a method.
Related
this is the problem [enter image description here][1]
class Program
{
/* I 'am sorry, but if written this code in french so I will explain the name of variables in English, and what are they doing
and Yes I am aware this code is spaghetti and I would appreciate if there is a better way to write it
T is an Array, and cible is a target */
public static int [] getRange(int[] T, int cible)
{
// T_indices is an Array of indexes
int[] T_indices = new int[10];
//cpt is a counting variable
int cpt=0;
for (int i = 0; i < T.Length; i++)
{
if(T[i]==cible)
{
for (int j = i; j < T.Length; j++)
{
if(T[i]==T[j])
{
T_indices[cpt] = j;
cpt++;
}
else
{
break;
}
}
break;
}
}
//checking if the element doesn't existe so we can return a -1
if(cpt==0)
{
T_indices = new int[1];
T_indices[0] = -1;
return T_indices;
}
else
{
//T_indices_Finaux is the final index Array
int[] T_indices_Finaux = new int[2];
T_indices_Finaux[0] = T_indices[0];
// Max doesn't need explanation I guess
int max = T_indices[0];
for (int i = 0; i < T_indices.Length; i++)
{
if(max< T_indices[i])
{
max = T_indices[i];
}
}
T_indices_Finaux[1] = max;
if(T_indices_Finaux[0]== T_indices_Finaux[1])
{
T_indices_Finaux = new int[1];
T_indices_Finaux[0] = T_indices[0];
}
return T_indices_Finaux;
}
}
// here we put this spaghetti code to the test suprisenly wroking out
static void Main(string[] args)
{
int[] T = { 1, 2, 2, 2, 2, 3, 4, 7, 8, 8 };
for (int i = 0; i < getRange(T, 2).Length; i++)
{
Console.WriteLine(getRange(T, 2)[i]);
}
Console.Read();
}
}
int[] T_indices = new int[10];
How do you know, that 10 is enough? You do not. This magic number would cause, that the code sometimes works and sometimes it just throws out of range exception. Besides this, the code is okay, but you do it in a bit too complicated way. What you need is basically this
public static int[] getRange(int[] T, int cible)
{
for (int i = 0; i < T.Length; ++i)
{
if (T[i] == cible)
{
int j = i + 1;
while (j < T.Length && T[j] == cible) { ++j; }
--j;
if (i == j) { return new int[] { i }; }
return new int[] { i, j };
}
}
return new int[] { -1 };
}
And btw. the test code calls the getRange function up to three times. You should call it once, store the result array and loop over that array.
pleas try this :
change getRange Method to this :
public static List<int> getRange(int[] T, int cible)
{
var result=new List<int>();
var list = T.ToList();
if(!list.Contains(cible))
result.Add(-1);
else
{
result.Add(list.IndexOf(cible));
if (list.Count(x=>x==cible)>1)
result.Add(list.LastIndexOf(cible));
}
return result;
}
and use it like this :
int[] T = { 1, 2, 2, 2, 2, 3, 4, 7, 8, 8 };
getRange(T, 2).ForEach(Console.WriteLine);
In this solution you will never get an OutOfRange ٍException and also use the native c # method (for get index of a item in array. "IndexOf" Instead "for") which is much faster and more efficient.
I have an issue with the following one :
Create a function named divisors/Divisors that takes an integer and returns an array with all of the integer's divisors(except for 1 and the number itself). If the number is prime return the string '(integer) is prime' (null in C#) (use Either String a in Haskell and Result, String> in Rust).
My code:
static int[] divisors(int a)
{
int[] array = new int[a];
int x = 0;
for( int i =2; i<a; i++)
{
if(a % i == 0)
{
array[x] = i;
x++;
}
}
if(array.Length == 0)
{
return null;
}
else
{
return array;
}
}
When I try to run it, it throws :
"Expected is <System.Int32[2]>, actual is <System.Int32[15]>
Values differ at index [2]
Extra: < 0, 0, 0... >"
Not sure what to do with this one.
I'd really appreciate some help.
The sollution :
using System.Collections.Generic;
public class Kata
{
public static int[] Divisors(int n)
{
List<int> numbers = new List<int>();
for (int i = 2; i < n; i++)
{
if (n % i == 0)
{
numbers.Add (i);
}
}
if (numbers.Count == 0)
{
return null;
}
else
{
int[] array = new int[numbers.Count];
array =numbers.ToArray();
return array;
}
}
}
I did not get that error with your code; however, your function will not return null because you have determined the Length of your array as a. So the length will never be zero. You get all those zeros because value types initialize for you. Your int array filled up with zeros. I think this excercise should prove to you that a different collection type would be more suited to data that needs to be dynamicly resized but if you are required to stick to arrays, here is some code that does.
static int[] divisors(int a)
{
int x = 0;
int[] array = new int[x];
for (int i = 2; i < a; i++)
{
if (a % i == 0)
{
x++;
Array.Resize<int>(ref array, x);
array[x-1] = i;
}
}
if (array.Length == 0)
return null;
else
return array;
}
private void button1_Click(object sender, EventArgs e)
{
int b = Int32.Parse(textBox1.Text);
int[] a = divisors(b);
if (a == null)
MessageBox.Show($"{b} is a prime number.");
else
{
foreach (int x in a)
{
Debug.Print(x.ToString());
}
}
}
If there are multiple string with same length(max), how do I find out all the indices. I am getting the first index currently. Is there a better way to do this?
using System;
using System.Linq;
namespace Examples
{
class Program
{
static void Main(string[] args)
{
Longestword("Find the largest word with lower index abcdefg ");
Console.ReadKey();
}
private static void Longestword(String sen)
{
String[] sArray = sen.Split(null);
int[] cArr = new int[sArray.Length];
for (int i = 0; i < sArray.Length; i++)
{
int j = sArray[i].Length;
cArr[i] = j;
}
int max = cArr.Max();
int index = cArr.ToList().IndexOf(max);
Console.WriteLine(index);
}
}
}
Here's my stab at a solution:
public static class LinqExtensions
{
public static List<int> IndicesOf(this int[] array, int item)
{
var indices = new List<int>();
for (int i = 0; i < array.Length; i++)
{
if (array[i] == item)
indices.Add(i);
}
return indices;
}
}
You can then call it like this:
int[] someArrayFindMax = new[] { 1, 4, 45, 23, 4, 3342, 34, 3342, 4, 3342, 3342 };
int max = someArrayFindMax.Max();
List<int> indices = someArrayFindMax.IndicesOf(max);
Here's another possible extension method for finding the indices of the longest strings directly:
public static List<int> LongestStringIndices(this string[] strings)
{
int longestString = -1;
var indices = new List<int>();
for (int i = 0; i < strings.Length; i++)
{
if (strings[i].Length > longestString)
{
longestString = strings[i].Length;
// We're no longer interested in the indices of the
// strings we now know to be shorter
indices.Clear();
indices.Add(i);
}
else if (strings[i].Length == longestString)
{
indices.Add(i);
}
// If it's less than the max length so far we ignore it
}
return indices;
}
I'd play with LINQ, as it's the C#-ish way.
Here's a fiddle: https://dotnetfiddle.net/NEFkqb
List<string> words = new List<string>{"aaaa","bb","cccc"};
List<int> lengths = words.Select(word => word.Length).ToList();
int max = lengths.Max();
List<int> maxes = new List<int>();
for(int i = 0; i < lengths.Count; i++)
if(lengths[i] == max)
maxes.Add(i);
I have a list of Offers, from which I want to create "chains" (e.g. permutations) with limited chain lengths.
I've gotten as far as creating the permutations using the Kw.Combinatorics project.
However, the default behavior creates permutations in the length of the list count. I'm not sure how to limit the chain lengths to 'n'.
Here's my current code:
private static List<List<Offers>> GetPerms(List<Offers> list, int chainLength)
{
List<List<Offers>> response = new List<List<Offers>>();
foreach (var row in new Permutation(list.Count).GetRows())
{
List<Offers> innerList = new List<Offers>();
foreach (var mix in Permutation.Permute(row, list))
{
innerList.Add(mix);
}
response.Add(innerList);
innerList = new List<Offers>();
}
return response;
}
Implemented by:
List<List<AdServer.Offers>> lst = GetPerms(offers, 2);
I'm not locked in KWCombinatorics if someone has a better solution to offer.
Here's another implementation which I think should be faster than the accepted answer (and it's definitely less code).
public static IEnumerable<IEnumerable<T>> GetVariationsWithoutDuplicates<T>(IList<T> items, int length)
{
if (length == 0 || !items.Any()) return new List<List<T>> { new List<T>() };
return from item in items.Distinct()
from permutation in GetVariationsWithoutDuplicates(items.Where(i => !EqualityComparer<T>.Default.Equals(i, item)).ToList(), length - 1)
select Prepend(item, permutation);
}
public static IEnumerable<IEnumerable<T>> GetVariations<T>(IList<T> items, int length)
{
if (length == 0 || !items.Any()) return new List<List<T>> { new List<T>() };
return from item in items
from permutation in GetVariations(Remove(item, items).ToList(), length - 1)
select Prepend(item, permutation);
}
public static IEnumerable<T> Prepend<T>(T first, IEnumerable<T> rest)
{
yield return first;
foreach (var item in rest) yield return item;
}
public static IEnumerable<T> Remove<T>(T item, IEnumerable<T> from)
{
var isRemoved = false;
foreach (var i in from)
{
if (!EqualityComparer<T>.Default.Equals(item, i) || isRemoved) yield return i;
else isRemoved = true;
}
}
On my 3.1 GHz Core 2 Duo, I tested with this:
public static void Test(Func<IList<int>, int, IEnumerable<IEnumerable<int>>> getVariations)
{
var max = 11;
var timer = System.Diagnostics.Stopwatch.StartNew();
for (int i = 1; i < max; ++i)
for (int j = 1; j < i; ++j)
getVariations(MakeList(i), j).Count();
timer.Stop();
Console.WriteLine("{0,40}{1} ms", getVariations.Method.Name, timer.ElapsedMilliseconds);
}
// Make a list that repeats to guarantee we have duplicates
public static IList<int> MakeList(int size)
{
return Enumerable.Range(0, size/2).Concat(Enumerable.Range(0, size - size/2)).ToList();
}
Unoptimized
GetVariations 11894 ms
GetVariationsWithoutDuplicates 9 ms
OtherAnswerGetVariations 22485 ms
OtherAnswerGetVariationsWithDuplicates 243415 ms
With compiler optimizations
GetVariations 9667 ms
GetVariationsWithoutDuplicates 8 ms
OtherAnswerGetVariations 19739 ms
OtherAnswerGetVariationsWithDuplicates 228802 ms
You're not looking for a permutation, but for a variation. Here is a possible algorithm. I prefer iterator methods for functions that can potentially return very many elements. This way, the caller can decide if he really needs all elements:
IEnumerable<IList<T>> GetVariations<T>(IList<T> offers, int length)
{
var startIndices = new int[length];
var variationElements = new HashSet<T>(); //for duplicate detection
while (startIndices[0] < offers.Count)
{
var variation = new List<T>(length);
var valid = true;
for (int i = 0; i < length; ++i)
{
var element = offers[startIndices[i]];
if (variationElements.Contains(element))
{
valid = false;
break;
}
variation.Add(element);
variationElements.Add(element);
}
if (valid)
yield return variation;
//Count up the indices
startIndices[length - 1]++;
for (int i = length - 1; i > 0; --i)
{
if (startIndices[i] >= offers.Count)
{
startIndices[i] = 0;
startIndices[i - 1]++;
}
else
break;
}
variationElements.Clear();
}
}
The idea for this algorithm is to use a number in offers.Count base. For three offers, all digits are in the range 0-2. We then basically increment this number step by step and return the offers that reside at the specified indices. If you want to allow duplicates, you can remove the check and the HashSet<T>.
Update
Here is an optimized variant that does the duplicate check on the index level. In my tests it is a lot faster than the previous variant:
IEnumerable<IList<T>> GetVariations<T>(IList<T> offers, int length)
{
var startIndices = new int[length];
for (int i = 0; i < length; ++i)
startIndices[i] = i;
var indices = new HashSet<int>(); // for duplicate check
while (startIndices[0] < offers.Count)
{
var variation = new List<T>(length);
for (int i = 0; i < length; ++i)
{
variation.Add(offers[startIndices[i]]);
}
yield return variation;
//Count up the indices
AddOne(startIndices, length - 1, offers.Count - 1);
//duplicate check
var check = true;
while (check)
{
indices.Clear();
for (int i = 0; i <= length; ++i)
{
if (i == length)
{
check = false;
break;
}
if (indices.Contains(startIndices[i]))
{
var unchangedUpTo = AddOne(startIndices, i, offers.Count - 1);
indices.Clear();
for (int j = 0; j <= unchangedUpTo; ++j )
{
indices.Add(startIndices[j]);
}
int nextIndex = 0;
for(int j = unchangedUpTo + 1; j < length; ++j)
{
while (indices.Contains(nextIndex))
nextIndex++;
startIndices[j] = nextIndex++;
}
break;
}
indices.Add(startIndices[i]);
}
}
}
}
int AddOne(int[] indices, int position, int maxElement)
{
//returns the index of the last element that has not been changed
indices[position]++;
for (int i = position; i > 0; --i)
{
if (indices[i] > maxElement)
{
indices[i] = 0;
indices[i - 1]++;
}
else
return i;
}
return 0;
}
If I got you correct here is what you need
this will create permutations based on the specified chain limit
public static List<List<T>> GetPerms<T>(List<T> list, int chainLimit)
{
if (list.Count() == 1)
return new List<List<T>> { list };
return list
.Select((outer, outerIndex) =>
GetPerms(list.Where((inner, innerIndex) => innerIndex != outerIndex).ToList(), chainLimit)
.Select(perms => (new List<T> { outer }).Union(perms).Take(chainLimit)))
.SelectMany<IEnumerable<IEnumerable<T>>, List<T>>(sub => sub.Select<IEnumerable<T>, List<T>>(s => s.ToList()))
.Distinct(new PermComparer<T>()).ToList();
}
class PermComparer<T> : IEqualityComparer<List<T>>
{
public bool Equals(List<T> x, List<T> y)
{
return x.SequenceEqual(y);
}
public int GetHashCode(List<T> obj)
{
return (int)obj.Average(o => o.GetHashCode());
}
}
and you'll call it like this
List<List<AdServer.Offers>> lst = GetPerms<AdServer.Offers>(offers, 2);
I made this function is pretty generic so you may use it for other purpose too
eg
List<string> list = new List<string>(new[] { "apple", "banana", "orange", "cherry" });
List<List<string>> perms = GetPerms<string>(list, 2);
result
Does code exist, for shifting List elements to left or right by specified amount, in C#?
It is tricky code, it will take some time to write and test special cases, I would rather
reuse something if it exists.
Thanks
Something like this for shift left...
public static void ShiftLeft<T>(List<T> lst, int shifts)
{
for (int i = shifts; i < lst.Count; i++)
{
lst[i - shifts] = lst[i];
}
for (int i = lst.Count - shifts; i < lst.Count; i++)
{
lst[i] = default(T);
}
}
For shift right it's a little more tricky, because we must copy in reverse
public static void ShiftRight<T>(List<T> lst, int shifts)
{
for (int i = lst.Count - shifts - 1; i >= 0; i--)
{
lst[i + shifts] = lst[i];
}
for (int i = 0; i < shifts; i++)
{
lst[i] = default(T);
}
}
With arrays it's a lot more simple, because Array has very powerful methods:
public static void ShiftLeft<T>(T[] arr, int shifts)
{
Array.Copy(arr, shifts, arr, 0, arr.Length - shifts);
Array.Clear(arr, arr.Length - shifts, shifts);
}
public static void ShiftRight<T>(T[] arr, int shifts)
{
Array.Copy(arr, 0, arr, shifts, arr.Length - shifts);
Array.Clear(arr, 0, shifts);
}
And yes, Array.Copy is protected against overleap: 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.
Below are a couple of extension methods that will shift the list either right or left. The methods will return a list.
public static class ShiftList
{
public static List<T> ShiftLeft<T>(this List<T> list, int shiftBy)
{
if (list.Count <= shiftBy)
{
return list;
}
var result = list.GetRange(shiftBy, list.Count-shiftBy);
result.AddRange(list.GetRange(0,shiftBy));
return result;
}
public static List<T> ShiftRight<T>(this List<T> list, int shiftBy)
{
if (list.Count <= shiftBy)
{
return list;
}
var result = list.GetRange(list.Count - shiftBy, shiftBy);
result.AddRange(list.GetRange(0, list.Count - shiftBy));
return result;
}
}
Here's an example of how to call it.
class Program
{
static void Main(string[] args)
{
List<int> test = Enumerable.Range(0, 10).ToList();
test = test.ShiftLeft(1);
PrintList(test);
Console.WriteLine("");
PrintList(test.ShiftRight(2));
Console.ReadLine();
}
private static void PrintList(List<int> test)
{
for (int i = 0; i < test.Count; i++)
{
Console.WriteLine(test[i]);
}
}
}
Keep it simple by taking the first part and second part and flipping them. Same thing but flip other way for the ShiftRight
public static List<int> ShiftLeft(List<int> a, int d)
{
if (a.Count > d)
{
var beginingPart = a.GetRange(0, d);
var remainingPart = a.GetRange(d, a.Count - d);
return remainingPart.Concat(beginingPart).ToList();
}
else if (a.Count < d)
{
var mod = d % a.Count;
if (mod != 0)
{
return rotLeft(a, mod);
}
}
return a;
}
Given that "iterations" is the times you want to shift and "numbers" is the List
Shift left:
static void ShiftLeft(int iterations)
{
for (int i = 0; i < iterations; i++)
{
numbers.Add(numbers[0]);
numbers.RemoveAt(0);
}
}
ShiftRight:
static void ShiftRight(int iterations)
{
for (int i = 0; i < iterations; i++)
{
numbers.Insert(0, numbers[numbers.Count - 1]);
numbers.RemoveAt(numbers.Count - 1);
}
}