How to find the total of each column in 2D-array - c#

Note: the array and total of columns should be appear as below figure (numbers should not be
the same as figure below, numbers should be random)
5 1 1 1 1 1 1 1 1 1
2 2 4 5 6 7 8 8 9 9
1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3
5 5 5 5 5 5 5 5 5 5
4 4 4 4 4 4 4 4 4 4
7 7 7 7 7 7 7 7 7 7
3 3 3 3 3 3 3 3 3 3
1 1 1 1 1 1 1 11 1 1
The total of each column
33 29 31 32 33 34 35 45 36 36
`enter coddouble[,] a = new double[10, 10];
Random x = new Random();
string s = "";
for (int r = 0; r < 10; r++)
{
for (int c = 0; c < 10; c++)
{
a[r, c] = x.Next(1, 21);
s = s + a[r, c].ToString() + "\t";
}
}
textBox1.Text = s;e here`
this is how to print the arry now how to find the sum of each column

It is very basic in array implementation.
There are many ways to achieve this.One of my preferred way by iterating over the array structure using simple loop like this.
static int array[10][10];
//or like
int[,] array = new int[,]
{
<declare array structure>
};
int i, j, rowlength=10, columnlength=10, sum = 0; //assuming your order 10 as given example .To make it dynamic use array.Length
sum = 0;
for (j = 0; j < columnlength; ++j)
{
for (i = 0; i < rowlength; ++i)
{
sum = sum + array[i][j];
}
Console.WriteLine(String.Format("Summation of {0}th column is {1}", j,sum));
sum=0;
}

var arr2d = new int[5];
arr2d[0] = {1,2,3,4,5};
// etc...
var arr = new int[arr2d.length];
for(int i=0; i<arr2d.length; i++) {
var item = arr2d[i];
for(int j=0; j<item.length; j++) {
arr[i] += item[j];
}
}

you can try the below code. It generic code and can work on any number of column, you don't need to hardcode number of column. columnSum List contain the sum of individual column
var array2D = Get2DArray(); //some function to populate, you can have your own way to populate your 2D array
List<int> columnSum = new List<int>();
for (int j = 0; j < array2D.length ; ++j)
{
int sum = 0;
for (int i = 0; i < array2D[j].length; ++i)
{
sum = sum + array2D[i][j];
}
columnSum.Add(sum); // columnSum List contain the sum of individual column
}

