How is my boundaries outside of the array? - c#

On my array, on line 40, my boundaries are outside of the array, but I am not sure how to format this since this is my first program with a multi dimensional array. Please help me. Thanks! (Line 40 is array[i, 0] = randomArray.Next(0, 100);)
namespace Exercise6
{
class Program
{
static void Main(string[] args)
{
OtherClass aTable = new OtherClass(); //instantiate class
Console.WriteLine("How many rows do you want your two-dimensional array to be?");
aTable.SRows = Console.ReadLine(); //reads input for how many rows that the user would like
aTable.IntRows = int.Parse(aTable.SRows); //convert rows to int
Console.WriteLine("Thanks you! How many columns would you like your two-dimensional arry to be?");
aTable.SColumns = Console.ReadLine(); //reads input for how many columns that the user would like
aTable.IntColumns = int.Parse(aTable.SColumns); //convert columns to int
//set two dimensional array based upon the size that the user has requested
int[ , ] array = new int[aTable.IntColumns, aTable.IntRows];
Random randomArray = new Random(); //call to random class to ask for random numbers
for (int i = 0; i <= aTable.IntColumns; i++) // rows
{
array[i, 0] = randomArray.Next(0, 100); // for every value in each row, insert a random number
}
//both arrays here are overloaded. See this site to see if can get help. Site is below after last close loop
for (int y = 0; y <= aTable.IntRows; y++) // columns
{
array[y, y] = randomArray.Next(0, 100);
}
Console.WriteLine(array);
}
}
}
namespace Exercise6
{
class OtherClass
{
private string sRows;
public string SRows { get; set; }
private int intRows;
public int IntRows { get; set; }
private string sColumns;
public string SColumns { get; set; }
private int intColumns;
public int IntColumns { get; set; }
}
}

Change loop condition to i < aTable.IntColumns
You loop starts from 0 and goes to value of aTable.IntColumns - 1
and code becomes
for (int i = 0; i < aTable.IntColumns; i++)
{
array[i, 0] = randomArray.Next(0, 100);
}

Since arrays are zero based, you can't go up to the max value:
// This line is incorrect
for (int i = 0; i <= aTable.IntColumns; i++)
That line should be:
for (int i = 0; i < aTable.IntColumns; i++)
That will let it go from 0 to aTable.IntColumns-1, which are the valid indices for for an array of aTable.IntColumns length. The same is true of the rows.

C# arrays used zero-relative offsets as their indices. That means that for an array of length n, the domain of its index i is 0 <= i <= n-1. A 100-element array has an index that ranges from 0-99. If you are trying to fill an m*n array with random values.
If your assignment is fill the array with random values (as seems likely), you'll need to do something like this:
for ( int i=0 ; i < aTable.IntRows ; i++ ) // rows
{
for ( int j= 0 ; i < aTable.IntColumns ; j++ )
{
array[i,j] = randomArray.Next(0,100); // for every value in each row, insert a random number
}
}
You might also note that your comments don't match your code: you are iterating over rows and checking the column limit and vice-versa.

The error is in for loop:
for (int i = 0; i < aTable.IntColumns; i++) // rows
{
array[i, 0] = randomArray.Next(0, 100); // for every value in each row, insert a random number
}
i < aTable.IntColumns should be the stopping criteria

Related

Simple Selection Sort won't sort

