I'm trying to find out how to make a 2D array out of possibly normal arrays.
Here is an example how'd I imagine that:
int[,] original = new int[,] {{1,1,1,1}, {1,0,0,1}, {1,0,0,1}, {1,1,1,1}};
int[] part = {1,1,1,1};
int[,] copy = new int[,] {part}, {1,0,0,1}, {1,0,0,1}, {1,1,1,1}};
This is not easy to do in general with native 2d arrays, and impossible to do during initialization.
But you can modify an existing 2d array with the following extension methods.
static class Program
{
static void Main(string[] args)
{
int[,] original = new int[,] {
{ 1, 1, 1, 1 },
{ 1, 0, 0, 1 },
{ 1, 0, 0, 1 },
{ 1, 1, 1, 1 } };
int[] row_0 = original.GetRow(0);
// {1,1,1,1}
int[] part = { 1, 2, 3, 4 };
original.SetRow(0, part);
// {{1,2,3,4},{1,0,0,1},...}
}
public static T[] GetRow<T>(this T[,] matrix, int row)
{
int rows = matrix.GetLength(0);
int columns = matrix.GetLength(1);
T[] result = new T[columns];
if (row<=rows)
{
int size = Buffer.ByteLength(matrix)/rows;
Buffer.BlockCopy(matrix, row*size, result, 0, size);
}
return result;
}
public static void SetRow<T>(this T[,] matrix, int row, params T[] elements)
{
int rows = matrix.GetLength(0);
int columns = matrix.GetLength(1);
if (row<rows && elements.Length == columns)
{
int size = Buffer.ByteLength(elements);
Buffer.BlockCopy(elements, 0, matrix, row*size, size);
}
}
}
Of course, the same functionality is trivial with jagged arrays. Instead of int[,] use int[][].
static class Program
{
static void Main(string[] args)
{
int[][] original = new int[][] {
new int[] { 1, 1, 1, 1 },
new int[] { 1, 0, 0, 1 },
new int[] { 1, 0, 0, 1 },
new int[] { 1, 1, 1, 1 }
};
int[] row_0 = original[0];
// { 1, 1, 1, 1}
int[] parts = new[] { 1, 2, 3, 4 }; // implicit int[] type
original[0] = parts;
// { {1, 2, 3, 4}, {1, 0, 0, 1},..}
int[,] matrix = original.JaggedToMatrix();
}
public static T[,] JaggedToMatrix<T>(this T[][] jagged)
{
int rows = jagged.Length;
int columns = jagged.Length>0 ? jagged[0].Length : 0;
T[,] result = new T[rows, columns];
for (int i = 0; i < rows; i++)
{
result.SetRow(i, jagged[i]);
}
return result;
}
public static T[][] MatrixToJagged<T>(this T[,] matrix)
{
int rows = matrix.GetLength(0);
int columns = matrix.GetLength(1);
T[][] result = new T[rows][];
for (int i = 0; i < rows; i++)
{
result[i] = matrix.GetRow(i);
}
return result;
}
public static T[] GetRow<T>(this T[,] matrix, int row)
{
int rows = matrix.GetLength(0);
int columns = matrix.GetLength(1);
T[] result = new T[columns];
if (row<=rows)
{
int size = Buffer.ByteLength(matrix)/rows;
Buffer.BlockCopy(matrix, row*size, result, 0, size);
}
return result;
}
public static void SetRow<T>(this T[,] matrix, int row, params T[] elements)
{
int rows = matrix.GetLength(0);
int columns = matrix.GetLength(1);
if (row<rows && elements.Length == columns)
{
int size = Buffer.ByteLength(elements);
Buffer.BlockCopy(elements, 0, matrix, row*size, size);
}
}
}
Related
Here is my code
public static int[] MoveZeroes(int[] arr)
{
// TODO: Program me
int zeroCount = 0;
int[] temp = { };
int numberItems = 0;
foreach (var a in arr)
{
if (a == 0)
{
zeroCount += 1;
}
else
{
temp[numberItems] = a;
}
numberItems += 1;
}
return new int[] { };
}
i use it like
int[] f = MoveZeroes(new int[] {1, 2, 1, 1, 3, 1, 0, 0, 0, 0});
But this is giving me error Index was outside the bounds of the array on line
temp[numberItems] = a;
how can i add items in array? what am i doing wrong ?
int[] temp = { }
This creates an array of ints that is 0 elements long. You can't insert into it because it has 0 length.
Use a List<int> and you can dynamically add to it:
public static int[] MoveZeroes(int[] arr)
{
// TODO: Program me
int zeroCount = 0;
var temp = new List<int>();
int numberItems = 0;
foreach (var a in arr)
{
if (a == 0)
{
zeroCount += 1;
}
else
{
temp.Add(a);
}
numberItems += 1;
}
return temp.ToArray();
}
I'd like help* in creating a method or (linq) expression that can row-wise concatenate lists (of varying lengths) of jagged arrays as the one below:
List<double[][]> orgArrayList = new List<double[][]>();
double[][] one = {
new [] {5d, 6},
new [] {7d, 9}};
double [][] two = {
new [] {5d, 6},
new [] {7d, 9}};
double [][] three= {
new [] {5d, 6},
new [] {7d, 9}};
orgArrayList.AddRange(new[] {one, two, three});
So that the resulting array will be equal to this one:
double[][] expected = {
new [] {5d, 6, 5, 6, 5, 6},
new [] {7d, 9, 7, 9, 7, 9}};
The number of jagged arrays in my input list(s) will be >=1. All arrays within a single list will be jagged with 2 dimensions, but none of the 2 dimensions will have a fixed/known length (size).
*'help' being a euphemism for someone telling me how to do it
You could start with something like this, which appends the elements of each row of add[] to the rows of src[], producing a new 2-dimensional array:
public static double[][] AppendToRows(double[][] src, double[][] add)
{
// Allocate new array to hold elements from src[] and add[]
double[][] res = new double[src.Length][];
// Append elements to each row of res[]
for (int i = 0; i < src.Length; i++)
{
// Allocate row res[i] large enough to hold elements from src[i] and add[i]
res[i] = new double[src[i].Length + add[i].Length];
// Copy/append elements from src[i] to res[i]
int ri = 0;
for (int j = 0; j < src[i].Length; j++)
res[i][ri++] = src[i][j];
// Copy/append elements from add[i] to res[i]
if (i >= add.Length)
continue;
for (int j = 0; j < add[i].Length; j++)
res[i][ri++] = add[i][j];
}
return res;
}
To append multiple arrays together, just call this method multiple times, once for each additional array that needs to be concatenated onto the resulting array.
A more comprehensive solution would be to take a List<double[][]> of input arrays, and to loop through each array in the list as you build each row of the result. But I have left that as an exercise for the reader.
You can create an extension, that will concatenate arrays the way you need, so it will looks like Linq:
public static class Extension
{
public static T[][] ConcatArrays<T>(this T[][] array, T[][] concatWith)
{
var max = Math.Max(array.Length, concatWith.Length);
var result = new T[max][];
for (var index = 0; index < max; index++)
{
var list = new List<T>();
if (index < array.Length)
{
list.AddRange(array[index]);
}
if (index < concatWith.Length)
{
list.AddRange(concatWith[index]);
}
result[index] = list.ToArray();
}
return result;
}
}
So the usage of this is:
var expected = one.ConcatArrays(two).ConcatArrays(three);
Hope it makes sense
As a final solution for my use case I simply combined David's and Valdimir's answer into a single method that can handle lists of varying lengths (>=1).
// ========================================
// My interpretation of David's suggestion
// using Valdimir's solution as a basis
// ========================================
public static double[][] RowWiseConcatListedJaggedArrays(List<double[][]> listOfJaggedArray)
{
var resArray = listOfJaggedArray[0];
for (int rInd = 1; rInd < listOfJaggedArray.Count; rInd++)
{
resArray = resArray.ConcatArrays(listOfJaggedArray[rInd]);
}
return resArray;
}
And putting everything together...
using System;
using System.Collections.Generic;
namespace RowWiseConcat
{
public static class Extension
{
// ====================
// Vladimir's solution
// ====================
public static T[][] ConcatArrays<T>(this T[][] array, T[][] concatWith)
{
var max = Math.Max(array.Length, concatWith.Length);
var result = new T[max][];
for (var index = 0; index < max; index++)
{
var list = new List<T>();
if (index < array.Length)
{
list.AddRange(array[index]);
}
if (index < concatWith.Length)
{
list.AddRange(concatWith[index]);
}
result[index] = list.ToArray();
}
return result;
}
}
class Program
{
// ========================================
// My interpretation of David's suggestion
// using Valdimir's solution as a basis
// ========================================
public static double[][] RowWiseConcatListedJaggedArrays(List<double[][]> listOfJaggedArray)
{
var resArray = listOfJaggedArray[0];
for (int rInd = 1; rInd < listOfJaggedArray.Count; rInd++)
{
resArray = resArray.ConcatArrays(listOfJaggedArray[rInd]);
}
return resArray;
}
static void Main(string[] args)
{
// ... do something that results in orgArrayList, e.g.
double[][] one =
{
new[] {5d, 6},
new[] {7d, 9}
};
double[][] two =
{
new[] {5d, 6},
new[] {7d, 9}
};
double[][] three =
{
new[] {5d, 6},
new[] {7d, 9}
};
List<double[][]> orgArrayList = new List<double[][]>()
{ one, two, three};
// Concat list items
var resArray = RowWiseConcatListedJaggedArrays(orgArrayList);
// ... continue with resArray
}
}
}
I have a question, I need to check if some array is part of greater array, it would be rather easy but I need to check if the greater array contains exact same sequence. For example
int[] greaterArray = {8, 3, 4, 5, 9, 12, 6 ... n - elements}
int[] lesserArray = {3, 4, 5}
Now I need to know if lesser array is part of this array but with same sequence so It it contains 3, 4, 5 next to each other in greater array.
I tried:
var exists = greaterArray.Intersect(lesserArray).Any();
But it return me information if any element of lesser array exists in greater array, not exact sequence. Any ideas?
int[] greaterArray = {8, 3, 4, 5, 9, 12, 6};
int[] lesserArray = { 3, 4, 5 };
bool sequenceFound = false;
for (int i = 0; i <= greaterArray.Length - lesserArray.Length; i++)
{
if (greaterArray.Skip(i).Take(lesserArray.Length).SequenceEqual(lesserArray))
{
sequenceFound = true;
break;
}
}
if (sequenceFound)
{
//sequence found
}
else
{
//sequence not found
}
Use the above code. It takes multiple sub-sequences from greaterArray of length equal to the length of lesserArray and matches it with lesserArray.
A bit more generic and without the use of LINQ:
int[] greaterArray = {8, 2, 4, 5, 9, 12, 3, 4, 5};
int[] lesserArray = {3, 4, 5};
for (int i = 0; i <= greaterArray.Length - lesserArray.Length; i++)
{
var sub = greaterArray.SubArray(i, lesserArray.Length);
if (Enumerable.SequenceEqual(sub, lesserArray))
{
Console.WriteLine("Equals!");
}
}
And this utils to get the SubArray:
public static T[] SubArray<T>(this T[] data, int index, int length)
{
T[] result = new T[length];
Array.Copy(data, index, result, 0, length);
return result;
}
This should do your work
int[] grtarr = { 8, 3, 4, 5, 9, 12, 6 };
int[] lsarr = { 3, 4, 5 };
List<int> lstGrtArr = grtarr.ToList();
List<int> lstLsrArr = lsarr.ToList();
bool sequenceMatch = false;
for (int i = 0; i < grtarr.Count(); i++)
{
if (lstGrtArr.Where(x => lstGrtArr.IndexOf(x) >= i).Take(lstLsrArr.Count()).SequenceEqual(lstLsrArr))
{
sequenceMatch = true;
break;
}
}
if(sequenceMatch)
{
//Do Something
}
static bool isPrefix(int[] source, int start_pos, int[] prefix)
{
bool result = start_pos + prefix.Length <= source.Length;
for (int i = 0; result && i < prefix.Length; ++i, ++start_pos)
result = source[start_pos] == prefix[i];
return result;
}
static bool Contains(int[] source, int[] prefix)
{
bool result = false;
for (int i = 0; !result && i < source.Length; ++i)
result = source[i] == prefix[0] ? isPrefix(source, i, prefix) : false;
return result;
}
Use this piece of code:
public bool ArraysEqual<T>(T[] a1, T[] a2)
{
if (ReferenceEquals(a1,a2))
return true;
if (a1 == null || a2 == null)
return false;
if (a1.Length != a2.Length)
return false;
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < a1.Length; i++)
{
if (!comparer.Equals(a1[i], a2[i])) return false;
}
return true;
}
Or if you want to use Linq and don't care too much about performance, the easiest thing is:
var arrays_are_the_same = Enumerable.SequenceEqual(a1, a2);
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 want to move all the data from column 0 of a 2D array to a separate 1D array. I have this so far:
for (int x = 0; x < 100; x++) { //100 is the amount of rows in the 2D array
array1D[x] = array2D[x, 0]; //0 is the column I want to take from
}
Is there a more better/more efficient way to achieve the same result?
You cannot copy out the columns, but you can copy out the rows with Buffer.BlockCopy()
class Program
{
static void FillArray(out int[,] array)
{
// 2 rows with 100 columns
array=new int[2, 100];
for (int i=0; i<100; i++)
{
array[0, i]=i;
array[1, i]=100-i;
}
}
static void Main(string[] args)
{
int[,] array2D;
FillArray(out array2D);
var first_row=new int[100];
var second_row=new int[100];
int bytes=sizeof(int);
Buffer.BlockCopy(array2D, 0, first_row, 0, 100*bytes);
// 0, 1, 2, ...
Buffer.BlockCopy(array2D, 100*bytes, second_row, 0, 100*bytes);
// 100, 99, 98, ..
}
}
Update
Here is an extension method do extract a single row from a 2D array (of any type)
public static T[] GetRow<T>(this T[,] array, int rowIndex)
{
int n = array.GetLength(1);
var row = new T[n];
var size = Buffer.ByteLength(row);
Buffer.BlockCopy(array, rowIndex*size, row, 0, size);
return row;
}
to be used as
var array = new double[3, 3] {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7 ,8, 9 } };
var second = array.GetRow(1);
// {4, 5, 6}