Try this using your code.
What I did was sum the column you add the number to the array. This is assuming c is column and r is row.
double[,] a = new double[10, 10];
Random x = new Random();
string s = "";
var colsum = new List<int>();
for (int r = 0; r < 10; r++)
{
var col = 0;
for (int c = 0; c < 10; c++)
{
col += x.Next(1, 21);
a[r, c] = col;
s = s + a[r, c].ToString() + "\t";
}
colsum.Add(col);
}
foreach(var col in colsum){
Console.WriteLine(colsum.ToString());
}

Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int[,] data = new int[,] {
{5, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{2 ,2, 4, 5, 6, 7, 8, 8, 9, 9},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
{3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
{5, 5, 5, 5, 5, 5, 5, 5, 5, 5},
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
{7, 7, 7, 7, 7, 7, 7, 7, 7, 7},
{3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
{1, 1, 1, 1, 1, 1, 1, 11, 1, 1}
};
int[] sum = new int[10];
for (int row = 0; row < 10; row++)
{
for (int col = 0; col < 10; col++)
{
if (row == 0)
{
sum[col] = data[row, col];
}
else
{
sum[col] += data[row, col];
}
}
}
List<List<int>> data2 = new List<List<int>>() {
new List<int>() {5, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
new List<int>() {2 ,2, 4, 5, 6, 7, 8, 8, 9, 9},
new List<int>() {1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
new List<int>() {2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
new List<int>() {3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
new List<int>() {5, 5, 5, 5, 5, 5, 5, 5, 5, 5},
new List<int>() {4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
new List<int>() {7, 7, 7, 7, 7, 7, 7, 7, 7, 7},
new List<int>() {3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
new List<int>() {1, 1, 1, 1, 1, 1, 1, 11, 1, 1}
};
//using linq
int[] sum2 = data2.Select(s => s.Select((t, i) => new { num = t, col = i })).SelectMany(u => u).GroupBy(v => v.col).ToList().Select(w => w.Select(x => x.num).Sum()).ToArray();
}
}
}
​

It's pretty simple - just 2 nested for loops like this
static double[] SumColumns(double[,] source)
{
int rowCount = source.GetLength(0);
int colCount = source.GetLength(1);
var colSums = new double[colCount];
for (int row = 0; row < rowCount; row++)
for (int col = 0; col < colCount; col++)
colSums[col] += source[row, col];
return colSums;
}
Sample usage with your code:
int rows = 10, cols = 10;
var a = new double[rows, cols];
var x = new Random();
var sb = new StringBuilder();
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
a[r, c] = x.Next(1, 21);
if (c > 0) sb.Append("\t");
sb.Append(a[r, c]);
}
sb.AppendLine();
}
var colsSums = SumColumns(a);
for (int c = 0; c < cols; c++)
{
if (c > 0) sb.Append("\t");
sb.Append(colsSums[c]);
}
var s = sb.ToString();
textBox1.Text = s;

I know this is an old post but you can have it by the following single line,
var result = Enumerable.Range(0, sample.GetLength(1)).Select(c => Enumerable.Range(0, sample.GetLength(0)).Select(r => sample[r, c]).Sum()).ToArray();
Test with sample data
var sample = new int[10, 10]
{
{ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 2, 2, 4, 5, 6, 7, 8, 8, 9, 9 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
{ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 },
{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
{ 1, 1, 1, 1, 1, 1, 1, 11, 1, 1 }
};
var row = sample.GetLength(0);
var column = sample.GetLength(1);
var result = Enumerable.Range(0, column).Select(c => Enumerable.Range(0, row).Select(r => sample[r, c]).Sum()).ToArray();
Gets sum of each column in an array with; 33, 29, 31, 32, 33, 34, 35, 45, 36, 36

Related

Remove row from multidimensional array in jagged array

I have a jagged array with a multidimensional array and want to remove an array inside the multidimensional array. My code is:
int[][,] arr = new int[4][,];
arr[0] = new int[,] {
{ 1, 2, 3 }, // <- I want to remove this row
{ 4, 5, 6 },
{ 5, 6, 7 },
{ 8, 9, 10 } };
arr[1] = new int[,] {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 } };
arr[2] = new int[,] {
{ 1, 2, 3, 4, 5 },
{ 5, 6, 7, 8, 9 },
{ 10, 11, 12, 13, 14 },
{ 15, 16, 17, 18, 19 } };
arr[3] = new int[,] {
{ 1, 2, 3, 4, 5, 6},
{ 5, 6, 7, 8, 9, 10},
{ 11, 12, 13, 14, 15, 16 },
{ 17, 18, 19, 20, 21, 22 } };
int[,] removeArray = { { 1, 2, 3 } };
I tried to remove {1, 2, 3} from arr[0] by using Linq:
arr = arr
.Where((val, i) => i != 0)
.ToArray();
but this removes the whole arr[0] row. Does anyone know how I can get to remove {1,2,3} using Linq?
Unlike jagged arrays, multidimensional ones doesn't consist of arrays:
int[][] jagged = new int[][] {
new[] { 1, 2, 3 }, // <- this is an array
new[] { 4, 5 }, // <- this is another array
};
int[,] array2D = new int[,] {
{ 1, 2, 3 }, // <- not an array
{ 4, 5, 6 }, // <- not an array
};
So if you want to "remove" row from 2d array, you have to recreate it; something like this:
private static T[,] RemoveRows<T>(T[,] source, T[] row) {
if (row.Length != source.GetLength(1))
return source;
var keepRows = new List<int>();
for (int r = 0; r < source.GetLength(0); ++r)
for (int c = 0; c < row.Length; ++c)
if (!object.Equals(source[r, c], row[c])) {
keepRows.Add(r);
break;
}
if (keepRows.Count == source.Length)
return source;
T[,] result = new T[keepRows.Count, source.GetLength(1)];
for (int r = 0; r < keepRows.Count; ++r)
for (int c = 0; c < result.GetLength(1); ++c)
result[r, c] = source[keepRows[r], c];
return result;
}
and then
// we remove row; let it be 1d array, not 2d one
int[] removeArray = { 1, 2, 3 };
arr = arr
.Select(array => RemoveRows(array, removeArray))
.ToArray();
please, fiddle yourself

Generate random numbers with specific interval

I'm trying to generate 3 numbers between 1 and 10. The difference between any two numbers must be smaller/equal to 2. For example: 2, 6, 9 are OK, but 2, 4, 7 are not (because 4 - 2 = 2).
private int GetGoodNumber()
{
int lastIndex = 0;
int x = 3;
int randomNumber = 0;
for (int i = 0; i < 3; i++)
{
int interval = UnityEngine.Random.Range(2, 7);
do
{
randomNumber = interval + (UnityEngine.Random.Range(0, 10));
} while (randomNumber > 10 || x <= 2);
x = (lastIndex > randomNumber) ? lastIndex - randomNumber : randomNumber - lastIndex;
lastIndex = randomNumber;
Debug.Log(randomNumber);
}
return randomNumber;
}
Unfortunately, my method does not work, does anyone know the problem.
There aren't too many combinations given this rule.
The firstNumber must be 1, 2, 3 or 4.
Based on this generate the next between firstNumber + 3 and 7.
And the last one by the same logic.
Code:
var random = new Random();
var first = random.Next(1, 4 + 1);
var second = random.Next(first + 3, 7 + 1);
var third = random.Next(second + 3, 10 + 1);
I think I would hardcode it to get correct distribution.
var x = new [,]
{
{1, 4, 7},
{1, 4, 8},
{1, 4, 9},
{1, 4, 10},
{1, 5, 8},
{1, 5, 9},
{1, 5, 10},
{1, 6, 9},
{1, 6, 10},
{1, 7, 10},
{2, 5, 8},
{2, 5, 9},
{2, 5, 10},
{2, 6, 9},
{2, 6, 10},
{2, 7, 10},
{3, 6, 9},
{3, 6, 10},
{3, 7, 10},
{4, 7, 10}
};
Mabe something like this:
public static List<int> GetRandomNumbers()
{
List<int> result = new List<int>();
for (int i = 0; i < 3; i++)
{
bool numberFit = false;
int number = 0;
do
{
number = random.Next(0, 10);
numberFit = !result.Any(x => x > number - 3 && x < number + 3);
} while (!numberFit);
result.Add(number);
}
return result;
}

Return only one subset of a given number list that sums to a target value

I was hoping someone could assist with an issue I'm having with a subset sum problem. I took the below code from another thread. What I'd like to do, ideally, is have a function that returns the first array that meets this condition: " if (s == target && partial.ToArray().Length == 7)".
Is that possible with the code I'm using below? In other words, I don't want ALL of the combinations, just the first one that meets that condition. I've tried a few things, but I'm not experienced enough at C# to really understand how to break out of the recursion or return the array to a calling function. Any help would be greatly appreciated.
private void button1_Click(object sender, EventArgs e)
{
List<int> numbers = new List<int>() { 2, 6, 6, 5, 8, 1, 3, 3, 9, 3, 6, 1, 3, 9, 1, 7, 8, 6, 8, 1, 1, 4, 4, 2, 8, 4, 5, 4, 6, 10, 1, 4, 3, 1, 2, 8, 4, 5, 9, 2, 2, 4 };
int target = 27;
sum_up(numbers, target);
}
private static void sum_up(List<int> numbers, int target)
{
sum_up_recursive(numbers, target, new List<int>());
}
private static void sum_up_recursive(List<int> numbers, int target, List<int> partial)
{
int s = 0;
foreach (int x in partial) s += x;
if (s == target && partial.ToArray().Length == 7)
Console.WriteLine("sum(" + string.Join(",", partial.ToArray()) + ")=" + target);
if (s >= target)
return;
for (int i = 0; i < numbers.Count; i++)
{
List<int> remaining = new List<int>();
int n = numbers[i];
for (int j = i + 1; j < numbers.Count; j++) remaining.Add(numbers[j]);
List<int> partial_rec = new List<int>(partial);
partial_rec.Add(n);
sum_up_recursive(remaining, target, partial_rec);
}
}
}
I'm sure there are easier ways of doing this, but to use your code, I believe this is one way you could do it:
using System.Linq;
using System.Collections.Generic;
private void button1_Click(object sender, EventArgs e)
{
List<int> numbers = new List<int>
{
2, 6, 6, 5, 8, 1, 3, 3, 9, 3, 6, 1, 3, 9, 1, 7, 8, 6, 8, 1, 1,
4, 4, 2, 8, 4, 5, 4, 6, 10, 1, 4, 3, 1, 2, 8, 4, 5, 9, 2, 2, 4
};
int target = 27;
sum_up(numbers, target);
}
private static void sum_up(List<int> numbers, int target)
{
sum_up_recursive(numbers, target, new List<int>(), 0);
}
private static void sum_up_recursive
(List<int> numbers, int target, List<int> #partial, int index)
{
int s = #partial.Sum();
if (s >= target && #partial.Count == 7)
{
Console.WriteLine("sum(" + string.Join(",", partial.ToArray()) + ")=" + target);
}
else if (s < target)
{
if( index + 7 > numbers.Count )
{
return;
}
else
{
List<int> partial_rec = numbers.GetRange(index, index + 7);
sum_up_recursive(numbers, target, partial_rec, ++index);
}
}
}

C# correct way to Iterate over 2d array as a subset 2d array

For an example if I want to iterate test and perfrorm operations on elements from that array but they have to be formatted in a particular way.
Essentially I am trying to loop over a 2d array using a 2d array.
double[,] test = {
{9, 8, 7, 6, 5, 4, 3, 2},
{8, 7, 6, 5, 4, 3, 2, 1},
{7, 6, 5, 4, 3, 2, 1, 0},
{6, 5, 4, 3, 2, 1, 0, 0},
{5, 4, 3, 2, 1, 0, 0, 0},
{4, 3, 2, 1, 0, 0, 0, 0},
{3, 2, 1, 0, 0, 0, 0, 0},
{2, 1, 0, 0, 0, 0, 0, 0},
};
double[,] subset = new double[2,2]; //used in math
What I would like to be able to do is to iterate over any size matrix (assuming that they are even sized and square) with each iteration looking like this:
Iteration 1:
subset[0,0] = test[0,0];
subset[0,1] = test[0,1];
subset[1,0] = test[1,0];
subset[1,1] = test[1,1];
So basically it selected a square same size as subset out of the large matrix.
Iteration 2:
subset[0,2] = test[0,2];
subset[1,2] = test[1,2];
subset[0,3] = test[0,3];
subset[1,3] = test[1,3];
You can do this via an extension method. A few things worth mentioning:
Using Array.Copy as opposed to manually assigning the elements should yield better performance.
Like Tom A mentioned in a comment, you should use yield return to create an IEnumerable. You can then iterate over it using a foreach loop, or perform other operations.
Implementation:
static class MatrixExtensions
{
public static IEnumerable<T[,]> ChunkMatrix<T>(this T[,] inputMatrix, int chunkWidth, int chunkHeight)
{
int inputWidth = inputMatrix.GetLength(0);
int inputHeight = inputMatrix.GetLength(1);
for(int i = 0; i < inputWidth; i += chunkWidth)
{
for(int j = 0; j < inputHeight; j += chunkHeight)
{
T[,] chunk = new T[chunkWidth, chunkHeight];
for(int k = 0; k < chunkWidth; k++)
{
int sourceIndex = i*inputWidth + k* inputWidth + j;
var destinationIndex = k* chunkHeight;
Array.Copy(inputMatrix, sourceIndex, chunk, destinationIndex, chunkHeight);
}
yield return chunk;
}
}
}
}
Usage:
double[,] test = {
{1, 2, 3, 4, 5, 6, 7, 8},
{9, 10, 11, 12, 13, 14, 15, 16},
{17, 18, 19, 20, 21, 22, 23, 24},
{25, 26, 27, 28, 29, 30, 31, 32},
{33, 34, 35, 36, 37, 38, 39, 40},
{41, 42, 43, 44, 45, 46, 47, 48},
{49, 50, 51, 52, 53, 54, 55, 56},
{57, 58, 59, 60, 61, 62, 63, 64},
};
foreach(double[,] chunk in test.ChunkMatrix(2, 2))
{
// First iteration:
// 1 2
// 9 10
//
// Second iteration:
// 3 4
// 11 12
//
// ...
}
I changed your test data to not include duplicate values, as to better illustrate the effect.
It should be noted that my implementation will not work correctly on matrices with dimensions that are not multiples of the chunks' dimensions, as it was mentioned in a comment that this will never be the case. If needed, modifying it to account for this scenario shouldn't be too hard.
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
const int COLUMNS = 8;
const int ROWS = 8;
const int SIZE = 2;
static void Main(string[] args)
{
double[,] test = {
{9, 8, 7, 6, 5, 4, 3, 2},
{8, 7, 6, 5, 4, 3, 2, 1},
{7, 6, 5, 4, 3, 2, 1, 0},
{6, 5, 4, 3, 2, 1, 0, 0},
{5, 4, 3, 2, 1, 0, 0, 0},
{4, 3, 2, 1, 0, 0, 0, 0},
{3, 2, 1, 0, 0, 0, 0, 0},
{2, 1, 0, 0, 0, 0, 0, 0},
};
for (int i = 0; i < COLUMNS; i += SIZE)
{
for (int j = 0; j < ROWS; j += SIZE)
{
for (int k = j; k < j + SIZE; k++)
{
for (int l = i; l < i + SIZE; l++)
{
Console.WriteLine("test[{0}, {1}] = {2}", k, l, test[k, l]);
}
}
}
}
Console.ReadLine();
}
}
}
I am not saying this is the best solution but while I look at the yield statement I managed to get it working using this method.
public static double[,] GetMapSection(Rectangle area, double[,] map) {
double[,] result = new double[area.Width, area.Height];
for (Int32 y = 0; y < area.Height; ++y) {
for (Int32 x = 0; x < area.Width; ++x) {
result[x, y] = map[x + area.X, y + area.Y];
}
}
return result;
}
I call it via:
List<double[,]> testChannel = new List<double[,]>();
for (int i = 0; i < Math.Sqrt(large_mapdata.Length); i+=8) {
for (int j = 0; j < Math.Sqrt(large_mapdata.Length); j+=8) {
testChannel.Add(GetMapSection(new Rectangle(i, j, 8, 8), large_mapdata));
}
}
In this example I am creating 8x8 chunks out of an array that is 32x32 in size.
I can confirm that this worked for me and is cleaner than what I had before.

how to create a 5 by 5 matrix in c# windows form

for (int i = 0; i!=5; i++)
{
for (int j=0; j!=5; j++)
{
array times[i, j] = int.Parse(Tb_First.Text);
list_Matrix.Items.Add(array times[i,j]);
}
}
or
int[,] numbers = new int[,] {{ 1 , 2 , 3, 4, 5 }, { 2, 3, 4, 5, 6 }} ;
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i !=5; i++)
{
for (int j = 0; j !=5; j++)
{
list_Matrix.Items.Add(numbers[i,j].To String());
}
}
}
i have tried this but it isn't working.. is there any other methods to generate a 5 by 5 matrix in C# in windows form. the input is written on text box and the matrix should be in a list box. some one please help me
try it
var numbers = new int[5,5] { { 1, 2, 3, 4, 5 },
{ 2, 3, 4, 5, 6 }, { 1, 2, 3, 4, 5 }, { 2, 3, 4, 5, 6 }, { 1, 2, 3, 4, 5 }};
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
list_Matrix.Items.Add(numbers[i,j].To String());
}
}
}
There is a source by microsoft for it
Programming guide (Multidimensional - Arrays /Matrix)
var numbers = new int[5,5] { { 1, 2, 3, 4, 5 }, { 2, 3, 4, 5, 6 }, {
1, 2, 3, 4, 5 }, { 2, 3, 4, 5, 6 }, { 1, 2, 3, 4, 5 }};
I guess discribe the int[,] is better than "var" to show that secound sample is almost correct. The problem is just the incorrect size.

Categories