how to point to back of generic list c# - c#

Is there a way to point to the last item added to a generic list in c# ? Like the back() for a vector in c++

If you're using the 3.5 framework
using System.Linq;
using System.Collections.Generic;
public static class Program {
public static void Main() {
Console.WriteLine(new List<int> { 1, 2, 3 }.Last()); // outputs - 3
}
}

List<int> myList = new List<int>();
for( int i = 0; i < 5; i++ )
{
myList.Add (i);
}
Console.WriteLine (String.Format ("Last item: {0}", myList[myList.Count - 1]));

list.Last() ?

Related

What does System.IndexOutOfRangeException: 'Index was outside the bounds of the array.' mean? - How to Bubble Sort in C#? [duplicate]

This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 3 years ago.
I'm doing a programming task for my course and I've been challenged to do it in C#. When I run it, it highlights numbers[position+1] and gives me the error: System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
// array of numbers
int[] numbers = { 9, 5, 4, 15, 3, 8, 11, 2 };
int noOfNumbers = 8;
int temp;
while (noOfNumbers > 1) {
foreach(int position in numbers) {
if (numbers[position] > numbers[position+1])
{
temp = numbers[position];
numbers[position] = numbers[position + 1];
numbers[position + 1] = temp;
}
}
noOfNumbers = noOfNumbers + 1;
}
Console.WriteLine(numbers);
}
}
}
Here is the pseudocode:
BEGIN
Numbers=[9,5,4,15,3,8,11,2]
AmountOfNumbers=8
Temp=0
WHILE AmountOfNumbers>1
FOR each itemPositionInArray in Numbers
IF Numbers[ItemPositionInArray] > Numbers[ItemPositionInArray+1]
Temp=Numbers[ItemPositionInArray]
Numbers[ItemPositionInArray]=Numbers[ItemPositionInArray+1]
Numbers[ItemPositionInArry+1]=Temp
AmountOfNumbers=AmountOfNumbers-1
OUTPUT(Numbers)
END
The problem in your code is here: (like Amy said)
foreach(int position in numbers) {
if (numbers[position] > numbers[position+1])
You're using the position as index to the array. The foreach will enumerate your array and will put in the element values into the position variable, not the index. So the first iteration position will contain 9 (not index 0)
For this you should use the "normal" for-loop.
for(int i=0; i < count; i++) { }
Here's an example to do a bubblesort. I've written some comment to explain what it does.
using System;
public class Program
{
public static void Main()
{
// array of numbers
int[] numbers = { 9, 5, 4, 15, 3, 8, 11, 2 };
// declare a boolean.
bool done;
do
{
// when nothing happens, you're done.
done = true;
// create a for-loop to iterate all item-1 (except the last)
for(int position=0;position<numbers.Length-1;position++)
{
// compare the values in the array
if (numbers[position] > numbers[position+1])
{
// swap the values
int temp = numbers[position];
numbers[position] = numbers[position + 1];
numbers[position + 1] = temp;
// if something was swapped, you're not ready.
done = false;
}
}
// loop until done is set.
} while (!done);
Console.WriteLine(string.Join(",", numbers));
}
}
Here's an .NET Fiddle

What am I doing wrong when using string.join in my code?

I have the code below, which I need to separate the result with ", ". I have so far used different methods because whenever I try to use String.Join, it doesn't work as expected. What am I doing wrong?
Code:
using System;
using System.Collections.Generic;
using System.Linq;
namespace _5._PrintEvenNumbers
{
class Program
{
public static void Main()
{
var input = Console.ReadLine().Split().Select(int.Parse).ToList();
var numbers = new Queue<int>();
for (int i = 0; i < input.Count(); i++)
{
if (input[i] % 2 == 0)
{
numbers.Enqueue(input[i]);
}
}
while (numbers.Any())
{
Console.Write(string.Join(", ", numbers.Dequeue()));
}
}
}
}
Expected result should be "2, 4, 6" for example. Currently it prints it "246"
Just replace
while (numbers.Any())
{
Console.Write(string.Join(", ", numbers.Dequeue()));
}
with
Console.Write(string.Join(", ", numbers));
Unless you really need to dequeue.

Permutation Algorithm OutOfMemory Exception

Please help me to how to fix OutOfMemory exception using below code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Permutation
{
class Program
{
static void Main(string[] args)
{
CreatePartsByFreezingEachElementOnce("abcedfghijk");
PrintPossiblePermutations(false);
Console.WriteLine("---------------");
PrintPossiblePermutations(true);
Console.ReadLine();
}
static void PrintPossiblePermutations(bool unique)
{
var allPermutations = new List<string>();
foreach (var item in _listWithFreezedKey)
if (item.Item2.Count() == 2)
{
allPermutations.Add(Swap(String.Join(",", item.Item1), item.Item2[0], item.Item2[1]));
allPermutations.Add(Swap(String.Join(",", item.Item1), item.Item2[1], item.Item2[0]));
}
if (unique)
{
var uniuePermutations = allPermutations.Distinct();
// PrintPermutations(uniuePermutations.ToList());
Console.WriteLine(uniuePermutations.Count());
}
else
{
// PrintPermutations(allPermutations);
Console.WriteLine(allPermutations.Count());
}
}
static void PrintPermutations(List<string> permutations)
{
int i = 1;
foreach (var item in permutations)
{
Console.WriteLine(string.Format("{0} :{1}", i, item));
i++;
}
}
static List<Tuple<List<char>, List<char>>> _listWithFreezedKey = new List<Tuple<List<char>, List<char>>>();
static void CreatePartsByFreezingEachElementOnce(string str, List<char> indexToFreeze = null)
{
List<Tuple<List<char>, List<char>>> _innerlistWithFreezedKey = new List<Tuple<List<char>, List<char>>>();
var arr = str.ToCharArray().ToList();
var copy = arr;
if (indexToFreeze == null)
{
indexToFreeze = new List<char>();
}
for (int i = 0; i < arr.Count(); i++)
{
copy = str.ToCharArray().ToList();
var nth = arr[i];
copy.RemoveAt(i);
indexToFreeze.Add(nth);
_listWithFreezedKey.Add(new Tuple<List<char>, List<char>>(indexToFreeze.ToList(), copy));
_innerlistWithFreezedKey.Add(new Tuple<List<char>, List<char>>(indexToFreeze.ToList(), copy));
indexToFreeze.RemoveAt(indexToFreeze.Count() - 1);
}
foreach (var item in _innerlistWithFreezedKey)
{
List<char> l = item.Item2;
CreatePartsByFreezingEachElementOnce(String.Join("", l), item.Item1);
}
}
static string Swap(string frezedPart, char swapChar1, char swapChar2)
{
return frezedPart + "," + swapChar1 + "," + swapChar2;
}
}
}
If you run this code using 10 chrs, it throws out of memory exception. But for 9 chars , it returns result.
It was my interview question to write a code such that it should not go out of memory if big data passed.
Thanks,
Your problem is that you want to generate all permutations at once, instead of generating them one-by-one. You are looking for an algorithm which produces the next permutation.
See the first page of Knuth's book on generating permutations.
I would like to answer my question by myself because it may help someone as well.
I will use Iterator Design Pattern to remove unused elements from memory and will convert collection into sequence.
Thanks,

Concat error in C#

I have a quick sort program using lists.
The error is in the quick sort function return statement.
System.Collections.List does not contain definition for Concat and the best extension method System.Collections.Generic.IEnumerableTsource has some invalid arguments.
The code is as follows.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter the n9o. of elements: ");
int n = Convert.ToInt32(Console.ReadLine());
List<int> unsorted = new List<int>();
Console.WriteLine("Enter the elements: ");
for (int i = 0; i < n; i++)
{
unsorted.Add(Convert.ToInt32(Console.ReadLine()));
}
List<int> sorted = quicksort(unsorted);
foreach (int entry in sorted)
{
Console.Write(entry + "\t");
}
return;
} //end of main.
public static List<int> quicksort(List<int> given)
{
if (given.Count == 1)
return given;
int mid = given.Count / 2;
List<int> less = new List<int>();
List<int> big = new List<int>();
for (int a = 0; a < given.Count; a++)
{
if (given[a] < mid)
{
less.Add(given[a]);
}
else
big.Add(given[a]);
}
return (quicksort(less).Concat(given[mid]).Concat(quicksort(big)));
}
}//end of class.
}//end of namespace.
You can't Concat an int into an IEnumerable<int>. You could instead wrap it in an array and Concat that to your other lists:
return quicksort(less)
.Concat(new[] { given[mid] })
.Concat(quicksort(big))
.ToList();
As the error is trying to tell you, the Concat() method takes a collection of items to concatenate, not a single int.
I think adding given[mid] to the resulting list is a mistake, since it will add the item to your resulting list twice...
also, you need to test against given[mid] not mid
So you should change your if statement to:
if (given[a] < given[mid])
less.Add(given[a]);
else if (given[a] > given[mid])
big.Add(given[a]);
This is assuming that all numbers are unique as well, because if given[mid] is not unique, then you have a problem