I'm new to algorithms and I tried to write a selection sort. With some help from the internet I have a script that should work, but doesn't. The result after the sort method is a list that is still unsorted.
I'm not sure if I missed anything and my code looks the same as the ones online.
Product.cs
public class Product
{
public string Name { get; set; }
public double Price { get; set; }
}
Order.cs
public class Order
{
public List<Product> listOfProducts = new List<Product>(){
new Product(){ Name="Item1", Price=2.55 },
new Product(){ Name="Item2", Price=1.92 },
new Product(){ Name="Item3", Price=2.12 }
};
public List<Product> GetAllProducts(){
return this.listOfProducts;
}
public void SortProductsByPrice(){
int min = 0;
for (int i = 0; i < this.listOfProducts.Count - 1; i++)
{
min = i;
for (int j = 0; j < this.listOfProducts.Count; j++)
{
if (listOfProducts[j].Price < listOfProducts[min].Price)
{
min = j;
}
}
Product temporary = listOfProducts[min];
listOfProducts[min] = listOfProducts[i];
listOfProducts[i] = temporary;
}
}
}
Program.cs
static void Main(string[] args)
{
Order order = new Order();
// unsorted list
foreach (Product pro in order.GetAllProducts())
{
Console.WriteLine(pro.Price);
}
Console.WriteLine("------------------------------------------");
order.SortProductsByPrice();
// sorted list
foreach (Product pro in order.GetAllProducts())
{
Console.WriteLine(pro.Price);
}
Console.ReadLine();
}
The problem in your code is in the nested loop.
If you take a closer look at the algorithm, you'll see that:
Selection sort is a simple sorting algorithm. This sorting algorithm is an in-place comparison-based algorithm in which the list is divided into two parts, the sorted part at the left end and the unsorted part at the right end. Initially, the sorted part is empty and the unsorted part is the entire list.
You're re-comparing your values with what you've already sorted, which you should not do. You're not getting a sorted list because by the end of your code, the values are being swapped over and over until they get back to their original order. A simple fix is by changing the nested for loop like this:
public void SortProductsByPrice()
{
int min = 0;
for (int i = 0; i < this.listOfProducts.Count - 1; i++)
{
min = i;
for (int j = i + 1; j < this.listOfProducts.Count; j++)
{
if (listOfProducts[j].Price < listOfProducts[min].Price)
{
min = j;
}
}
Product temporary = listOfProducts[min];
listOfProducts[min] = listOfProducts[i];
listOfProducts[i] = temporary;
}
}
So precisely, we just changed 1 line:
for (int j = i + 1; j < this.listOfProducts.Count; j++)
^^^^^
If you take another look at the pseudo-code in the above link, you'll see that this function now resembles it:
procedure selection sort
list : array of items
n : size of list
for i = 1 to n - 1
/* set current element as minimum*/
min = i
/* check the element to be minimum */
for j = i+1 to n
if list[j] < list[min] then
min = j;
end if
end for
/* swap the minimum element with the current element*/
if indexMin != i then
swap list[min] and list[i]
end if
end for
end procedure

No Output for MergeSort Algorithm c#

In my project I've implemented MergeSort, bubble sort, and sequential search algorithms, however the Merge sort is not giving any output to the console, while the others work. I've tried debugging with no real luck.
public static void mergeSort(int[] a)
{
int inputLength = a.Length;
//sets the middle index to the total length divided by 2
int midIndex = a.Length / 2;
//sets the last index to the length minus one (minus one included so
an out of bounds exception is avoided
int endIndex = a.Length - 1;
//left side set to the middle index size
int[] leftArray = new int[midIndex];
//right side set to the total length minus the middle length
int[] rightArray = new int[inputLength - midIndex];
//looping from zero to middle of the array
for (int i = 0; i < midIndex; i++)
{
leftArray[i] = a[i];
}
//looping from the middle to the end of the array
for(int i = midIndex; i < inputLength; i++)
{
rightArray[i - midIndex] = a[i];
}
//recursively called the method to sort these two sides
mergeSort(leftArray);
mergeSort(rightArray);
//this calls the merge method to put the two halves together
merge(a, leftArray, rightArray);
}
private static void merge(int[] a, int[] leftHalf, int[] rightHalf)
{
int leftSize = leftHalf.Length;
int rightSize = rightHalf.Length;
int i = 0, j = 0, k = 0;
//loops until no more elements in left or right array
while(i < leftSize && j < rightSize)
{
if(leftHalf[i] <= rightHalf[j])
{
//sets the element at iteration k to the elements at i in the
left half if
//it is smaller than the right half
a[k] = leftHalf[i];
i++;
}
else
{
//if the right half is smaller, set element at iteration k
equal to the
//element at index j of the right half
a[k] = rightHalf[j];
j++;
}
k++;//iterate K
}
//these account for leftover elements after the above while loop.
while (i < leftSize)
{
a[k] = leftHalf[i];
i++;
k++;
}
while (j < rightSize)
{
a[k] = rightHalf[j];
j++;
k++;
}
}
My main method is here:
static void Main(string[] args)
{
try{
TextFileReader reader = new TextFileReader();
int[] numberArray = reader.ReadFile("numbers.txt");
//printArray(numberArray);
Sorts sorts = new Sorts();
//sorts.bubbleSort(numberArray);
//printArray(numberArray);
//sorts.selectionSort(numberArray);
Searches searches = new Searches();
//searches.SequentialSearch(numberArray, 897);
//searches.binarySearch(numberArray, 9992);
//Console.WriteLine("\n\nArray length: " + numberArray.Length);
mergeSort(numberArray);
printArray(numberArray);
}
catch(IOException ex)
{
Console.WriteLine("IO Exception Found.");
}
}
public static void printArray(int[] numberArray)
{
foreach(int i in numberArray)
{
Console.WriteLine(i);
}
}
}
}
This is driving me crazy because the other algorithms are working and outputting correctly, but when the MergeSort is ran it gives no exceptions or errors.

