I seem to have trouble converting a character array to a 2D integer array. The specifics are as follows:
I want to convert a character array that contains a specific delimiter to a multidimensional array in which the end of each row is specified by the delimiter found inside the character array ( I have already made sure in a different method that every row has the same length).
The array contains only 0s and 1s.
The problem is that when testing the method it appears that it (the method) skips a row - reads the first row, the next row is 0s, reads the third row, the fourth is 0s.
These are the methods (the method in question and the testing method):
/// <summary>
/// Converts a character array to 2D int array, where each character is a digit and only the digits of 1 and 0 are
/// allowed.
/// </summary>
/// <returns>The 2D int array.</returns>
/// <param name="charArray">Character array.</param>
/// <param name="delimiter">Delimiter.</param>
public int[,] ConvertCharArrayTo2DIntArray(char[] charArray, char delimiter){
int columnCounter = 0;
//count how many rows
while (charArray [columnCounter] != delimiter) {
columnCounter++;
}
//count how many lines taking into account the delimiter
int rows = charArray.Length/(columnCounter+1);
int[,] twoDimArray = new int[rows, columnCounter];
//count
int h = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columnCounter; j++) {
if (charArray [h] != '\n') {
twoDimArray [i, j] = (int)Char.GetNumericValue(charArray [h]);
//throw exception if the array contains numbers other than 1 or 0
if (twoDimArray [i, j] != 1 && twoDimArray [i, j] != 0)
throw new ArgumentException ();
h++;
} else {
h++;
break;
}
}
}
return twoDimArray;
}
This is the testing method:
[Test()]
public void TestConvertCharArrayTo2DIntArray(){
HelperClass hc = new HelperClass ();
int[,] twoDimArrayExpected = new int[,]{
{ 0, 1, 0, 1, 0 },
{ 0, 1, 0, 1, 0 },
{ 0, 1, 0, 1, 0 },
{ 0, 1, 0, 1, 0 } };
char[] charArray = new char[] {'0','1','0','1','1','\n','1','1','1','1','1','\n','0','1','1','1','0','\n','0','1','0','1','0','\n'};
int[,] twoDimArrayActual = hc.ConvertCharArrayTo2DIntArray (charArray, '\n');
for (int i = 0; i < twoDimArrayExpected.GetLength (0); i++) {
for (int j = 0; j < twoDimArrayExpected.GetLength (1); j++) {
Console.Write (twoDimArrayActual [i,j]);
//Commented out because it throws exceptions
//Assert.AreEqual(twoDimArrayExpected[i,j],
//twoDimArrayActual[i,j]);
if (j == twoDimArrayExpected.GetLength (1) - 1) {
Console.Write ("\n");
}
}
}
}
The output is this:
01011
00000
11111
00000
I may simply be stuck, but right now I really can't figure this out.
When the inner loop ends, you are positioned on the delimiter. This is the point where you need to skip the character delimiter incrementing the control variable h
As you do now, you increment the control variable but then you break out of the inner loop. Just removing the break instructon however doesn't work because exiting the inner loop increments the control variable iof the outer loop leaving every even row empty and unprocessed
You could try to fix your code with
int h = 0;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columnCounter; j++)
{
twoDimArray[i, j] = (int)Char.GetNumericValue(charArray[h]);
//throw exception if the array contains numbers other than 1 or 0
if (twoDimArray[i, j] != 1 && twoDimArray[i, j] != 0)
throw new ArgumentException();
h++;
}
h++;
}
Real easy if you use a list object
List<List<int>> twoDimArrayExpected = new List<List<int>>() {
new List<int>() { 0, 1, 0, 1, 0 },
new List<int>(){ 0, 1, 0, 1, 0 },
new List<int>(){ 0, 1, 0, 1, 0 },
new List<int>(){ 0, 1, 0, 1, 0 } };
string resutls = string.Join("\n", twoDimArrayExpected.Select(x => string.Join("", x)));
Related
The wished output is a lot of array that looks like this:
public decimal [] array 1 = {1, 1, 0, 0, 0};
public decimal [] array 2 = {0, 1, 1, 0, 0};
public decimal [] array 3 = {0, 0, 1, 1, 0};
public decimal [] array 4 = {0, 0, 0, 1, 1};
The dimension does not fit my problem, because the problem demands a array of 14 elements, but the idear is the same. The question is how do I create this in a smart way. I tried a "for loop" creating array 1, but as the loop carried on it overwrote array 1 with array 2:
class Program
{
public decimal[] array_1 = { 0, 0, 0, 0, 0 };
public void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
if (i == 0)
{
array_1 [i] = 1;
array_1 [i + 1] = 1;
}
else if (i == 1)
{
array_1[i] = 1;
array_1[i + 1] = 1;
}
else if (i == 2)
{
array_1[i] = 1;
array_1[i + 1] = 1;
}
else if (i == 3)
{
array_1[i] = 1;
array_1[i + 1] = 1;
}
else if (i == 4)
{
array_1[i] = 1;
array_1[i + 1] = 1;
}
}
}
}
The output of the above is a array with only ones and not four different arrays as firstly wished.
decimal[][] arrays = { array_1, array_2, array_3, array_4 };
for (int a = 0; a < arrays.Length; a++) {
for (int i = 0; i < arrays[a].Length; i++) {
arrays[a][i] = i == a || i == a+1 ? 1 : 0;
}
}
Or, you can create one two-dimensional array:
decimal[,] array = new decimal[4, 5];
for (int row = 0; row < array.GetLength(0); row++) {
for (int column = 0; column < array.GetLength(1); column++) {
array[row, column] = column == row || column == row+1 ? 1 : 0;
}
}
Use multidimensional array:
class Program
{
public decimal[,] arrayObj = new decimal[5, 5];
public void Main(string[] args)
{
for (int i = 0; i < 4; i++)
{
arrayObj[i][i] = 1;
arrayObj[i+1] = 1;
}
}
If you want a collection (say, decimal[][] - jagged array) of arrays, I suggest using Linq:
int n = 4;
decimal[][] arrays = Enumerable.Range(1, n)
.Select(index => Enumerable
.Range(1, n + 1)
.Select(x => (decimal) (x == index || x == index + 1 ? 1 : 0))
.ToArray())
.ToArray();
and then use the collection
decimal array1 = arrays[0];
Test
string report = string.Join(Environment.NewLine, arrays
.Select(array => string.Join(" ", array)));
Outcome:
1 1 0 0 0
0 1 1 0 0
0 0 1 1 0
0 0 0 1 1
If you insist on 2d array:
int n = 4;
decimal[,] arrays = new decimal[n, n + 1];
for (int i = 0; i < arrays.GetLength(0); ++i) {
arrays[i, i] = 1;
arrays[i, i + 1] = 1;
}
sorry for noob question :). I've got 2d array 3x3 filled with random numbers (-5,5)
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
{
dPole[i, j] = nc.Next(-10, 10);
I want all the numbers that are positive and then save them into 1d array:
foreach (int j in dPole)
{
if (j > 0)
{
Console.WriteLine(j);
for (int i = 0; i < sizeOf1dArray; i++)
jPole[i] = j;
}
}
Output of Console.WriteLine(j)- to check if the condition is right:
6
2
5
6
9
8
Output of 1d Array:
8
8
8
8
8
8
Only the last number is saved into array. Why? Thanks.
An alternative route would be to use Cast<int> to flatten the array and use Where to filter.
int[,] dPole = new int[,] { { 3, -5, 0 }, { -3, 3, 2 }, { -2, 1, 1 } };
int[] jPole = dPole.Cast<int>().Where(i => i > 0).ToArray();
// jPole is now { 3, 3, 2, 1, 1 };
for (int i = 0; i < sizeOf1dArray; i++)
jPole[i] = j;
because at this loop action last j value is 8 and this loop fills all jPole array with j value every time, that means it fills all with 6 first, than puts 2 at entire array, then 5...... and for last it fills it with 8.
try something like that
int i = 0;
foreach (int j in dPole)
{
if (j > 0)
{
Console.WriteLine(j);
jPole[i] = j;
i++;
}
}
I Have an array, TempArray[] = {1,3,-1,5,7,-1,4,10,9,-1}
I want to remove every single -1 from this array and copy the remaining arrays into a new array called Original, which should output the numbers as 1,3,5,7,4,10,9
I can only use an if statement within a for loop!
This is what I have so far, but I keep getting an error message, System.IndexOutOfRangeException
for (int i = 0; i < TempArray.Length; i++)
{
if (TempArray[i] != -1)
{
//error occurs at this line
//My attempt is to set the new array, Original[i] equal to TempArray[i] only where the values are not -1.
TempArray[i] = Original[i];
}
}
If you can only use If statement in for loop. This looks like a school project. First you count how many non negative numbers are there in your array. Create new array with that length and fill that array.
int[] TempArray = new int[] {1,3,-1,5,7,-1,4,10,9,-1};
int[] Original ;
int countNonNegative=0;
for (int i = 0; i < TempArray.Length; i++)
{
if (TempArray[i] != -1)
{
countNonNegative++;
}
}
Original = new int[countNonNegative];
int index=0;
for (int i = 0; i < TempArray.Length; i++)
{
if (TempArray[i] != -1)
{
Original[index] = TempArray[i];
index++;
}
}
Console.WriteLine("Original Length = "+Original.Length);
using System.Linq;
int[] withoutNegativeOnes = myArray
.Where(a => a != -1)
.ToArray();
var Original = new int[TempArray.Length];
var originalCounter = 0;
for (int i = 0; i < TempArray.Length; i++)
{
if (TempArray[i] != -1)
{
Original[originalCounter++] = TempArray[i];
}
}
Now Original may contain empty spaces at the end though, but you have all the elements which aren't -1. You can use the following code to iterate through the values:
for (int i = 0; i < originalCounter; i++)
{
Console.WriteLine(Original[i]);
}
and that's because the originalCounter has the last index values that wasn't filled from TempArray's iteration.
try this one
int[] TempArray = { 1, 3, -1, 5, 7, -1, 4, 10, 9, -1 };
int[] original = TempArray.Where(i => i != -1).ToArray();
foreach(int i in original)
Console.WriteLine(i.ToString());
If I have the following array
{ 1, 0, 0, 1, 2, 0, 1 }
And I want a method that will take the array and change it to
{ 1, 1, 2, 1, 0, 0, 0 }
What would be the best algorithm to do this? Is it possible to do this in O(N) time?
this question is essentially my exact question except in python not c#, in case I was not clear: (only difference is move the zeros to the right, not left)
how to move all non-zero elements in a python list or numpy array to one side?
Thanks
EDIT: I've ran into another problem that I didn't consider at first. I'm actually trying to run this algorithm on a 2d array, but only on one particular dimension. how would I change to account for this?
Here's a way you could do it.
var original = new int[] { 1, 0, 0, 1, 2, 0, 1 };
var nonZeroes = original.Where(x => x != 0); //enumerate once
var numberOfZeroes = original.Count() - nonZeroes.Count();
return nonZeroes.Concat(Enumerable.Repeat(0, numberOfZeroes)).ToArray();
UPDATED FOR 2D ARRAY
int[,] array =
{
{ 1, 0, 0, 1, 2, 0, 1 }, // Row 0
{ 1, 0, 0, 1, 2, 0, 1 }, // Row 1
{ 1, 0, 0, 1, 2, 0, 1 } // Row 2
};
PullNonZerosToLeft(array, 1);
for (int row = 0; row <= array.GetUpperBound(0); row++)
{
for (int col = 0; col <= array.GetUpperBound(1); col++)
{
Console.Write("{0} ", array[row,col]);
}
Console.WriteLine();
}
PullNonZerosToLeft()
public static void PullNonZerosToLeft(int[,] array, int row)
{
if (row > array.GetUpperBound(0))
{
return;
}
// Used to keep track of the swap point
int index = 0;
for (int i = 0; i <= array.GetUpperBound(1); i++)
{
if (array[row, i] == 0)
{
continue;
}
int temp = array[row, i];
array[row, i] = array[row, index];
array[row, index] = temp;
index++;
}
}
Results:
1 0 0 1 2 0 1
1 2 1 1 0 0 0
1 0 0 1 2 0 1
UPDATED FOR JAGGED ARRAY
A non-Linq approach, where you swap all non-zero elements with zero elements.
int[][] array =
{
new[] { 1, 0, 0, 1, 2, 0, 1 }, // Row 0
new[] { 1, 0, 0, 1, 2, 0, 1 }, // Row 1
new[] { 1, 0, 0, 1, 2, 0, 1 } // Row 2
};
PullNonZerosToLeft(array, 1);
foreach (int[] row in array)
{
Console.WriteLine(String.Join(", ", row));
}
PullNonZerosToLeft()
public static void PullNonZerosToLeft(int[][] array, int row)
{
if (row >= array.Length)
{
return;
}
// Used to keep track of the swap point
int index = 0;
for (int i = 0; i < array[row].Length; i++)
{
if (array[row][i] == 0)
{
continue;
}
int temp = array[row][i];
array[row][i] = array[row][index];
array[row][index] = temp;
index++;
}
}
Results:
1, 0, 0, 1, 2, 0, 1
1, 1, 2, 1, 0, 0, 0
1, 0, 0, 1, 2, 0, 1
It is possible to do it in O(n) time and O(1) space complexity.
Start with a low pointer at 0 and a high pointer at last index of the array.
Algorithm:
1. Increment low till you find 0, decrement high till you find a non-zero number.
2. Swap Array[low] and Array[high].
3. Repeat steps 1 and 2 till low is less than high.
You can just order by n == 0.
var original = new int[] { 1, 0, 0, 1, 2, 0, 1 };
var result = original.OrderBy(n => n == 0).ToArray();
Here's a way to do it in O(n) time by creating a new array. Note that this avoids the penalty of looping through the array a second time to get the count of zeros, as in Dleh's answer.
public static int[] PushNonZeroToLeft(int[] aiArray)
{
var alNew = new List<int>();
var iZeroCount = 0;
foreach (int i in aiArray)
if (i > 0)
alNew.Add(i);
else
iZeroCount++;
alNew.AddRange(Enumerable.Repeat(0, iZeroCount));
return alNew.ToArray();
}
Not sure if O(n) can be achieved if you have to mutate the original array...
Here's an O(n) time, O(1) space algorithm for doing what you want. It will also preserve the order of the non-zero elements.
var array = new []{ 1, 3, 3, 1, 2, 0, 1 };
int j = 0;
for( int i = 0; i < array.Length && j < array.Length; ++i )
{
if( array[i] != 0 ) continue;
if( j <= i ) j = i + 1;
while( j < array.Length && array[j] == 0 ) ++j;
if( j >= array.Length ) break;
var t = array[i];
array[i] = array[j];
array[j] = t;
}
This is how I'd approach it. Nice and simple. I didn't run performance tests but would expect it to be a little more performant than some of the suggestions that use LINQ, or create new arrays.
int[] array = { 1, 0, 0, 1, 2, 0, 1 };
for (int i = 0; i < array.Length; i++)
{
if (array[i] == 0)
{
int j;
for (j = i + 1; j < array.Length; j++)
{
if (array[j] != 0)
break;
}
if (j < array.Length)
{
array[i] = array[j];
array[j] = 0;
}
else break;
}
}
Yes, this is possible to do in O(N) time.
Basically:
Loop through the array
For every element you find that is non-zero, copy it
First element should be copied to position 0, next to position 1, etc. Keep track of how far you get with this position.
When you've looped through it, iterate the position you kept track of through the rest of the array until you reach the end, and keep setting elements to zero as you go.
The algorithm will copy, not move, so the 3rd point above will make sure any elements we copied but did not subsequently overwrite will be zeroed out afterwards.
Here's some example code:
int next = 0;
// copy all non-zero elements to the start
foreach (var element in collection)
if (element != 0)
collection[next++] = element;
// fill remainder with zeroes
while (next < collection.Count)
collection[next++] = 0;
How to delete a specific row and column from 2D array in C#?
int[,] array= {{1,2,3},{4,5,6},{7,8,9}};
lets say I want to delete row i and column i (skipping them) ... for nXn array not just 3x3 and store the remaining array in a new array...
so the output would be:
{5,6},{8,9}
There's no built-in way to do that, you can do it yourself:
static void Main()
{
int[,] array = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
var trim = TrimArray(0, 2, array);
}
public static int[,] TrimArray(int rowToRemove, int columnToRemove, int[,] originalArray)
{
int[,] result = new int[originalArray.GetLength(0) - 1, originalArray.GetLength(1) - 1];
for (int i = 0, j = 0; i < originalArray.GetLength(0); i++)
{
if (i == rowToRemove)
continue;
for (int k = 0, u = 0; k < originalArray.GetLength(1); k++)
{
if (k == columnToRemove)
continue;
result[j, u] = originalArray[i, k];
u++;
}
j++;
}
return result;
}
No, arrays don't let you do that. You could make your own data structure for that, but it's not going to be exactly simple (unlike if you only wanted to be able to remove rows, for example).
For simple operations, it would be quite enough to build a class on top of an underlying array, and handle the re-indexing to map the virtual 2D array to the physical array underneath. But it's going to get a bit tricky as you combine removals and additions, and deform the array overall.
Very simple logic. Just play with the loop:
int[,] array = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int[,] arrayskip = new int[array.GetLength(0) - 1, array.GetLength(1) - 1];
for (int i = 1; i < array.GetLength(0); i++)
{
for (int j = 1; j < array.GetLength(1); j++)
{
arrayskip[i - 1, j - 1] = array[i, j];
}
}
I created this method, have a look
public static double[,] fillNewArr(double[,] originalArr, int row, int col)
{
double[,] tempArray = new double[originalArr.GetLength(0) - 1, originalArr.GetLength(1) - 1];
int newRow = 0;
int newCol = 0;
for (int i = 0; i < originalArr.GetLength(0); i++)
{
for (int j = 0; j < originalArr.GetLength(1); j++)
{
if(i != row && j != col)
{
tempArray[newRow, newCol] = originalArr[i, j];
newRow++;
newCol++;
}
}
}
return tempArray;
}
having some out of range, It's obvious why but I'm trying to get there...