c# parallel arrays data from text file

Here's the problem: Index was outside the bounds of the array. Assignment: Write a program that determines the number of students who can still enroll in a given class. Design your solution using parallel arrays. Test your solution by retrieving the following data from a text file. Define a exception class for this problem if the current enrollment exceeds the maximum enrollment by more than three. Halt the program and display a message indicating which course is over-enrolled.
Here's the original code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
private static string[] classes = { "CS150", "CS250", "CS270", "CS300", "CS350" };
private static int[] currentEnrolled = { 18, 11, 9, 4, 20 };
private static int[] maxEnrollment = { 20, 20, 20, 20, 20 };
private static int currentEnrollment()
{
int enrolled = 0;
foreach (int i in currentEnrolled)
{
enrolled += i;
}
return enrolled;
}
private static void listClasses()
{
foreach (string i in classes)
{
Console.WriteLine("Class: {0}", i);
}
}
private static void ClassStatus()
{
for (int i = 0; i < currentEnrolled.Length; i++)
{
Console.WriteLine("Class: {0}, Max: {1}, Current: {2}, remaining: {3}", classes[i], maxEnrollment[i], currentEnrolled[i], maxEnrollment[i] - currentEnrolled[i]);
}
}
static void Main(string[] args)
{
Console.WriteLine("Currently Enrolled: {0}", currentEnrollment());
ClassStatus();
Console.ReadKey(false);
}
}
}
Now, I've been editing the above code to take a text file instead, however I get an error. Here's what I'm working with:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
private static string[] classes = new string[900];
private static int[] currentEnrolled = new int[900];
private static int[] maxEnrollment = new int[900];
private static int currentEnrollment()
{
int enrolled = 0;
foreach (int i in currentEnrolled)
{
enrolled += i;
}
return enrolled;
}
private static void listClasses()
{
foreach (string i in classes)
{
Console.WriteLine("Class: {0}", i);
}
}
private static void ClassStatus()
{
for (int i = 0; i < currentEnrolled.Length; i++)
{
Console.WriteLine("Class: {0}, Max: {1}, Current: {2}, remaining: {3}", classes[i], maxEnrollment[i], currentEnrolled[i], maxEnrollment[i] - currentEnrolled[i]);
}
}
static void Main(string[] args)
{
string[] lines = File.ReadAllLines("classes.txt");
int i = 0;
foreach (string line in File.ReadAllLines("classes.txt"))
{
string[] parts = line.Split(',');
while (i < 900 && i < parts.Length)
{
classes[i] = parts[1];
currentEnrolled[i] = int.Parse(parts[2]);
maxEnrollment[i] = int.Parse(parts[3]);
}
i++;
}
Console.WriteLine("Currently Enrolled: {0}", currentEnrollment());
ClassStatus();
Console.ReadKey(false);
}
}
}
Some of the components used in the above code were taken from this article: Splitting data from a text file into parallel arrays
Text file looks like this:
CS150,18,20
CS250,11,20
CS270,32,25
CS300,4,20
CS350,20,20
Any assistance will be appreciated. And yes, this is an assignment. Programming is most definitely not my strong suit.
There seem to be multiple problems with your while loop.
First, parts.Length will always be 3, since you have 2 commas and split on that. So the condition i < 900 && i < parts.Length does not really make sense, it's like i < 900 and i < 3, so it will always stop at 3. The intent is not really clear here, I think you meant to loop on each 900 values, but fi soforeach already does that for you.
Next, since there's 3 parts and C# arrays are 0-based, it should be parts[0], parts[1] and parts[2]. That's what causing your 'out of range' exception.
Finally, i++; should be in your while loop. If you leave it outside, you will loop forever as the index will never increase.
Basically, it should be something like this :
while (i < 900)
{
classes[i] = parts[0];
currentEnrolled[i] = int.Parse(parts[1]);
maxEnrollment[i] = int.Parse(parts[2]);
i++;
}
Again, the 900 is not really clear since you don't have 900 values per line (remember you're in a foreach). In my opinion you might as well scratch all that and redo it carefully.
What you need to do, is the following :
Read the file and store all the lines
Foreach line do:
Split the line in 3 parts
Store each separate part
Write results
For the "custom exception" part, you can add:
For the length of currentEnrollment do:
If currentEnrollment at current index is superior than maxEnrollment at current index do:
Throw a new exception with the className at current index

Categories

Resources