How to fill the array of integers from console input - c#

Let's say I know how many numbers will user put in. I have an int array and I want to fill it with integers user put in devided by particular character, for example space. I managed to solve it this way.
int[] numbers = new int[5];
string[] input = Console.ReadLine().Split(' ');
for (int i = 0; i < numbers.Length; ++i)
numbers[i] = int.Parse(input[i]);
I want to ask you, is there any other, better way to do this?

You could use Linq:
var numbers = Console.ReadLine().Split(' ').Select(token => int.Parse(token));
// if you must have it as an array...
int[] arr = numbers.ToArray();
This basically does the same thing as your code, it's just more concise.
You could also make your code more robust by handling cases where the user inputs something that's not a number (which would cause int.Parse() to throw an exception).

Suggestion 1: if you would like to read all values from single line delimited by space, then i would suggest you to use command line arguments. so that you can atleast avoid using String array in your program as command line arguments are stored into the Main() method String array argument.
Suggestion 2: while parsing the values into Int it would be nice to check wether parsing is successfull or not, so that if the parsing failes(due to invalid integer) then we can store zero or some default value.
Int32.TryParse() allows you to let you know wether parsing is sucessfull or not.
Try This:
static void Main(string[] args)
{
int[] numbers = new int[args.Length];
int temp;
for(int i=0;i<args.Length;i++)
{
if (Int32.TryParse(args[i],out temp))
{
numbers[i] = temp;
}
else
{
numbers[i] = 0;
}
}
}

Let me try, just read console line and split by space. use ConvertAll method fro Array class.
int[] myArray = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);

Even though the return value from Console.Read() returns an integer, it isn't quite that simple. It will return the integer representation of the characters you type in.
In order to retrieve the number of elements, as your code attempts to do. You should refactor a small portion into this:
Console.WriteLine("enter no of elements");
c = int.Parse(Console.ReadLine());
Please note that this piece of code can throw exceptions if what you type in isn't a number

You can use StringTokenizer to tokenize the whole line and then use parseInt().

Related

Domino recursion

I have a recursion assignment where I have to input into console the following data:
On the first line a natural number equal with the number of tiles I have to input on the following lines (in my example the first number is 6).
On the following lines the domino tiles in the following order:
1 2
1 3
3 4
2 3
3 5
4 5
On the last line another number representing the number of tiles that needs to be returned on each separate line (in my example the number is equal with 3).
With this data I have to display all possible combinations of pairs. For each separate line the number the second number from the first pair has to be equal with the first number of the following pair and so on. I had a hint for this assignment where I have to declare an intermediary list that is equal with the function (using recursion from the start) but when I'm trying to run the code it gives me a null exception for the intermediaryList.
In the first instance I read the data as a 2d array but settled with a simple string array where.
This is my code so far, could you help me with a suggestion, how to avoid the null exception?
(sorry if I missed something from the explanation, this is my second post here so far and thank you in advance). Also I have to mention that I'm allowed to use just "using System;" Not allowed to use Linq or anything else.
enter code here
static string[] ReadDominoTiles(int n)
{
string[] input = new string[n];
for (int i = 0; i < n; i++)
{
input[i] = Console.ReadLine();
}
return input;
}
static string[] DominoSolution(string[] dominoTiles, int numberOfPairs)
{
string[] finalList = new string[numberOfPairs];
if (numberOfPairs == 1)
{
return finalList;
}
string[] intermediaryList = DominoSolution(dominoTiles, numberOfPairs - 1);
for (int i = 0; i < intermediaryList.Length; i++)
{
for (int j = 0; j < dominoTiles.Length; j++)
{
// This is where I get the nullref exception, every value from intermediaryList is null
if (intermediaryList[i] != dominoTiles[j] && intermediaryList[j][1] == dominoTiles[j][0])
{
finalList[j] += intermediaryList[j] + " " + dominoTiles[j];
}
}
}
return finalList;
}
static void Main(string[] args)
{
int n = Convert.ToInt32(Console.ReadLine());
string[] dominoTiles = ReadDominoTiles(n);
int numberOfPairs = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(DominoSolution(dominoTiles, numberOfPairs));
}
This is where I get the nullref exception, every value from intermediaryList is null
That's correct, you call the function recursively after doing exactly zero work, besides adding a recursion termination condition which returns an array of nulls. So the first time you come out of your recursion you have in intermediaryList a number of null elements, so when you pretend they're strings and try to get intermediaryList[j][1] you'll get a null reference exception.
As to the solution, it's not exactly clear what's with all the arrays you're allocating. Use a List<> with an actual type and do your work properly. Though I hate to break it to you but if I understand your assignment correctly the solution will use backtracking and combinatorics, which is much more code and much better structured than what you have here.

