An array of arrays is given. It is necessary to find the minimum element in each column and write the data to a new array. I have done the following implementation, in accordance with the given conditions. But I am having a problem:expected minimum element in each column of the array are incorrect. Where am I making a mistake?
class Program
{
static int[][] Input()
{
Console.Write("n = ");
int n = int.Parse(Console.ReadLine());
int[][] a = new int[n][];
//int[] minA = new int[n];
for (int i = 0; i < n; ++i)
{
a[i] = new int[n];
for (int j = 0; j < n; ++j)
{
Console.Write("a[{0},{1}]= ", i, j);
a[i][j] = int.Parse(Console.ReadLine());
}
}
return a;
}
static void Print(int[] a)
{
foreach (double elem in a)
{
Console.Write("{0} ", elem);
}
}
static void Print2(int[][] a)
{
for (int i = 0; i < a.Length; ++i, Console.WriteLine())
for (int j = 0; j < a[i].Length; ++j)
Console.Write("{0,5} ", a[i][j]);
}
static int[] F(int[][] a)
{
int[] b = new int[a[1].Length];
for (int j = 0; j < a[1].Length; j++)
{
int tempmin = a[0][j];
for (int i = 0; i < a[0].Length; i++)
{
if (a[j][i] <= tempmin)
{
tempmin = a[j][i];
b[j] += tempmin;
}
}
}
return b;
}
static void Main()
{
int[][] myArray = Input();
Print2(myArray);
int[] b = new int[myArray.Length];
b = F(myArray);
Print(b);
}
}
I suggest looping over all lines, while tracking all min columns values:
using System.Linq; // for the final `ToArray()`
...
private static int[] MinColumns(int[][] data) {
if (null == data)
throw new ArgumentNullException(nameof(data));
// List of columns' mins; initially the list is empty
List<int> list = new List<int>();
// for each line (not column!) within jagged array...
foreach (int[] line in data) {
// let's just skip null lines (alternative is to throw exception)
if (null == line)
continue;
// each new line can update columns' max values.
// now we update each column
for (int c = 0; c < line.Length; ++c)
// if index c is too big, i.e.
// the line is too long and some columns appear first time...
if (c >= list.Count)
// ...we just add values of such columns as columns' min
for (int i = list.Count; i <= c; ++i)
list.Add(line[i]);
else
// otherwise we update min values: we compare known min and current value
list[c] = Math.Min(list[c], line[c]);
}
// finally, we convert list into array with ahelp of Linq
return list.ToArray();
}
Note, that here we ignore all holes, e.g. for
int[][] demo = new int[][] {
new int[] {1, 2, 3, 4},
new int[] {5, 6}, // <- hole: we don't have 3d and 4th columns here
new int[] {7, 0, 8},
};
the answer will be {Min(1, 5, 7), Min(2, 6, 0), Min(3, 8), Min (4)} = {1, 0, 3, 4}
Edit: Usage is quite direct; something like this (fiddle yourself)
static void Main()
{
// Get jagged array
int[][] myArray = Input();
// Print it
Print2(myArray);
// Get max for each column
int[] b = MinColumns(myArray);
// Print these maxes
Print(b);
}
static void Main(string[] args)
{
char[][] array = {new char[] {'2','A','3','E'},
new char[] {'F','A'},
new char[] {'F','F','F','F'},
new char[] {'5','A','0','E','9'}};
List<double> arr = new List<double>();
List<double> results = new List<double>();
for (int i = 0; i < array.Length; i++)
{
double result = 0;
for (int index = 0; index < **array.Length**; index++)
{
char c = array[i][index];
if (c > 47 && c < 58)
{
arr.Add(c - 48);
}
else
{
arr.Add((c - 65)+10);
}
}
int power = arr.Count();
for (int ind = 0; ind < power; ind++)
{
arr[ind] = Math.Pow(16, power - 1) * arr[ind];
power--;
result += arr[ind];
}
arr = new List<double>();
results.Add(result);
}
}
My goal is to convert these HEX numeric system numbers to Decimal numeric system numbers.
I know the easy and short way using Console.WriteLine()methods and Standard Numeric Format Strings, but the point is to do this hard way(using jagged arrays). All code work properly , but i dont know how to do change(or get current) value length of different inner arrays in jagged array. If i do it this way usign array.Length - it stay static and doesnt change like i need. I try to use array.GetLength(i) but it dosent work 2.
for (int i = 0; i < array.Length; i++)
...
for (int index = 0; index < **array.Length**; index++)
To get the required length, try
for (int i = 0; i < array.Length; i++)
...
for (int index = 0; index < array[i].Length**; index++)
You are checking the length of the outer array (array.Length), while you meant to read the size of the second, inner array (array[i].Length). Try this:
for (int i = 0; i < array.Length; i++)
{
double result = 0;
for (int index = 0; index < array[i].Length; index++)
I would prefer for each
var array = new[]{new[] {'2','A','3','E'},
new[] {'F','A'},
new[] {'F','F','F','F'},
new[] {'5','A','0','E','9'}};
foreach (var item in array)
{
Console.WriteLine(item.Length);
}
I am wanting to create multiple arrays of ints(in C#). However they all must have a unique number in the index, which no other array has that number in that index. So let me try show you what I mean:
int[] ints_array = new int[30];
for (int i = 0; i < ints_array.Count(); i++)
ints_array[i] = i;
//create a int array with 30 elems with each value increment by 1
List<int[]> arrayList = new List<int[]>();
for(int i = 0; i < ints_array.Count(); i++)
arrayList.Add(ints_array[i]. //somehow sort the array here randomly so it will be unique
So I am trying to get the arrayList have 30 int[] arrays and each is sorted so no array has the same int in the same index as another.
Example:
arrayList[0] = {5,2,3,4,1,6,7,8,20,21... etc }
arrayList[1] = {1,0,5,2,9,10,29,15,29... etc }
arrayList[2] = {0,28,4,7,29,23,22,17... etc }
So would this possible to sort the array in this unique kind of way? If you need anymore information just ask and ill fill you in :)
Wouldn't it be easier to create the arrays iteratively using an offset pattern?
What I mean is that if you created the first array using 1-30 where 1 is at index 0, the next array could repeat this using 2-30 where 2 is at index 0 and then wrap back to 1 and start counting forward again as soon as you go past 30. It would be an easy and repeatable way to make sure no array shared the same value/index pair.
You can do it like that:
List<int[]> arrayList = new List<int[]>();
Random rnd = new Random();
for (int i = 0; i < ints_array.Length; i++)
{
ints_array = ints_array.OrderBy(x => rnd.Next()).ToArray();
var isDuplicate = arrayList.Any(x => x.SequenceEqual(ints_array));
if (isDuplicate)
{
while (arrayList.Any(x => x.SequenceEqual(ints_array)))
{
ints_array = ints_array.OrderBy(x => rnd.Next()).ToArray();
}
}
arrayList.Add(ints_array);
}
I think, this wouldn't be so efficient for bigger numbers than 30.But in this case it shouldn't be a problem, in my machine it takes 7 milliseconds.
Jesse's idea would be best unless you needed a pure random pattern. In that case I would recommend generating a random number, checking all your previous arrays, and then placing it in an array if it did not match any other arrays current index. Otherwise, generate a new random number until you find a fresh one. Put that into a loop until all your arrays are filled.
Use a matrix (2D-array). It is easier to handle than a list of arrays. Create a random number generator. Make sure to initialize it only once, otherwise random number generator may create bad random numbers, if created in too short time intervals, since the slow PC-clock might not have ticked in between. (The actual time is used as seed value).
private static Random random = new Random();
Create two helper arrays with shuffeled indexes for rows and columns:
const int N = 30;
int[] col = CreateUniqueShuffledValues(N);
int[] row = CreateUniqueShuffledValues(N);
Then create and initialize the matrix by using the shuffeled row and column indexes:
// Create matrix
int[,] matrix = new int[N, N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
matrix[row[i], col[j]] = (i + j) % N;
}
}
The code uses these two helper methods:
private static int[] CreateUniqueShuffledValues(int n)
{
// Create and initialize array with indexes.
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = i;
}
// Shuffel array using one variant of Fisher–Yates shuffle
// http://en.wikipedia.org/wiki/Fisher-Yates_shuffle#The_modern_algorithm
for (int i = 0; i < n; i++) {
int j = random.Next(i, n);
Swap(array, i, j);
}
return array;
}
private static void Swap(int[] array, int i, int j)
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
int size = 10;
// generate table (no duplicates in rows, no duplicates in columns)
// 0 1 2
// 1 2 0
// 2 0 1
int[,] table = new int[size, size];
for (int y = 0; y < size; y++)
for (int x = 0; x < size; x++)
table[y, x] = (y + x) % size;
// shuffle rows
Random rnd = new Random();
for (int i = 0; i < size; i++)
{
int y1 = rnd.Next(0, size);
int y2 = rnd.Next(0, size);
for (int x = 0; x < size; x++)
{
int tmp = table[y1, x];
table[y1, x] = table[y2, x];
table[y2, x] = tmp;
}
}
// shuffle columns
for (int i = 0; i < size; i++)
{
int x1 = rnd.Next(0, size);
int x2 = rnd.Next(0, size);
for (int y = 0; y < size; y++)
{
int tmp = table[y, x1];
table[y, x1] = table[y, x2];
table[y, x2] = tmp;
}
}
// sample output
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
Console.Write("{0} ", table[y, x]);
Console.WriteLine();
}
I have a two-dimensional array (of Strings) which make up my data table (of rows and columns). I want to sort this array by any column. I tried to find an algorithm for doing this in C#, but have not been successful.
Any help is appreciated.
Can I check - do you mean a rectangular array ([,])or a jagged array ([][])?
It is quite easy to sort a jagged array; I have a discussion on that here. Obviously in this case the Comparison<T> would involve a column instead of sorting by ordinal - but very similar.
Sorting a rectangular array is trickier... I'd probably be tempted to copy the data out into either a rectangular array or a List<T[]>, and sort there, then copy back.
Here's an example using a jagged array:
static void Main()
{ // could just as easily be string...
int[][] data = new int[][] {
new int[] {1,2,3},
new int[] {2,3,4},
new int[] {2,4,1}
};
Sort<int>(data, 2);
}
private static void Sort<T>(T[][] data, int col)
{
Comparer<T> comparer = Comparer<T>.Default;
Array.Sort<T[]>(data, (x,y) => comparer.Compare(x[col],y[col]));
}
For working with a rectangular array... well, here is some code to swap between the two on the fly...
static T[][] ToJagged<T>(this T[,] array) {
int height = array.GetLength(0), width = array.GetLength(1);
T[][] jagged = new T[height][];
for (int i = 0; i < height; i++)
{
T[] row = new T[width];
for (int j = 0; j < width; j++)
{
row[j] = array[i, j];
}
jagged[i] = row;
}
return jagged;
}
static T[,] ToRectangular<T>(this T[][] array)
{
int height = array.Length, width = array[0].Length;
T[,] rect = new T[height, width];
for (int i = 0; i < height; i++)
{
T[] row = array[i];
for (int j = 0; j < width; j++)
{
rect[i, j] = row[j];
}
}
return rect;
}
// fill an existing rectangular array from a jagged array
static void WriteRows<T>(this T[,] array, params T[][] rows)
{
for (int i = 0; i < rows.Length; i++)
{
T[] row = rows[i];
for (int j = 0; j < row.Length; j++)
{
array[i, j] = row[j];
}
}
}
Load your two-dimensional string array into an actual DataTable (System.Data.DataTable), and then use the DataTable object's Select() method to generate a sorted array of DataRow objects (or use a DataView for a similar effect).
// assumes stringdata[row, col] is your 2D string array
DataTable dt = new DataTable();
// assumes first row contains column names:
for (int col = 0; col < stringdata.GetLength(1); col++)
{
dt.Columns.Add(stringdata[0, col]);
}
// load data from string array to data table:
for (rowindex = 1; rowindex < stringdata.GetLength(0); rowindex++)
{
DataRow row = dt.NewRow();
for (int col = 0; col < stringdata.GetLength(1); col++)
{
row[col] = stringdata[rowindex, col];
}
dt.Rows.Add(row);
}
// sort by third column:
DataRow[] sortedrows = dt.Select("", "3");
// sort by column name, descending:
sortedrows = dt.Select("", "COLUMN3 DESC");
You could also write your own method to sort a two-dimensional array. Both approaches would be useful learning experiences, but the DataTable approach would get you started on learning a better way of handling tables of data in a C# application.
Array.Sort(array, (a, b) => { return a[0] - b[0]; });
Here is an archived article from Jim Mischel at InformIt that handles sorting for both rectangular and jagged multi-dimensional arrays.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int[,] arr = { { 20, 9, 11 }, { 30, 5, 6 } };
Console.WriteLine("before");
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
Console.Write("{0,3}", arr[i, j]);
}
Console.WriteLine();
}
Console.WriteLine("After");
for (int i = 0; i < arr.GetLength(0); i++) // Array Sorting
{
for (int j = arr.GetLength(1) - 1; j > 0; j--)
{
for (int k = 0; k < j; k++)
{
if (arr[i, k] > arr[i, k + 1])
{
int temp = arr[i, k];
arr[i, k] = arr[i, k + 1];
arr[i, k + 1] = temp;
}
}
}
Console.WriteLine();
}
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
Console.Write("{0,3}", arr[i, j]);
}
Console.WriteLine();
}
}
}
}
This code should do what you are after, I haven't generalised it for n by n, but that is straight forward. That said - I agree with MusiGenesis, using another object that is a little better suited to this (especially if you intend to do any sort of binding)
(I found the code here)
string[][] array = new string[3][];
array[0] = new string[3] { "apple", "apple", "apple" };
array[1] = new string[3] { "banana", "banana", "dog" };
array[2] = new string[3] { "cat", "hippo", "cat" };
for (int i = 0; i < 3; i++)
{
Console.WriteLine(String.Format("{0} {1} {2}", array[i][0], array[i][1], array[i][2]));
}
int j = 2;
Array.Sort(array, delegate(object[] x, object[] y)
{
return (x[j] as IComparable).CompareTo(y[ j ]);
}
);
for (int i = 0; i < 3; i++)
{
Console.WriteLine(String.Format("{0} {1} {2}", array[i][0], array[i][1], array[i][2]));
}
Can allso look at Array.Sort Method http://msdn.microsoft.com/en-us/library/aa311213(v=vs.71).aspx
e.g. Array.Sort(array, delegate(object[] x, object[] y){ return (x[ i ] as IComparable).CompareTo(y[ i ]);});
from http://channel9.msdn.com/forums/Coffeehouse/189171-Sorting-Two-Dimensional-Arrays-in-C/
So your array is structured like this (I'm gonna talk in pseudocode because my C#-fu is weak, but I hope you get the gist of what I'm saying)
string values[rows][columns]
So value[1][3] is the value at row 1, column 3.
You want to sort by column, so the problem is that your array is off by 90 degrees.
As a first cut, could you just rotate it?
std::string values_by_column[columns][rows];
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
values_by_column[column][row] = values[row][column]
sort_array(values_by_column[column])
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
values[row][column] = values_by_column[column][row]
If you know you only want to sort one column at a time, you could optimize this a lot by just extracting the data you want to sort:
string values_to_sort[rows]
for (int i = 0; i < rows; i++)
values_to_sort[i] = values[i][column_to_sort]
sort_array(values_to_sort)
for (int i = 0; i < rows; i++)
values[i][column_to_sort] = values_to_sort[i]
In C++ you could play tricks with how to calculate offsets into the array (since you could treat your two-dimensional array as a one-d array) but I'm not sure how to do that in c#.
Try this out. The basic strategy is to sort the particular column independently and remember the original row of the entry. The rest of the code will cycle through the sorted column data and swap out the rows in the array. The tricky part is remembing to update the original column as the swap portion will effectively alter the original column.
public class Pair<T> {
public int Index;
public T Value;
public Pair(int i, T v) {
Index = i;
Value = v;
}
}
static IEnumerable<Pair<T>> Iterate<T>(this IEnumerable<T> source) {
int index = 0;
foreach ( var cur in source) {
yield return new Pair<T>(index,cur);
index++;
}
}
static void Sort2d(string[][] source, IComparer comp, int col) {
var colValues = source.Iterate()
.Select(x => new Pair<string>(x.Index,source[x.Index][col])).ToList();
colValues.Sort((l,r) => comp.Compare(l.Value, r.Value));
var temp = new string[source[0].Length];
var rest = colValues.Iterate();
while ( rest.Any() ) {
var pair = rest.First();
var cur = pair.Value;
var i = pair.Index;
if (i == cur.Index ) {
rest = rest.Skip(1);
continue;
}
Array.Copy(source[i], temp, temp.Length);
Array.Copy(source[cur.Index], source[i], temp.Length);
Array.Copy(temp, source[cur.Index], temp.Length);
rest = rest.Skip(1);
rest.Where(x => x.Value.Index == i).First().Value.Index = cur.Index;
}
}
public static void Test1() {
var source = new string[][]
{
new string[]{ "foo", "bar", "4" },
new string[] { "jack", "dog", "1" },
new string[]{ "boy", "ball", "2" },
new string[]{ "yellow", "green", "3" }
};
Sort2d(source, StringComparer.Ordinal, 2);
}
If you could get the data as a generic tuple when you read it in or retrieved it, it would be a lot easier; then you would just have to write a Sort function that compares the desired column of the tuple, and you have a single dimension array of tuples.
This is an old question, but here's a class I just built based on the article from Jim Mischel at InformIt linked by Doug L.
class Array2DSort : IComparer<int>
{
// maintain a reference to the 2-dimensional array being sorted
string[,] _sortArray;
int[] _tagArray;
int _sortIndex;
protected string[,] SortArray { get { return _sortArray; } }
// constructor initializes the sortArray reference
public Array2DSort(string[,] theArray, int sortIndex)
{
_sortArray = theArray;
_tagArray = new int[_sortArray.GetLength(0)];
for (int i = 0; i < _sortArray.GetLength(0); ++i) _tagArray[i] = i;
_sortIndex = sortIndex;
}
public string[,] ToSortedArray()
{
Array.Sort(_tagArray, this);
string[,] result = new string[
_sortArray.GetLength(0), _sortArray.GetLength(1)];
for (int i = 0; i < _sortArray.GetLength(0); i++)
{
for (int j = 0; j < _sortArray.GetLength(1); j++)
{
result[i, j] = _sortArray[_tagArray[i], j];
}
}
return result;
}
// x and y are integer row numbers into the sortArray
public virtual int Compare(int x, int y)
{
if (_sortIndex < 0) return 0;
return CompareStrings(x, y, _sortIndex);
}
protected int CompareStrings(int x, int y, int col)
{
return _sortArray[x, col].CompareTo(_sortArray[y, col]);
}
}
Given an unsorted 2D array data of arbitrary size that you want to sort on column 5 you just do this:
Array2DSort comparer = new Array2DSort(data, 5);
string[,] sortedData = comparer.ToSortedArray();
Note the virtual Compare method and protected SortArray so you can create specialized subclasses that always sort on a particular column or do specialized sorting on multiple columns or whatever you want to do. That's also why CompareStrings is broken out and protected - any subclasses can use it for simple comparisons instead of typing out the full SortArray[x, col].CompareTo(SortArray[y, col]) syntax.
I like the DataTable approach proposed by MusiGenesis above. The nice thing about it is that you can sort by any valid SQL 'order by' string that uses column names, e.g. "x, y desc, z" for 'order by x, y desc, z'. (FWIW, I could not get it to work using column ordinals, e.g. "3,2,1 " for 'order by 3,2,1') I used only integers, but clearly you could add mixed type data into the DataTable and sort it any which way.
In the example below, I first loaded some unsorted integer data into a tblToBeSorted in Sandbox (not shown). With the table and its data already existing, I load it (unsorted) into a 2D integer array, then to a DataTable. The array of DataRows is the sorted version of DataTable. The example is a little odd in that I load my array from the DB and could have sorted it then, but I just wanted to get an unsorted array into C# to use with the DataTable object.
static void Main(string[] args)
{
SqlConnection cnnX = new SqlConnection("Data Source=r90jroughgarden\\;Initial Catalog=Sandbox;Integrated Security=True");
SqlCommand cmdX = new SqlCommand("select * from tblToBeSorted", cnnX);
cmdX.CommandType = CommandType.Text;
SqlDataReader rdrX = null;
if (cnnX.State == ConnectionState.Closed) cnnX.Open();
int[,] aintSortingArray = new int[100, 4]; //i, elementid, planid, timeid
try
{
//Load unsorted table data from DB to array
rdrX = cmdX.ExecuteReader();
if (!rdrX.HasRows) return;
int i = -1;
while (rdrX.Read() && i < 100)
{
i++;
aintSortingArray[i, 0] = rdrX.GetInt32(0);
aintSortingArray[i, 1] = rdrX.GetInt32(1);
aintSortingArray[i, 2] = rdrX.GetInt32(2);
aintSortingArray[i, 3] = rdrX.GetInt32(3);
}
rdrX.Close();
DataTable dtblX = new DataTable();
dtblX.Columns.Add("ChangeID");
dtblX.Columns.Add("ElementID");
dtblX.Columns.Add("PlanID");
dtblX.Columns.Add("TimeID");
for (int j = 0; j < i; j++)
{
DataRow drowX = dtblX.NewRow();
for (int k = 0; k < 4; k++)
{
drowX[k] = aintSortingArray[j, k];
}
dtblX.Rows.Add(drowX);
}
DataRow[] adrowX = dtblX.Select("", "ElementID, PlanID, TimeID");
adrowX = dtblX.Select("", "ElementID desc, PlanID asc, TimeID desc");
}
catch (Exception ex)
{
string strErrMsg = ex.Message;
}
finally
{
if (cnnX.State == ConnectionState.Open) cnnX.Close();
}
}
I know its late but here is my thought you might wanna consider.
for example this is array
{
m,m,m
a,a,a
b,b,b
j,j,j
k,l,m
}
and you want to convert it by column number 2, then
string[] newArr = new string[arr.length]
for(int a=0;a<arr.length;a++)
newArr[a] = arr[a][1] + a;
// create new array that contains index number at the end and also the column values
Array.Sort(newArr);
for(int a=0;a<newArr.length;a++)
{
int index = Convert.ToInt32(newArr[a][newArr[a].Length -1]);
//swap whole row with tow at current index
if(index != a)
{
string[] arr2 = arr[a];
arr[a] = arr[index];
arr[index] = arr2;
}
}
Congratulations you have sorted the array by desired column. You can edit this to make it work with other data types
Short way, but be careful of performance in big arrays and must have n-count of columns:
This will order it from the last number to the first. In case of need reverse it from 0 to "hero":
for (int i = n-1; i >= 0; i--)
{
resultsAsArray = resultsAsArray.OrderBy(x => x[i]).ToArray();
}
Example (do not be surprised, that 3 is first, 2 after that - those are negative, so -3 is lesser than -2)
var original = new int[][] { new int[] { -3, 1, 2 }, new int[] { -2, -1, 3 }, new int[] { -3, -1, 4 }, new int[] { -3, -2, 5 } };
*var processed = new int[][] { new int[] { -3, -2, 5 }, new int[] { -3, -1, 4 }, new int[] { -3, 1, 2 }, new int[] { -2, -1, 3 } };
Assuming it is a jagged array, you can use LINQ or Array.Sort() method to sort it.
Method 1: Using LINQ
var myOrderedRows = myArray.OrderBy(row => row[columnIndex]).ToArray();
Here, LINQ creates a new IEnumerable which needs to be converted to array (using ToArray()) myOrderedRows. Your original array is still unsorted. More details can be found in docs here.
Method 2: Using Array.Sort()
Array.Sort(myArray, (p, q) => p[columnIndex].CompareTo(q[columnIndex]));
In this case your original array is sorted in place. You can also provide custom Comparer for more comparison rules. More details can be found in docs here.