A method to search Id inside a matrix -Trouble with output - c#

I am new at programming and I am trying to create a method that allows me search Id inside a [10,4] matrix, however I don't get how to do it without using nested fors and also if and else statement. The problem is related to output, I know the structure isn't correct, but since I don't what else can be done I am trying make it as it is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace menu
{
class Program
{
enum header { id, name, surname, addres };
public static int id = 1;
static void Main(string[] args)
{
string[,] matrix = new string[10, 4];
insertStudent(matrix);
idSearch(matrix);
Console.ReadKey();
}
static int generateId()
{
return id++;
}
static void insertStudent(string[,] matrix)
{
int n = generateId();
matrix[n - 1, 0] = Convert.ToString(n);
for (int i = 1; i < matrix.GetLength(1); i++)
{
do
{
Console.WriteLine($"Insert {Enum.GetName(typeof(header), i)}");
matrix[n - 1, i] = Console.ReadLine();
}
while (String.IsNullOrEmpty(matrix[n - 1, i]));
}
}
static void idSearch(string[,] matrix)
{
int idChosen=0;
Console.WriteLine($"Insert ID you want to visualize:");
int.TryParse(Console.ReadLine(), out idChosen);
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
if (matrix[i, 0] == Convert.ToString(idChosen))
{
Console.WriteLine(matrix[i, j]);
}
else
{
Console.WriteLine("The chosen ID does not exist");
}
}
}
}
}
}

Right now you printing "The chosen ID does not exist" every time you check an index in your matrix. You want to move that statement to outside of your loop after you've already checked every index. Right now that check is really saying that your ID is not in that specific cell. I've altered your code slightly to reflect this. I also fixed your check to be on matrix[i,j] instead of matrix[i,0]
Also using a nested for loop is OK to use. I don't believe C# has any built in helper methods for searching multidimensional arrays.
bool found = false;
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
if (matrix[i, j] == Convert.ToString(idChosen))
{
//note that this will print your id
Console.WriteLine(matrix[i, j]);
//this would print where it found it
Console.WriteLine("Found at [" + i + "," + j + "]");
found = true;
}
}
}
if (!found)
{
Console.WriteLine("The chosen ID does not exist");
}

Related

Memory error NZEC when using C# on HackerEarth

I am solving a question on HackerEarth. The test case passes successfully, but the rest of the cases show a NZEC error. I know NZEC stands for Non Zero Exit Code but I am not sure why this is happening here.
Any insight about why this happens and how I can optimize my code (preferably without changing the logic) will help.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution
{
static void Main(String[] args)
{
int t = int.Parse(Console.ReadLine());
int[] arr = new int[3];
for(int m = 0; m < t; m++)
{
arr[m] = int.Parse(Console.ReadLine());
}
for (int n = 0; n < t; n++)
{
int i, j;
for (i = 0; i < arr[n]; i++)
{
for (j = 0; j < 2 * arr[n]; j++)
{
if (j <= i || j >= 2 * arr[n] - 1 - i)
{
Console.Write("*");
}
else
{
Console.Write("#");
}
}
Console.WriteLine("\n");
}
Console.WriteLine("\n");
}
}
}

Sub list items are not showing in C#