I can't figure out why I'm reading wrong input in reading array elements in codechef problem for reverse array problem

I'm getting different user input instead of getting real inputs given by user in codechef
User Input:
4
1 2 3 4
Expected Output:
4 3 2 1
using System;
public class Test
{
public static void Main()
{
int N = Convert.ToInt32(Console.ReadLine());
int[] arr = new int[N];
for(int i=0;i<N;i++){
arr[i] = Convert.ToInt32(Console.Read());
}
for(int j=N-1;j>=0;j--){
Console.Write(arr[j]);
Console.Write(" ");
}
}
}
Output I got:
32 50 32 49
Since you said you want to do it without ReadLine, let's work with your current code. There are two issues at hand.
You should skip the spaces
You get the character codes instead of the values
To skip the spaces, you can simply read them and do nothing with the read character. I implemented this below in a way that assumes after every number (one digit long) there will be a single space to ignore. But you could also do that in a less hacky way by checking what the read character actually is before you discard it.
To get the character code into the value, I first perform a conversion into a char by casting it. Then I get the numeric value, which might be a double. But because you know that your numbers are integers, we can cast that to int.
using System;
class Program {
static void Main(string[] args) {
int N = Convert.ToInt32(Console.ReadLine());
int[] arr = new int[N];
for(int i=0;i<N;i++){
arr[i] = (int)Char.GetNumericValue((char)Console.Read());
Console.Read();
}
for(int j=N-1;j>=0;j--){
Console.Write(arr[j]);
Console.Write(" ");
}
}
}

Read numbers from a file

I have a problem my code is not efficient enough. He thinks he knows the content. How do I write the code so it can work with any file. So he practically only excludes numbers and ignores the words (strings).
public static int SumUpFileContent(string file)
{
int sum = 0;
var lines = File.ReadAllLines(file);
foreach (var line in lines)
{
if (int.TryParse(line, out int i))
sum += i;
}
return sum;
}
Keep in mind :
This doesn't work with numbers that have decimals, only integers. replace int.TryParse() with double.TryParse() if you have to.
The data must come in a very specific format (i.e. every entry must be on its own line)
From the information you provided you could split the file content in to an array
then for each item in the array use an int.tryParse to see if it is a number. (this is assumed that the numbers are always int)

Rearranging a string of numbers from highest to lowest C#

