I have a multidimensional array and I want to multiply each row of it by a single dimensional array containing factors to create a new multidimensional array. However, the number of rows in the multidimensional array will vary from one run to the next, so I'll need a way to loop the multiplication through each row of the multidimensional array until the last row is reached.
Here is a simple example, I have multidimensional array:
{ { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 12} }
and I want to multiply each row by:
{0.5, 0.4, 0, 0.8}
to get:
{ { 1*0.5, 2*0.4, 3*0, 4*0.8}, { 5*0.5, 6*0.4, 7*0, 8*0.8}, { 9*0.5, 10*0.4, 11*0, 12*0.8} }
I've tried to use .Length within a for loop using the example code.
double [] factors = {0.5, 0.4, 0, 0.8};
int [,] myarray = new int [3,4] {
{ 1, 2, 3, 4},
{ 5, 6, 7, 8},
{ 9, 10, 11, 12}
};
double [] output = new double[myarray.Length];
for(int i = 0; i < myarray.Length; ++i)
output[i] = myarray[i] * factors;
I'm getting syntax errors that extension method 'Length' cannot be applied to type int, and also indexing with [] cannot be applied to type int.
I'd suggest a ragged array. Multidimensional arrays exist, but are poorly supported and almost nobody uses them. If you use a jagged array, you can be more concise. More importantly, you can be more intentional about it:
double[][] myArray = getMeSomeData();
double[] factors = getMeSomeRowFactors();
foreach (var row in myArray)
{
MultiplyRow(row, factors)
}
. . .
void MultiplyRow( double[] row, double[] factors )
{
for ( int col = 0 ; col < row.length ; ++col )
{
row[col] = row[col] * factors[col];
}
}
Or even better: use Linq:
double[][] myArray = getMeSomeData();
double[] factors = getMeSomeRowFactors();
myArray = myArray
.Select( row => row.Select( (cell, i) => cell * factors[i] ).ToArray() )
.ToArray()
;
Or even [arguably] better;
double[][] myArray = getMeSomeData();
double[] factors = getMeSomeRowFactors();
myArray = myArray
.Select( Multiply(factors) )
.ToArray()
;
. . .
Func<double,int,double[]> Multiply( double[] factors )
{
return (cell, i) => cell * factors[i];
}
I am not sure if you find it useful, but you can achieve it by using MathNet.Numerics:
PM> Install-Package MathNet.Numerics
using MathNet.Numerics.LinearAlgebra.Double;
using System.Linq;
...
var myarray = new double[3, 4]
{
{ 1, 2, 3, 4},
{ 5, 6, 7, 8},
{ 9, 10, 11, 12}
};
var factors = new double[4] { 0.5, 0.4, 0, 0.8 };
var matrix1 = Matrix.Build
.DenseOfArray(myarray);
var matrix2 = Matrix.Build
.DenseOfRows(Enumerable.Repeat(factors, matrix1.RowCount));
var res = matrix1.PointwiseMultiply(matrix2).ToArray();
You can get the length of each dimension by using the method GetLength:
double[,] output = new double[myarray.GetLength(0), myarray.GetLength(1)];
for (int i = 0; i < myarray.GetLength(0); i++)
{
for (int j = 0; j < myarray.GetLength(1); j++)
{
output[i, j] = myarray[i, j] * factors[j];
}
}
In case your array is huge, you can speed up the calculation by using all processors/cores of your PC:
Parallel.For(0, myarray.GetLength(0), i =>
{
for (int j = 0; j < myarray.GetLength(1); j++)
{
output[i, j] = myarray[i, j] * factors[j];
}
});
Related
I want to make a function that takes an array of integers as input and print an array of int as Fibonaci series like: third element= second element + first element.
Here is my code so far:
static void Result(int[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] < 0)
Console.WriteLine("arr[i]", arr[i], " number to get must be greater or equal than 0");
var n = arr[i] + 1;
var a = new int[n];
arr[0] = 0;
if (arr[i] == 0)
{
a[1] = 1;
}
for ( i = 2; i < n; i++)
{
a[i] = a[i - 2] + a[i - 1];
}
}
}
public static void Main()
{
int[] arr = {7, 8, 3, 9, 11,16,14,91, };
Result(arr);
}
if input is : 1 ,3 ,4 ,6, 7 ,8 10, 11, 15 ,25 output should be: 1, 3, 4, 7, 11 so 1+3=4, 4+3=7 and so on.
I took a look at your code and you were very close.
The biggest issue was you were starting at i = 0 which would cause errors if you attempted to access arr[-1] and arr[-2].
We can solve that by starting with i = 2.
For example:
static int[] Result(int[] arr)
{
int[] result = arr;
for (int i = 2; i < arr.Length; i++)
{
result[i] = result[i-1] + result[i-2];
}
return result;
}
int[] arr = { 1 ,3 ,4 ,6, 7 ,8, 10, 11, 15 ,25 };
arr = Result(arr);
Console.WriteLine(string.Join(", ",arr));
// outputs: 1, 3, 4, 7, 11, 18, 29, 47, 76, 123
Another side note is that unless you're passing the int[] arr as a reference you will need to return a new int[] as the result since Result()'s changes to arr are not reflected on the array.
I want to pass int a[] values into int b[]. but I'm facing confusion. Can anyone correct me out. The output of b is 0,0,0,45,4,2,1. it supposed to be like 7,6,5,4,45,2,1.
static void Main()
{
int[] a = new int[] { 1, 2, 45, 4, 5, 6, 7 };
int[] b = new int[7];
int temp = 0;
for (int i = 0; i <= a.Length - 1; i++)
{
b[(b.Length - i) - 1] = a[i];
Console.WriteLine(b[i]);
}
}
The problem here is that you're inserting items starting from the last index of b, but you're outputting them starting from the first index. The code to copy the items is correct, but you need to adjust your line that outputs the result to the console to show the items in b using the same index that you just used to insert the item.
Note there are a couple of other improvments you can make, such as using array initializer syntax for a, using a.Length to instantiate b instead of a hard-coded number, removing the unused temp variable, using i < a.Length for the for condition (instead of i <= Length - 1, which does a subtraction operation on each iteration), and storing the b index in a variable instead of calculating it twice:
static void Main()
{
int[] a = new int[] {1, 2, 45, 4, 5, 6, 7};
int[] b = new int[a.Length];
for (int i = 0; i < a.Length; i++)
{
int bIndex = b.Length - i - 1;
b[bIndex] = a[i];
Console.WriteLine(b[bIndex]);
}
Console.ReadLine();
}
However, this will still output the items in the order in which you insert them, which will be the same order as they appear in a. If you want to show that the items in b are the reverse of a, the easiest way is to do it after you've populated b. Note we can make use of the string.Join method here to join each item with a comma:
static void Main()
{
int[] a = new int[] {1, 2, 45, 4, 5, 6, 7};
int[] b = new int[a.Length];
for (int i = 0; i < a.Length; i++)
{
b[b.Length - i - 1] = a[i];
}
Console.WriteLine($"'a' array: {string.Join(",", a)}");
Console.WriteLine($"'b' array: {string.Join(",", b)}");
Console.ReadLine();
}
Output
If you want to create a reverse array from an existing array, you can use Reverse extension method:
//using System.Linq;
int[] a = new int[] { 1, 2, 45, 4, 5, 6, 7 };
int[] b = a.Reverse().ToArray();
You can learn more about Extension Methods.
You can have this syntax
int[] a = {1, 2, 45, 4, 5, 6, 7};
int[] b = new int[7];
for (int i = 0, j = b.Length - 1; i < a.Length; i++, j--)
{
b[i] = a[j];
Console.WriteLine(b[i]);
}
I need to find the largest subarray. For example: array list { 1, 4, 7, 3, -3, -4, -1, 4, 2, 1 } need to find the largest subarray where the numbers are decreasing.
As from the list { 7, 3, -3, -4 } is one subarray and { 4, 2, 1 }, as the earlier one is biggest need to print that.
Simply
var results = new List<int>();
for (var i = 0; i < input.Length; i++)
{
// how we check
var current = new List<int>();
// just to know if we are are going down
var lastValue = input[i];
// second loop make sure we stop if the numbers aren't going down
for (var j = i; j < input.Length && input[j] <= lastValue; j++)
{
current.Add(input[j]);
lastValue = input[j];
}
// Update the result depending on the criteria
if (current.Count >= results.Count)
{
results = current;
}
}
// print your awesome numbers
foreach (var value in results)
{
Console.Write($"{value}, ");
}
You can test it here
You could try this LINQ approach:
var array = new[] { 1, 4, 7, 3, -3, -4, -1, 4, 2, 1 };
var descending_subarrays =
array
.Skip(1)
.Aggregate(new [] { array.Take(1).ToList() }.ToList(), (a, x) =>
{
if (a.Last().Last() > x)
{
a.Last().Add(x);
}
else
{
a.Add(new [] { x }.ToList());
}
return a;
})
.OrderByDescending(x => x.Count)
.ToList();
That gives:
You can then just pick the find answer with a descending_subarrays.First().
I am trying to find common element in three arrays. I am using Hashtable for this purpose as many people suggested here that it gives O(n) and its better.
Here is the code I have tried..
using System;
using System.Collections;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class newAttempt
{
static void Main()
{
Hashtable hm = new Hashtable();
int[] a = new int[] { 1, 2, 3, 4, 5 };
int[] b = new int[] { 2, 4, 6, 7, 8 };
int[] c = new int[] { 3, 4, 5, 6, 9 };
for (int i = 0; i <= a.Length - 1; i++)
{
hm.Add(i, a[i]);
}
foreach(int k in b)
if (hm.Contains(k))
{
foreach (int j in c)
if (hm.Contains(j))
Console.WriteLine(j);
}
Console.ReadKey();
}
}
}
I am getting ouput as
3
4
3
4
I want my program to stop looking when it finds out that 4 is the only element which is common in this case. Please help.
Use list.Intersect function , this is example .
var list1 = new string[] {"4", "5", "6", "7", "8"};
var list2 = new string[] {"4", "5"};
var commonElement = list1.Intersect(list2);
foreach (string s in commonElement ) Console.WriteLine(s);
Output:
4
5
For more information ,
This is the example of Intersection or array !
int[] a = new int[] { 1, 2, 3, 4, 5 };
int[] b = new int[] { 2, 4, 6, 7, 8 };
int[] c = new int[] { 3, 4, 5, 6, 9 };
var result = a.Intersect(b).Intersect(c).ToArray(); // 4
You can use the Extension Method Intersect from linq.
var hm1 = new HashSet<int>(new[] {1, 2, 3, 4, 5});
var hm2 = new HashSet<int>(new[] { 2, 4, 6, 7, 8 });
var hm3 = new HashSet<int>(new[] { 3, 4, 5, 6, 9 });
var intersection = hm1.Intersect(hm2).Intersect(hm3);
foreach (var i in intersection)
{
Console.WriteLine(i);
}
You're not checking if the inner number is the same as the outer loop's number, so essentially you're printing all numbers in b and c that are in hm. Replace your inner loop by:
foreach (int j in c)
if (j==k) // hm.Contains(j) is covered by the previous hm.Contains(k)
Console.WriteLine(j);
Edit: The other answer's intersect method is preferable for C#. Alternately, you can convert the arrays to a Set before performing this operation to improve performance for longer sequences.
Try changing the code to something like
foreach (int k in b)
if (hm.Contains(k))
{
foreach (int j in c)
if (j == k && hm.Contains(j)) //changes here
Console.WriteLine(j);
}
If you wish to exit the for loops once a match has been found you can try something like
bool found = false;
for (int bIndex = 0; !found && bIndex < b.Length; bIndex++)
{
int k = b[bIndex];
if (hm.Contains(k))
{
for (int cIndex = 0; !found && cIndex < c.Length; cIndex++)
{
int j = c[cIndex];
if (j == k && hm.Contains(j))
{
Console.WriteLine(j);
found = true;
}
}
}
}
in your code you are checking the first array with second array.if match then the first array with third array.
but what we need is,if the first to array have a match hen we want to check if that value is present in third array.only that particular value.
but your checking the whole values of first array with the third array
public static void main(String args[])
{
Hashtable hm = new Hashtable();
int[] a = new int[] { 1, 2, 3, 4, 5 };
Integer[] b = new Integer[]{ 2, 4, 6, 7, 8 };
int[] c = new int[] { 3, 4, 5, 6, 9 };
for (int i = 0; i <= a.length - 1; i++)
{
hm.put(i,a[i]);
}
for(int k:b)
{
if (hm.contains(k))
{
for(int j:c)
{
if (k==j) //here is the change
{
System.out.print(j);
}
}
}
}
}
}
You can use Linq. Intersect method will be good for such purpose.
But, do you want to find out intersections just using loops and Hashtable?
this code should work:
Hashtable hm = new Hashtable();
int[] a = new int[] { 1, 2, 3, 4, 5 };
int[] b = new int[] { 2, 4, 6, 7, 8 };
int[] c = new int[] { 3, 4, 5, 6, 9 };
foreach (var iA in a)
{
foreach (var iB in b)
{
if (iA == iB && !hm.ContainsKey(iA))
{
hm.Add(iA, iA);
}
}
}
foreach (var iC in c)
{
if (hm.ContainsKey(iC))
{
Console.WriteLine(iC);
hm.Remove(iC);
}
}
I have an int array in one dimension:
var intArray=new[] { 1, 2, 3, 4, 5, 6 };
and I want to convert it to two dimensions, such as:
var intArray2D=new[,] { {1, 2}, {3, 4}, {5, 6} };
How do I achieve this with C#?
with a loop perhaps:
for (int i = 0; i < oldArr.Length; i=i+2)
{
newArr[i/2, 0] = oldArr[i];
newArr[i/2, 1] = oldArr[i + 1];
}
Untested, but should get you pointed in the right direction...
If the one dimensional array contains the primitive data in row major order, and the total capacity of the 2 dimensional array equals the length of the one dimensional array, you can use this.
int[] source = new int[6];
int[,] target = new int[3, 2];
Buffer.BlockCopy(source, 0, target, 0, source.Length * sizeof(int));
Note that unlike Array.Copy and other array/list methods, Buffer.BlockCopy operates on a number of bytes of data, even if each element of the array is larger than 1 byte. It also only operates on arrays of primitive data types.
Additional references:
Multi-dimensional arrays are stored in row-major order (ECMA-335 Partition I, ยง8.9.1)
Buffer.BlockCopy
Edit: Here is a complete unit test.
[TestMethod]
public void SOTest16203210()
{
int[] source = new int[6] { 1, 2, 3, 4, 5, 6 };
int[,] destination = new int[3, 2];
Buffer.BlockCopy(source, 0, destination, 0, source.Length * sizeof(int));
Assert.AreEqual(destination[0, 0], 1);
Assert.AreEqual(destination[0, 1], 2);
Assert.AreEqual(destination[1, 0], 3);
Assert.AreEqual(destination[1, 1], 4);
Assert.AreEqual(destination[2, 0], 5);
Assert.AreEqual(destination[2, 1], 6);
}
I believe you want to split an integer array into an array of two integers each:
int[] list = new int[] { 1, 2, 3, 4, 5, 6};
int[][] newlist = new int[list.Length / 2][];
for (int i = 0, n = 0; i < list.Length; i += 2, n++)
{
newlist[n] = new[] { list[i], list[i + 1] };
}
To assign it to Points in particular you could try:
List<Point> plist = new List<Point>();
for (int i = 0; i < list.Length; i += 2)
{
plist.Add(new Point(list[i], list[i + 1]));
}
you may use this code. in here you can send any length you like. you can "deivde" the arry[] to arry[,] for any lenth.2 or 3 or what ever you like! as long as size % a.length ==0 !!!!
code
static int[,] convert(int[] a, int size)
{
int[,] value = new int[a.Length / size, size];
int counter = 0;
//
for (int b = 0; b < value.GetLength(0); b++)
for (int c = 0; c < value.GetLength(1); c++)
{
value[b, c] = a[counter];
counter++;
}
return value;
}
If the product of the dimensions are the same, the fastest way would probably be to pin the matrix using a fixed statement, then to use the Marshalling class to copy the continuous block from the array to an IntPtr created from the void* you got from the fixed.
You would have to wrap this in an unsafe statement and enable unsafe in the assembly's build config.
I have converted this from vb to c#
int Size = OldArray.Length;
int[,] NewPoints = null;
if (Size % 2 != 0) {
//Error - Array has odd number of elements!
} else {
for (i = 0; i <= Size - 1; i += 2) {
Array.Resize(ref AllPoints, (i / 2) + 1, 2);
NewPoints[i / 2, 0] = OldArray(i);
NewPoints[i / 2, 1] = OldArray(i + 1);
}
}
You could try this:
int [] a = {1,2,3,4,5,6};
int [,] b = new int[a.Length/2,2];
for(int i = 0;i<a.Length;i++)
{
b[i/2,i%2] = a[i];
}
Note that i/2 is an integer division, hence both 4/2 and 5/2 will give 2 which is a correct index in 2Darray for the tuple 5 and 6 from the original array. The second index is determined using reminder when divided by 2, it will give 0 if the index is even number and 1 if the index of the item from the original array is odd number.
I would consider this for any dimension of array:
public class TestClass {
public static void TestMethod2D() {
var intLinear=new[] { 1, 2, 3, 4, 5, 6 };
var indexer2D=new ArrayIndexer<int>(3, 2);
for(var i=intLinear.Length; i-->0; indexer2D[i]=intLinear[i])
;
var int2D=(int[,])indexer2D.ToArray();
}
public static void TestMethod4D() {
var intLinear=new[] { 1, 2, 3, 4, 5, 6 };
var indexer4D=new ArrayIndexer<int>(2, 2, 2, 2);
for(var i=intLinear.Length; i-->0; indexer4D[i]=intLinear[i])
;
var int4D=(int[, , ,])indexer4D.ToArray();
}
}
public partial class ArrayIndexer<T> {
public Array ToArray() {
return m_Array;
}
public ArrayIndexer(params int[] lengths) {
m_Array=Array.CreateInstance(typeof(T), lengths);
}
public T this[params int[] indices] {
set {
m_Array.SetValue(value, indices.Transform(m_Array));
}
get {
return (T)m_Array.GetValue(indices.Transform(m_Array));
}
}
Array m_Array;
}
public static partial class ArrayExtensions {
public static int[] Transform(
this int[] indices, Array array, bool isRowMajor=true) {
if(indices.Length>array.Rank)
return indices;
else {
var list=indices.ToList();
if(isRowMajor)
list.Reverse();
for(int r, q=0, i=0, count=array.Rank; count-->0; ++i) {
var index=isRowMajor?count-i:i;
if(indices.Length>i) {
q=Math.DivRem(indices[i]+q, array.GetLength(index), out r);
list[i]=r;
}
else {
if(index<0) {
list.Add(q);
q=0;
}
else {
q=Math.DivRem(q, array.GetLength(index), out r);
list.Add(r);
}
}
}
if(isRowMajor)
list.Reverse();
return list.ToArray();
}
}
}
ArrayExtensions.Transform is an indices transformer, it performs the linear transformation with the geometry of a given array. isRowMajor controls the layout, such as you would regard an int[,] in x, y or in y, x order.