I am trying to add a list inside a list. But I wasn't able to retrieve the items from the sub list. There is no error, but no data was retrieved from the sub list. Please focus on GenerateClue() I think the error is there.
When I'm trying to access the data using clueList[0][0], There is no data
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
public class TrainingMode : MonoBehaviour {
private List<int> answerKey;
private List<int> clue;
private List<List<int>> clueList;
private int correct;
private int wellPlaced;
public Text answerKeyText;
System.Random random = new System.Random();
void Start () {
answerKey = new List<int>();
clue = new List<int>();
clueList = new List<List<int>>();
GenerateAnswerKey();
GenerateClue();
//CheckCorrectAndWellPlaced();
answerKeyText.GetComponent<Text>().text = answerKey[0] + " "+ answerKey[1] + " "+ answerKey[2];
foreach (List<int> arrClue in clueList)
{
foreach (int item in arrClue)
{
Debug.Log(item);
}
}
}
private void GenerateClue()
{
//Generate clue
for (int j = 0; j <= 5; j++)
{
for (int i = 0; i <= 2; i++)
{
int randomNumber = random.Next(0, 9);
if (clue.Contains(randomNumber))
{
i--;
}
else
{
clue.Add(randomNumber);
}
if (clue.Count == 3)
{
clueList.Add(clue);
clue.Clear();
}
}
}
}
private void CheckCorrectAndWellPlaced()
{
correct = 0;
wellPlaced = 0;
//Check for correct and wellplaced numbers
for (int i = 0; i <= 2; i++)
{
if (answerKey.Contains(clue[i]))
{
correct++;
}
if (clue[i] == answerKey[i])
{
wellPlaced++;
}
}
}
private void GenerateAnswerKey() {
//Generate answerkey
for (int i = 0; i <= 2; i++)
{
int randomNumber = random.Next(0, 9);
if (answerKey.Contains(randomNumber))
{
i--;
}
else
{
answerKey.Add(randomNumber);
}
}
}
}
The problem is that when you add the clue to your clue list what it's actually doing is passing a reference because List<> is a class. So you end up having just 2 variables pointing to the same memory. One is your clue variable and the other is the clueList[X]. So when you call clue.Clear() you are clearing the clue list which is ACTUALLY the same memory than your clueList[X].
As as fix just change this:
if (clue.Count == 3)
{
clueList.Add(clue);
clue.Clear();
}
into this:
if (clue.Count == 3)
{
clueList.Add(new List<int>(clue));
clue.Clear();
}
Your problem is here :
if (clue.Count == 3)
{
clueList.Add(clue);
clue.Clear();
}
You're adding clue to the clueList and then clearing the clue which has the same "memory address" ( same object as in the clueList ).
So in general, you're filling the clue list with some random numbers and then you're clearing this up whenever it fills making it empty again.
Instead, try to create a new list of ints on the beginning of your first for-loop.
for (int j = 0; j <= 5; j++)
{
var list = new List<int>();
for (int i = 0; i <= 2; i++)
{
int randomNumber = random.Next(0, 9);
if (list.Contains(randomNumber))
{
i--;
}
else
{
list.Add(randomNumber);
}
if (list.Count == 3)
{
clueList.Add(list);
}
}
}
You need to create a copy of the list, so to avoid the Clear() call to act on the element put in the clueList.
if (clue.Count == 3)
{
clueList.Add(clue.ToList());
clue.Clear();
}
But I also think that there can be cases when the list won't be inserted, because there can be cases when the random number it's always the same and you keep on going out the for loop.
for (int j = 0; j <= 5; j++)
{
for (int i = 0; i <= 2; i++)
{
int randomNumber = random.Next(0, 9);
if (clue.Contains(randomNumber))
{
i--;
}
else
{
clue.Add(randomNumber);
}
if (clue.Count == 3) // EDIT: what if it never reaches 3 ?
{
clueList.Add(clue.ToList());
clue.Clear();
}
}
}

Comparing two variable in a structure C#

What I want to do is compare two of the same variable in a structure.
For example I have a structure like so:
struct player
{
public string name;
public int number;
}
static player[] players = new player[3];
and what I want to do is compare the numbers, so that if two players have the same number, something will happen.
This is what I tried, however it would always say two numbers were the same because it would compare two of the same
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length; j++)
{
if (players[i].number == players[j].number)
{
Console.WriteLine("Same");
Console.ReadLine();
}
else
{
Console.WriteLine("Not");
Console.ReadLine();
}
}
Hopefully you understand what I mean.
Any help would be really appreciated!
Thanks
Problem is in your loop variables i and j starting both at index zero. Then you are comparing element zero to element zero and therefore the condition is true.
Update this line:
for (int j = 0; j < length; j++)
to this:
for (int j = i + 1; j < length; j++)
Edit
To be more precise. The condition evaluates to true not only for the first element, but for each element when i and j are the same. This solution bars both control variables from having the same value in any iteration.
Simple, just add a check to make sure you aren't comparing the same index, because this is the same object:
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length; j++)
{
if (i == j) continue;
if (players[i].number == players[j].number)
{
Console.WriteLine("Same");
Console.ReadLine();
}
else
{
Console.WriteLine("Not");
Console.ReadLine();
}
}
Use a Class, and do it using Linq:
public class Player
{
public string Name { get; set; }
public int Number { get; set; }
}
Then in the other class have this method to cross-check
private void Match()
{
var players = new Player[3].ToList();
foreach (var found in players.ToList().Select(player => players.FirstOrDefault(p => p.Number == player.Number)))
{
if (found != null)
{
Console.WriteLine("Same");
Console.ReadLine();
}
else
{
Console.WriteLine("Not");
Console.ReadLine();
}
}
}