What I'm trying to do is to create a function that will rearrange a string of numbers like "1234" to "4321". I'm certain that there are many much more efficient ways to do this than my method but I just want to see what went wrong with what I did because I'm a beginner at programming and can use the knowledge to get better.
My thought process for the code was to:
find the largest number in the inputted string
add the largest number into a list
remove the largest number from the inputted string
find the largest number again from the (now shorter) string
So I made a function that found the largest number in a string and it worked fine:
static int LargestNumber(string num)
{
int largestnumber = 0;
char[] numbers = num.ToCharArray();
foreach (var number in numbers)
{
int prevNumber = (int) char.GetNumericValue(number);
if (prevNumber >= largestnumber)
{
largestnumber = prevNumber;
}
}
return largestnumber;
}
Now the rearranging function is what I am having problems with:
static List<int> Rearrange(string num)
{
List<int> rearranged = new List<int>(); // to store rearranged numbers
foreach (var number in num) //for every number in the number string
{
string prevnumber = number.ToString(); // the previous number in the loop
if (prevnumber == LargestNumber(num).ToString()) // if the previous number is the larges number in the inputted string (num)
{
rearranged.Add(Convert.ToInt32(prevnumber)); // put the previous number into the list
// removing the previous number (largest) from the inputted string and update the inputted string (which should be now smaller)
StringBuilder sb = new StringBuilder(num);
sb.Remove(num.IndexOf(number), 1);
num = sb.ToString();
}
}
return rearranged; // return the final rearranged list of numbers
}
When I run this code (fixed for concatenation):
var rearranged = Rearrange("3250");
string concat = String.Join(" ", rearranged.ToArray());
Console.WriteLine(concat);
All I get is:
5
I'm not sure what I'm missing or what I'm doing wrong - the code doesn't seem to be going back after removing '5' which i s the highest number then removing the next highest number/
Your issue is your if statement within your loop.
if (prevnumber == LargestNumber(num).ToString()
{
rearranged.Add(Convert.ToInt32(prevnumber));
//...
}
You only ever add to your List rearranged if the value of prevnumber is the largest value, which is false for every number but 5, so the only value that ever gets added to the list is 5.
That's the answer to why it's only returning 5, but I don't think that will make your method work properly necessarily. You're doing a very dangerous thing by changing the value of the collection you are iterating over (the characters in num) from within the loop itself. Other answers have been written for you containing a method that rearranges the numbers as you've described.
Your Rearrange method is returning List<int> when you try to write that to the console, the best it can do is write System.Collections.Generic.List1[System.Int32] (its type)
Instead of trying to write the list, convert it first into a data type that can be written (string for example)
eg:
var myList = Rearrange("3250");
string concat = String.Join(" ", myList.ToArray());
Console.WriteLine(concat);
Building on pats comment you could iterate through your list and write them to the console.
e.g.
foreach(var i in Rearrange(3250))
{
console.writeline(i.ToString());
}
or if you want to see the linq example.
using system.linq;
Rearrange(3250).foreach(i => console.writeline(i.ToString()));
--edit after seeing you're only getting '5' output
This is because your function only adds number to the list if they are the largest number in your list, which is why 5 is only being added and returned.
Your Rearrange method can be written easily using Array.Sort (or similar with (List<T>) :
int[] Rearrange(int num)
{
var arr = num.ToString ().ToCharArray ();
Array.Sort (arr, (d1, d2) => d2 - d1);
return Array.ConvertAll (arr, ch => ch - '0');
}
Just reading your first sentence
Does not test for integers
static int ReversedNumber(string num)
{
char[] numbers = num.ToCharArray();
Array.Sort(numbers);
Array.Reverse(numbers);
Debug.WriteLine(String.Concat(numbers));
return (int.Parse(String.Concat(numbers)));
}
Because your foreach loop within Rearrange method only loop through the original num. The algorithm doesn't continue to go through the new num string after you have removed the largest number.
You can find the problem by debugging, this foreach loop in Rearrange goes only 4 times if your input string is "3250".

Searching the same line in different arrays c#

I have six different arrays each with the same amount of elements in them, my question is, if I want to view the line that says 'test' and it happens to be the 22nd line, is there a way so that I can view the 22nd of all the arrays at the same time and then print them to the console, is it possible to do that?
e.g. I want to search through one array and then when it finds 'test' it prints out the same index of all arrays, including the one which 'test' was contained in.
Could a Binary Search be used here?
Thanks.
Yes you can.
Simply iterate through the first array until you find the string you are looking for, then use the counter to access the remaining arrays. Your code should look something like this:
for (int counter = 0; counter < Array1.Length; counter++)
{
if (Array1[counter] == "your string here")
{
//Print same line on remaining arrays, eg:
Console.WriteLine(Array2[counter]);
Console.WriteLine(Array3[counter]);
//Then you can break out of the loop
break;
}
}
If those are arrays, i can't see any problem doing this:
string[] array1, array2, array3..// etc
...
var stringToSearch = "someValue";
...
int matchPosition = Array.IndexOf(array1, stringToSearch);
if(matchPosition != -1)
{
// just sample of usage - access string by array2[matchPosition]
Console.WriteLine(array2[matchPosition]);
Console.WriteLine(array3[matchPosition]);
}

Categories