Can you dynamically create variables based on rows in an Excel file in C#?

I am trying to make a C# program that takes coordinates from an excel file in the sense that each column is x,y,z and r, respectively, and each row is a different point. I would like to be able to create variables in the format point0, point1, etc. depending on how many rows there are.
As of right now I am reading each cell into an Array, then manually creating points from that array. In this case there are 4 rows and 4 points (points 0 to 3). This works for now but I have to imagine there is a much easier way of doing this or at least something more dynamic. 4 points is not a big deal but there could be many more.
int rows = 4;
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < rows; j++)
{
points[i,j] = excel.ReadCell(i, j);
}
}
for(int i = 0; i < 4; i++)
{
point0[0, i] = points[0, i];
}
for (int i = 0; i < 4; i++)
{
point1[1, i] = points[1, i];
}
for (int i = 0; i < 4; i++)
{
point2[2, i] = points[2, i];
}
for (int i = 0; i < 4; i++)
{
point3[3, i] = points[3, i];
}
Even condensing the set of loops where the points are manually created would save time, I am just not sure if there is a way to say something such as
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
{
point+"i"[i,j] = points[i,j]
}
}
Where the ith iteration is concatenated to the variable name.
Any help would be greatly appreciated, and I am open to all recommendations (I am pretty new to C# if you can't tell)
I would define a class of what the combination of the four points mean. Not based on the row or column that they're stored on but what they actually represent.
public class Shape
{
public int Start { get; set; }
public int End { get; set; }
public int Mean { get; set; }
public int Median { get; set; }
}
Then as you loop through each row you can Create and add all four points at the same time. Some thing like this.
public List GetShapesFromExcel()
{
var list = new List();
int StartColumn = 'x';
int EndColumn = 'y';
int MeanColumn = 'z';
int MedianColumn = 'r';
foreach (var row in workSheet)
{
var shape = new Shape()
{
Start = excel.ReadCell(row, StartColumn);
End = excel.ReadCell(row, EndColumn);
Mean = excel.ReadCell(row, MeanColumn);
Median = excel.ReadCell(row, MedianColumn);
};
}
return list;
}
I'm taking a wild stab in the dark on what you're data actually represents but I would take the time to go ahead and spin that up into a real object so that it's easier to reason about as you're writing the code.
variables like ā€˜Iā€™ & ā€˜Jā€™ Don't save enough time in this case to be useful.
last suggestion is to go ahead and check out the package EPPlus. that package has the ability to turn rows into structured classes
check this out to get started.
How to parse excel rows back to types using EPPlus

Trying to find Frequency of elements in array

I am trying to count how many times a number appears in an array 1 (a1) and then trying to print out that number by storing it in array 2 (a2) just once and then try to print array 2. But first using for loop and a function, I will check that if a number already exist in array 2 then move to next index in array 1, unfortunateley this code is not working; can someone please help me in trying to fix it, I don't need some complex solutions like dictionaries or lists athe moment, although it might be helpful too. thanks, I am not an expert in programming and I try to practise it in my free time, so please help me.
I just want this code to be fixed for my understanding and knowledge
class Program
{
static void Main(string[] args)
{
int i, j;
int[] a1 = new int[10];
int[] a2 = new int[10];
int[] a3 = new int[10];
//takes an input
for (i = 0; i < a1.Length; i++)
{
a1[i] = Convert.ToInt32(Console.ReadLine());
}
for (i = 0; i < a1.Length; i++)
{
Cn(a1, a2); //calls in function
i++; //increments is if true
int count = 0;
for (j = 0; j < a1.Length; j++)
{
//if a number matches with a number in second array
if (a1[i] == a1[j])
{
//do count ++
count++;
// store that number into second array
a2[i] = a1[i];
}
}
//store the number of counts in third array
a3[i] = count;
}
for (i = 0; i < a2.Length; i++)
{
if (a2[i] != 0)
{
Console.WriteLine(a2[i]);
}
}
Console.ReadLine();
}
//function to check if element at current index of array 1 exists in array 2 if yes than break
public static void Cn (int[] aa1, int [] aa2)
{
int k, j;
for ( k = 0; k < aa1.Length; k++)
{
for (j = 0; j < aa2.Length; j++)
{
if (aa1[k] == aa2[j])
break;
}
}
}
}
You probably want to do a group by count:
int[] a1 = new int[10];
var rnd = new Random();
//takes an input
for (int i = 0; i < a1.Length; i++)
{
a1[i] = Convert.ToInt32(rnd.Next(0, 11)); // or Console.ReadLine()
}
var grouped = a1
.GroupBy(x => x)
.Select(g => new
{
Item = g.Key,
Count = g.Count()
}).ToList(); // ToList() is optional, materializes the IEnumerable
foreach (var item in grouped)
{
Console.WriteLine($"number: {item.Item}, count: {item.Count}");
}
This uses a Hash algorithm internally.
You can solve this without a Hash or Dictionary but it wouldn't be very efficient because you need to do lots of linear searches through the arrays.
The advantage of a Hash algorithm is that your lookups or groupings are much faster than if you loop over a complete array to find / increment an item.

Starpattern in console app

I need to create the following pattern:
It is homework, this question I failed the first time.
I read now that I should have only used "*" one time, but how would this even work in that case?
Would appreciate if anyone could give me some insight in how to think.
My code is down below:
using System;
class StarPattern
{
public static void Main()
{
for (int i = 0; i < 5; i++)
{
Console.Write("*");
}
for (int a = 0; a <= 0; a++)
{
Console.WriteLine("");
Console.Write("*");
}
for (int c = 0; c <= 0; c++)
{
Console.WriteLine(" *");
}
for (int d = 0; d <= 1; d++ )
{
Console.Write("*");
Console.WriteLine(" *");
}
for (int e = 0; e < 5; e++ )
{
Console.Write("*");
}
Console.ReadLine();
}
}
You can simplify your code by nesting loops so outer (i) = rows and inner (j) = columns. From looking at your sample, you want to write out if you're on the boundary of either so you can add a condition to just write out on min and max.
private static void Main(string[] args)
{
for (int i = 0; i <= 4; i++)
{
for (int j = 0; j <= 4; j++)
{
if (i == 0 || i == 4 || j == 0 || j == 4)
{
Console.Write("*");
}
else
{
Console.Write(" ");
}
}
Console.WriteLine();
}
Console.ReadKey();
}
I'd probably replace 0 with a constant called MIN and 4 with a constant called MAX to save duplicating them. That way, you could increase the size of the square by just changing the constants.
Hardly anyone is commenting their code for you. How disappointing!
The trick here is to focus on what is important and define values that you will;
be using many times in the code
only want to change once if requirements need tweeking
These values are height and width - the core components of a rectangle.
The golden rule for the pattern is: If the row and column of each character is on the edge of the square, print a *
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Stars
{
class Program
{
static int Width = 5; //define the width of the square in characters
static int Height = 5; //define the height of the square in characters
static void Main(string[] args)
{
for (int row = 0; row <= Height; row++) //Each iteration here is one row.
{
//loop representing columns. This is NESTED within the rows so
//that each row prints more than one column
for (int column = 0; column <= Width; column++)
{
if (IsCentreOfSquare(row, column)) //calculate if the current row and column coordinates are the interior of the square
{
Console.Write(" ");
}
else
{
Console.Write("*");
}
}
Console.WriteLine(); //this row is over. move to the next row
}
Console.ReadLine(); //pause so that the user can admire the pretty picture.
}
/// <summary>
/// Calculates if the row and column indexes specified are in the interior of the square pattern
/// </summary>
/// <returns></returns>
private static bool IsCentreOfSquare(int row, int col)
{
if (row > 0 && row < Height)
{
if (col > 0 && col < Width)
{
return true;
}
}
return false;
}
}
}
This might be overkill for such a simple program, but make it scalable and add some const ints to make the design able to be modified whenever you'd like!
Good question. It's fun to feel like I'm tutoring again! Glad to see you at least gave it an honest attempt :)
class Program
{
// Use string if you are okay with breaking the current pattern.
// private static string myDesign = "*";
// Use char if you want to ensure the integrity of your pattern.
private static char myDesign = '*';
private const int COLUMN_COUNT = 5;
private const int ROW_COUNT = 5;
private const int FIRST_ROW = 0;
private const int LAST_ROW = 4;
private const int FIRST_COLUMN = 0;
private const int LAST_COLUMN = 4;
static void Main(string[] args)
{
// Iterate through the desired amount of rows.
for (int row = 0; row < ROW_COUNT; row++)
{
// Iterate through the desired amount of columns.
for (int column = 0; column < COLUMN_COUNT; column++)
{
// If it is your first or last column or row, then write your character.
if (column == FIRST_COLUMN || column == LAST_COLUMN || row == FIRST_ROW || row == LAST_ROW)
{
Console.Write(myDesign);
}
// If anywhere in between provide your blank character.
else
{
Console.Write(" ");
}
}
Console.WriteLine("");
}
Console.Read();
}
}
It is not that difficult to do. You need to create two loops: one for the rows and one for the columns and then determine whether to print a star or not. Only the first and the last rows and columns have a star.
In my example I use two counters that start from 0 and count to 4. If the remainder of either counter value divided by 4 equals to 0 then I print a star, otherwise a space.
using System;
namespace Stars
{
internal static class StarPattern
{
private static void Main()
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
Console.Write((i%4 == 0) | (j%4 == 0) ? '*' : ' ');
}
Console.WriteLine();
}
}
}
}
You need to print a certain number of lines with a certain sequence of characters per line.
One approach would be to create or find a method that prints whatever character sequence you need. Then create a method to sequence calls to to that. Finally, print the result of all that.
private void PrintBox(char c, int width, int height)
{
var result = new List<string>();
result.Add(new string(c, width)); // First line
for (var i = 0; i < height - 2; i++)
{
string iLine;
int spaceCount = width - 2;
iLine = new string(c, 1) + new string(' ', spaceCount) + new string(c, 1);
result.Add(iLine);
}
result.Add(new string(c, width)); // Last line
// FYI, there's a StringBuilder class that makes all this easier
foreach (var line in result)
{
Console.WriteLine(line);
}
}
The important OOP concept here is that we made use of a single reusable method for constructing a sequence of characters - new string(char, int). If we wanted to create a Circle, we could create a BuildCircle method based on the same principle.

Categories

Resources