Insertion sort algorithm c#

I am trying to implement the Insertion sort in one of my programs. What I have been trying to create is a sorting program (in both ascending or descending order) However I have tried with algorithms such as quicksort and merge-sort, I am really new to c# and coding. The problem I am facing here is the fact that my files includes both a string of code, as well as a double/integer (example: 75.350, 74.430, Thursday, Friday) and since this algorithm is designed for integers. Is there a way to convert it please?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
StreamReader sh1Open = new StreamReader("c:..\\Files\\SH1_Open.txt");
string Sh1OpenString = sh1Open.ReadToEnd();
int[] x = { Convert.ToInt32(Sh1OpenString) };
int j;
int temp;
for (int i = 1; i < x.Length; i++)
{
j = i - 1;
while (j >= 0 && x[j]>x[j+1])
{
temp = x[j];
x[j] = x[j + 1];
x[j + 1] = temp;
j = j - 1;
}
}
for (int i = 0; i < x.Length; i++)
{
Console.WriteLine(x[i]);
}
Console.ReadKey();
}
}
}
The best way is probably using generic method with IComparable constraint.
T[] InsertionSort(T[] x) where T : IComparable<T>
{
for (int i = 0; i < x.Length-1; i++)
{
int j = i+1;
while (j>0)
{
if (x[j-1].CompareTo(x[j]) > 1)
{
T temp = x[j-1];
x[j - 1] = x[j];
x[j] = temp;
}
j--;
}
}
return x;
}
or using algorithm from http://www.codecodex.com/wiki/Insertion_sort
static void InsertSort(IComparable[] array)
{
int i, j;
for (i = 1; i < array.Length; i++)
{
IComparable value = array[i];
j = i - 1;
while ((j >= 0) && (array[j].CompareTo(value) > 0))
{
array[j + 1] = array[j];
j=j-1;
}
array[j + 1] = value;
}
}
Also, there is probably a bug in this line:
int[] x = { Convert.ToInt32(Sh1OpenString) };
because you're trying to convert whole file to one integer.
Since in C# the comparison operators are defined for strings you could just replace all relevant int variables with string variables. The algorithm should run the same (albeit a bit slower)

2 dimensional array

For each element in the array I need a unique identifier such as Seat1, Seat2, Seat 3....... all the way to the end of the length of the array.
currently I have done the following:
int rows = 10, cols = 10;
bool[ , ] seatArray = new bool[rows , cols]; //10 rows, 10 collums
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++ )
{
seatArray[i, j] = false;
}
foreach (bool element in seatArray)
{
Console.WriteLine("element {0}", element);
}
}
this simply just says "Element False" x 100 in the console.
i need to replace "Element" with Seat1, Seat2, Seat3....to the end of the array length.
any help will be much appreciated!
thank you!
Create a Seat class (or structure, if more appropriate) with ID and Occupied(?) properties. Make an array of this type.
public class Seat
{
public string ID { get; set; }
public bool Occupied { get; set; }
}
int rows = 10, cols = 10;
Seat[,] seats = new Seat[rows,cols];
for (int i = 0; i < rows; ++i )
{
for (int j = 0; j < cols; ++j)
{
seats[i,j] = new Seat { ID = "Seat" + (i*cols + j), Occupied = false };
}
}
foreach (var seat in seats)
{
Console.WriteLine( "{0} is{1} occupied", seat.ID, seat.Occupied ? "" : " not" );
}
int count = 1;
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++ )
{
seatArray[i, j] = count;
count++;
}
foreach (bool element in seatArray)
{
Console.WriteLine("element {0}", element);
}
no idea what language this is so idk the syntax but just do some external counter to number them
that just says false every time you set every one to false, dont use a bool, or write a class to hold the true false and number info
tvanfosson, i am struggling to make your coding work, iv put it into a new class off my main method see below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Class1
{
public class Seat
{
public string ID { get; set; }
public bool Occupied { get; set; }
}
int rows = 10, cols = 10;
Seat[,] seats = new Seat[rows,cols];
for (int i = 0; i < rows; ++i )
{
for (int j = 0; j < cols; ++j)
{
seats[i,j] = new Seat { ID = "Seat" + (i*cols + j), Occupied = false };
}
}
foreach (var seat in seats)
{
Console.WriteLine( "{0} is{1} occupied", seat.ID, seat.Occupied ? "" : " not" );
}
}
}
is this correct as i seem to be receiving a lot of syntax errors
thank you!

Categories

Resources