I've learned C++ and am currently taking C#. Just to clarify, I am providing all the instructions but if I can get help with parts (b) and (c) I think I can do the rest.
This is my assignment:
Matrix is a 2 dimensional array of row size r and column size c. There are specific rules of adding or subtracting matrices A and B (of same row size m and column size n). The product of matrix A of dimension m by n (m is the row size or row dimension, n is the column dimension) and another matrix B of dimension p by q is meaningful only if p = n and in this case AB is a matrix of dimension m by q.
(a) Define class Matrix with at least private variables depending on row size, column size etc.
(b) Provide constructor when row size and column size are specified. You will set all the arguments to 0.0.
(c) Provide method to set the entries of a matrix
(d) Provide Add method of matrices
(e) Provide Subtract method.
(f) Provide scalar multiplication which will multiply all the elements of matrix A by the value x.
(g) Provide multiplication method mul so that A.mul(B) is equal to AB if A’s column dimension c is equal to B’s row dimension. Generate error message if the product AB is meaningless.
{
{
private int r=10;//row size
private int c=10;//column size
int[,] array=new int [10,10];
public Matrix()
{
for (int i = 0; i < this.r; i++)
{
for (int j = 0; j < this.c; j++)
{
}
}
}
public Matrix(int rowSize, int columnSize)
{
this.r = rowSize;
this.c = columnSize;
}
public void SetMatrix()
{
for (int i=0; i<this.r; i++)
{
for(int j=0; j<this.c; j++)
{
}
}
}
}
}
Without a finite size, I'm not sure how to proceed with creating the array (the 10,10 was just so the compiler would stop complaining). Secondly, when that's established, I'm not sure on how to fill in the array (most likely from the console). Hopefully my question doesn't sound too much like I'm asking for someone to do my homework for me. XD
First - you don't need a loop to initialize your matrix. Just declaring an int[r,c] will give you a 2d array filled with zeros. Your description doesn't say a zero argument constructor is required, so I wouldn't provide one, it's not clear how it should behave anyway. So just create one constructor like this:
public Matrix(int rows, int cols)
{
r = rows;
c = cols;
array = new int[r,c]; // Note: this will be filled with zeros!
}
For setting entries you can just provide a method like this:
public void SetCell(int row, int col, int val)
{
array[row,col] = val;
}
Or you could even do something like this using an indexer:
public int this[int row, int col]
{
get { return array[row,col]; }
set { array[row,col] = value; } // You didn't ask for a setter, but I assume you'll need one
}
if I can get help with parts (b) and (c) I think I can do the rest.
Ok, good luck then
EDIT:
So to clarify, when you declare an array of int it will be initially filled with zeros. This is in contrast to c++ where it would be a random block of memory that will be filled with random junk and you would need to set to zero. The use of unassigned variables is one of the "problems" with c++ that c# aimed to fix. For example, if you run this code:
int[] arr = new int[10];
Console.WriteLine(string.Join(",",arr));
It will write 0,0,0,0,0,0,0,0,0,0 every single time.
For more info read here. In particular, this part:
Note If you do not initialize an array at the time of declaration, the array members are automatically initialized to the default initial value for the array type. Also, if you declare the array as a field of a type, it will be set to the default value null when you instantiate the type.
But note, if you do this:
int a;
Console.WriteLine(a);
You will actually get a compile time error complaining about the usage of an unassigned variable.
Related
I am taking a class in c# programming and cannot figure out how to do the following. I have spent hours researching and nobody else seems to have the same issues.
The question is:
Write a function named, evenOrOdd, that will accept three parameters. The first parameter is the integer array used in the above function. The second parameter is the string array from step 2 and the third parameter is an integer indicating the size of the two arrays. This function will perform the following tasks:
This function will loop through the first array, checking each value to see if it is even or odd.
For each item in the integer array, the function will then place the appropriate value, “even” or “odd”, in the corresponding position of the string array.
Hint: Using the modulus operator, (also called the modulo), to divide the number by 2 will result in either a remainder of 0 or 1. A remainder of 0 indicates an even number and a remainder of 1 indicates an odd number. The modulus operator for all of the languages in this class is %.
After calling both functions, print the maximum number determined by findMax as well as the array index position of the largest number. Next, the program will loop through the two arrays and print the integer from integer array followed by the corresponding “even” or “odd” value from the string array
I do not understand how to populate the second string array with "even" or "odd".
The two arrays should be something like this:
array1 [1,2,3,4,5,6,7,8,9,10]
then run through a loop to determine if the values are even or odd and then assign the values to the second array so it is something like this:
array2 [odd,even,odd,even,odd,even,odd,even,odd,even]
I am confused how I "link" these two arrays together so that it know index of array 1=index of array 2.
You don't have to "link" the arrays together. You can use a variable which contains the current index and use it for both arrays. Like this:
for (int i = 0; i < array1.Length; i++){
//array1[i]...
//array2[i] = ...
}
This way, you can check if the number at index i in array 1 is even or odd and then modify the index i of array 2 accordingly.
Instead of array1.Length, you can also use the third argument of the method.
It looks like a code challenge. I highly recommend you find your own way to understand and solve this kind of problem and the fundamental concepts behind it as well.
One way to code the EvenOrOdd method:
public void EvenOrOdd(int[] numbers,
string[] natures, int size)
{
for(int i=0; i < size; i++)
if(numbers[i] % 2 == 0)
natures[i] = "even";
else
natures[i] = "odd";
}
One wat to code FindMax Function:
public static (int MaxValue, int MaxIndex) FindMax(int[] numbers)
{
int major = int.MinValue;
int majorIndex = -1;
for(int i=0; i < numbers.Length; i++)
if(numbers[i] > major)
{
major = numbers[i];
majorIndex = i;
}
return (major, majorIndex);
}
Check it in dotnetFiddle
I have an Array variable. I can use the Rank property to get the number of dimensions and I know that you can use a foreach to visit each element as if the array was flattened. However, I wish to modify elements and change element references. I cannot dynamically create the correct number of for loops and I cannot invalidate an enumerator.
EDIT
Thanks for the comments, sorry about the previous lack of clarity at the end of a long tiring day. The problem:
private void SetMultiDimensionalArray(Array array)
{
for (int dimension = 0; dimension < array.Rank; dimension++)
{
var len = array.GetLength(dimension);
for (int k = 0; k < len; k++)
{
//TODO: do something to get/set values
}
}
}
Array array = new string[4, 5, 6];
SetMultiDimensionalArray(array);
Array array = new string[2, 3];
SetMultiDimensionalArray(array);
I had another look before reading this page and it appears all I need to do is create a list of integer arrays and use the overloads of GetValue and SetValue -
Array.GetValue(params int[] indices)
Array.SetValue(object value, params int[] indices)
Everything seems clear now unless someone can suggest a superior method. svick has linked to this so I will accept this answer barring any further suggestions.
It's hard to tell what exactly do you need, because your question is quite unclear.
But if you have a multidimensional array (not jagged array) whose rank you know only at runtime, you can use GetValue() to get the value at specified indices (given as an array of ints) and SetValue() to set it.
I have a measurement array of 1024 values. But in this array are some values wrong like noise/peaks. The array is normally like sinus so all values should be in a good line.
How can i create a filter to the array to remove these peaks and noise?
I heard something of an algorithm that compares always three values and creates the mean-value of it but I can't find an example of this.
The wrong values are "peaks" which are bigger than the value before so it is perhaps easier if i just compare the value with the value before for a given "Offset"?
But how to do this?
public int FilterArray(double[] Values, double Offset, out double[] Results)
{
int ArrLength = Values.Length;
Results = new double[ArrLength];
for (int i = 0; i < ArrLength; i++)
Values[i] = 0;
try
{
for (int i = 0; i < ArrLength; i++)
{
if (Values[i+1] + Offset) > (Values[i]
{
// here someting is needed
}
else
{
// nothing to do if next value is ok
}
}
}
return 0;
}
Thanks for all help
I suggest to use a List instead of an Array. If you need an Array to process your data you can use the ToArray() Method but removing/filtering items from a List is way more easy than resizing Arrays.
It seems you heard about Median Filter (due to phrase that compares always three values phrase). It works good when you have to remove rare peaks.
Example: for data point triplet [3, 100, 7] algorithm finds that median (not mean!) value of this triplet is 7, and (100) data point is replaced by (7) value.
public int FilterArray(List<double> Values, double Offset, out double[] Results)
{
foreach(double value in new List<double>(Values))
{
// some logic
Values.Remove(value);
}
return 0; //??
}
i have double[,] Array;. Is it possible to get something like double[] ColumnArray0 = Array[0,].toArray() and double[] RowArray1 = Array[,1].toArray() without making a copy of every elemet(using for)?
Thanks.
Although being very late, I want to provide an alternative answer to the question.
The first important part of the question was to be able to access complete rows OR columns of the matrix. One possibility of doing this is by using extension methods:
public static class MatrixExtensions
{
/// <summary>
/// Returns the row with number 'row' of this matrix as a 1D-Array.
/// </summary>
public static T[] GetRow<T>(this T[,] matrix, int row)
{
var rowLength = matrix.GetLength(1);
var rowVector = new T[rowLength];
for (var i = 0; i < rowLength; i++)
rowVector[i] = matrix[row, i];
return rowVector;
}
/// <summary>
/// Sets the row with number 'row' of this 2D-matrix to the parameter 'rowVector'.
/// </summary>
public static void SetRow<T>(this T[,] matrix, int row, T[] rowVector)
{
var rowLength = matrix.GetLength(1);
for (var i = 0; i < rowLength; i++)
matrix[row, i] = rowVector[i];
}
/// <summary>
/// Returns the column with number 'col' of this matrix as a 1D-Array.
/// </summary>
public static T[] GetCol<T>(this T[,] matrix, int col)
{
var colLength = matrix.GetLength(0);
var colVector = new T[colLength];
for (var i = 0; i < colLength; i++)
colVector[i] = matrix[i, col];
return colVector;
}
/// <summary>
/// Sets the column with number 'col' of this 2D-matrix to the parameter 'colVector'.
/// </summary>
public static void SetCol<T>(this T[,] matrix, int col, T[] colVector)
{
var colLength = matrix.GetLength(0);
for (var i = 0; i < colLength; i++)
matrix[i, col] = colVector[i];
}
}
Usage example:
double[,] myMatrix = ... // Initialize with desired size and values.
double[] myRowVector = myMatrix.GetRow(2); // Gets the third row.
double[] myColVector = myMatrix.GetCol(1); // Gets the second column.
myMatrix.SetCol(2, myColVector); // Sets the third column to the second column.
First thing to note is that you can use these generic methods with any kind of [,]-matrices and corresponding []-vectors. Imagine replacing the Ts with doubles, and you would get the specific version for 'double' (as was asked by the OP).
Second thing is, that getting and setting the rows uses Array.Copy, while getting and setting the columns uses a loop. This is due to the Row-Major order of C#, which allows the first, but not the second. Of course both can be implemented with a loop, as seen commented out.
Make sure to pass correct dimensions for the set-Methods, or the program will crash (error and dimension checking can be added easily). The whole logic could as well be implemented for jagged arrays like double[][], however, the OP specificially asked for multidimensional ones.
As for the second part of the question: If your matrix consists of double, and since double is a value type, the values will always be copied. So your desired behaviour of not copying the values would not be possible. However, if using objects as T, only the reference pointing to the object will be copied, and not the object itself (so beware of mutating the 'copied' object).
Lastly, if you really don't want to copy the double-values, I'd suggest passing your whole matrix (only the reference is passed), and then directly looping through the desired columns and/or rows.
Arrays are a memory area where all entries are stored in a consecutive way. Depending on the data layout in memory this is only possible for either rows or columns.
Instead of the 2d array double[,] type it is in your case better to use an array of arrays double[][]
double[][] Array2d = new double[10][];
Array2d[0] = new double[10];
Array2d[1] = new double[10];
...
and then:
double[] RowArray0 = Array2d[0];
Depending on how you put the data in your array, you can also treat the Array2d as a column array. But to have both at the same time is not possible.
Also have a look here:
Multidimensional Array [][] vs [,]
I am trying to figure out how to turn the following, one-line CSV file into a 30x30 2D array.
http://pastebin.com/8NP7s7N0
I've tried looking it up myself, but I just can't seem to wrap my brain around the concept of multidimensional arrays, and I don't know how to turn a one-line file like this into an array of a specified size.
I want to be able to make an array that would look like this when printed:
0,0 = 2
0,1 = 2
All the way to 30,30.
Most of the numbers in the CSV are indeed 2's, but some are 1s. The difference is very important though. I am trying to make collision detection for a game, and this CSV file is the map. All I need left is how to create this array - leave the rest to me. :)
Thank you very much to all, have a nice day.
This should be a complete example using a 5 x 5 grid. I've tried it and seems to work as expected:
namespace ConsoleApplication1
{
using System;
class Program
{
const int MapRows = 5;
const int MapColumns = 5;
static void Main(string[] args)
{
// Create map and the raw data (from file)
var map = new int[MapRows, MapColumns];
string rawMapData = "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";
string[] splitData = rawMapData.Split(',');
int index = 0;
// Loop through data
for (int row = 0; row < MapRows; row++)
{
for (int column = 0; column < MapColumns; column++)
{
// Store in map and show some debug
map[row, column] = int.Parse(splitData[index++]);
Console.WriteLine(string.Format("{0},{1} = {2}", row, column, map[row, column]));
}
}
// Wait for user to read
Console.ReadKey();
}
}
}
Assuming your file is 900 elements first you need to read it in..
something along the lines of
line = myStreamReader.readLine().Split(',').. then in John U's example, value would be the next index in this array called line
I'll let you work out whats missing from my example :P
well, first you need to get the numbers...
var numbers = Read_File_As_String().Split(new char[',']).Select(n => int.Parse(n)).ToList();
then, you need to build your array
const int ROWS = 30;
const int COLS = 30;
var result = new int[ROWS, COLS];
for (int row = 0; row < ROWS; row++)
for (int col = 0; col < COLS; col++)
result[row, col] = numbers[(row * COLS) + col];
for(row=0;row<30;row++)
{
for(col=0;col<30;col++)
{
array[row][col] = value;
}
}
Value would need to be moved along to point to the next thing each time, but I'm sure you can figure that out.
Edited to add: If it's a map it might be easier to store it as an array in the first place.
Since you asked about the concept of multi-dimensional arrays, here are some useful ways of thinking about arrays. Please note these are analogies, meant to help you visualize them.
Think of a 1D array as a list of items (not in the programming sense of list!).
Think of a 2D array as a table (again, not in the programming sense!). In a table (like a spreadsheet) you have rows and columns, and each dimension in your array accesses one of these.
For higher dimensional arrays, it may help to think geometrically. For instance, you can think of 3D arrays as 3-dimensional points in space, and 4D arrays as 4-dimensional points in space-time.
So if you have a single CSV file, start off by conceptualizing how this would be re-structured as a table. Once you have that, you have a pretty straight-forward mapping to the array.