C# Add value to array through user input - c#

I want to add elements to my array through a user input.
I know this can be done very easy using a list but i have to use an array.
The problem with the code is that the array.lenght will always be 1.
I want the array to have the same size as the total amount of elements in it, so
size of the array shouldnt be set when declaring the array.
I thought that if you add an element to an array it will copy the previous values + the added value and create a new array.
UPDATED WITH ANSWER
public static void Add(int x){
if (Item == null) // First time need to initialize your variable
{
Item = new int[1];
}
else
{
Array.Resize<int>(ref Item, Item.Length + 1);
}
Item[Item.Length-1] = x; //fixed Item.Length -> Item.Length-1
}

Use List<int> instead of an explicit array, which will dynamically size for you, and use the Add() method to add elements at the end.

I didn't test in VS. Here you go:
namespace ConsoleApplication1
{
class Program
{
static int[] Item; //Fixed int Item[] to int[] Item
static void Main(string[] args)
{
Add(3);
Add(4);
Add(6);
}
public static void Add(int x){
if (Item == null) // First time need to initialize your variable
{
Item = new int[1];
}
else
{
Array.Resize<int>(ref Item, Item.Length + 1);
}
Item[Item.Length-1] = x; //fixed Item.Length -> Item.Length-1
}
}
}
This should resize your array by one each time and then set the last item to what you are trying to add. Note that this is VERY inefficient.

Lists grow as you add elements to it. Arrays have a constant size. If you must use arrays, the easiest way to do it, is to create an array that is big enough to hold the entered elements.
private int[] _items = new int[100];
private int _count;
public void Add(int x)
{
_items[_count++] = x;
}
You also need to keep track of the number of elements already inserted (I used the field _count here);
As an example, you can then enumerate all the items like this:
for (int i = 0; i < _count; i++) {
Console.WriteLine(_items[i]);
}
You can make the items accessible publicly like this:
public int[] Items { get { return _items; } }
public int Count { get { return _count; } }
UPDATE
If you want to grow the array size automatically, this is best done by doubling the actual size, when the array becomes too small. It's a good compromise between speed and memory efficiency (this is how lists work internally).
private int[] _items = new int[8];
private int _count;
public void Add(int x)
{
if (_count == _items.Lengh) {
Array.Resize(ref _items, 2 * _items.Length);
}
_items[_count++] = x;
}
However, keep in mind that this changes the array reference. So no permanent copy of this array reference should be stored anywhere else.

Related

Adding to an array c#

I have an array int Stack[] of size 5. I want to implement a method Push(value) that will push value into the last available slot of the array. Example: if array is empty and I use Push(1), now there is a 1 on position 0 of the array; but if the array has 3 values and I use Push(1), there will be a 1 on position 3 (since the array starts at 0, for a total of 4 values in the array). How may I do this?
public class Stack{
int items[];
int top;
public Stack(int size){
items=new int[size];
top=0;
}
public void Push(int val){
if(!IsFull()){
items[top++]=val;
}
}
public int Pop(){
if(!IsEmpty()){
return items[--top];
}else{
//-1 is for invalid op or just you can chech before calling Pop()
//is stack empty or not
return -1;
}
}
public bool IsFull()=>top==items.Length;
public bool IsEmpty()=>top==0;
}
For this purpose you have List<T>
https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1?view=net-6.0
Of course you can do that with an array as well, but that would mean that you have to make a new array for each Push() execution, which is completely unnecessary when you can use a list

c# initializing a list with another list/new list

I have a List of Lists.
To do some Opertations with each of those lists, i separate the Lists by a property and set a temp List with its value;
The list can be sometimes empty.
That is why i use this function for assignment.
EDIT:
My current solution is this simple method.
It should be easily adaptable.
private List<string> setList(List<string> a, int count)
{
List < string > retr;
if(a.Capacity == 0)
{
retr = new List<string>();
for(int counter = 0; counter < count; counter++)
{
retr.Add(string.empty);
}
}
else
{
retr = a;
}
return retr;
}
Is there a better way to either take a list as values or initialize a list with element count?
Or should I implement my own "List" class that has this behavior?
You could use Enumerable.Repeat<T> if you wanted to avoid the loop:
var list = Enumerable.Repeat<string>("", count).ToList();
But there are several things that are problematic with your code:
If Capacity is not 0, it doesn't mean it's equal to your desired count. Even if it is equal to the specified count, it doesn't mean that the actual List.Count is equal to count. A safer way would be to do:
static List<string> PreallocateList(List<string> a, int count)
{
// reuse the existing list?
if (a.Count >= count)
return a;
return Enumerable.Repeat("", count).ToList();
}
Preallocating a List<T> is unusual. It's usually common to use arrays when you have a fixed length known in advance.
// this would (perhaps) make more sense
var array = new string[count];
And keep in mind, as mentioned in 1., that list's Capacity is not the same as Count:
var list = new List<string>(10);
// this will print 10
Console.WriteLine("Capacity is {0}", list.Capacity);
// but this will throw an exception
list[0] = "";
Most likely, however, this method is unnecessary and there is a better way to accomplish what you're doing. If nothing else, I would play the safe card and simply instantiate a new list each time (presuming that you have an algorithm which depends on a preallocated list):
static List<string> PreallocateList(int count)
{
return Enumerable.Repeat("", count).ToList();
}
Or, if you are only interested in having the right capacity (not count), then just use the appropriate constructor:
static List<string> PreallocateList(int count)
{
// this will prevent internal array resizing, if that's your concern
return new List<string>(count);
}
Your method is meaningless but equivalent to
static List<string> setList(List<string> a, int count) =>
a.Capacity == 0 ? Enumerable.Repeat("", count).ToList() : a;
if you want Linq.

How to push 0 item to the stack of int?

I have a simple stack implementation. But I cant realize how programmer solve the following problem: It is not possible to push a 0 to the stack. How to do that? I mean how to track is it a 0 value or just end of the stack? Or its not a problem in my implementation?
public class Stack: IStack
{
private int[] s;
private int N = 0;
public Stack(int N)
{
s = new int[N];
}
public void push(int x)
{
s[N++] = x;
if (N >= s.Length)
{
Array.Resize(ref s, s.Length*2);
}
}
public int pop()
{
s[N] = 0;
return s[--N];
}
}
You are already tracking the last element of the stack with N (or rather, N - 1). You don't need to verify whether the element is 0, and your implementation actually doesn't distinguish between zeroes and other numbers.
In the implementation you provided, it is perfectly possible to push a 0 into the stack.
By the way, I would reimplement your pop() method like this:
public int? pop()
{
if (N != 0)
{
return s[--N];
}
else
{
return null;
}
}
This way, it returns null in case the stack is empty.
You should realize that it doesn't matter what the values S[N], S[N+1], ... are since you are only using the values S[0..N-1] for your implementation. You consider the part S[N...] as uninitialized and adding a new element, even 0, causes S[N] to become initialized as the new value.
You can push 0 nothing prevents it. N is equal to number of elements, it's also used to track index of next item to push N == (index of last element + 1). The problem i see is that if you run pop() too many times you will get IndexOutOfRangeException.
You can add IsEmpty property like this:
public bool IsEmpty
{
get { return N < 1; }
}

Method that accepts both float[] and double[] arrays

I have a method that accepts an array (float or double), start and end index and then does some element manipulations for indexes in startIndex to endIndex range.
Basically it looks like this:
public void Update(float[] arr, int startIndex, int endIndex)
{
if (condition1)
{
//Do some array manipulation
}
else if (condition2)
{
//Do some array manipulation
}
else if (condition3)
{
if (subcondition1)
{
//Do some array manipulation
}
}
}
Method is longer than this, and involves setting some elements to 0 or 1, or normalizing the array.
The problem is that I need to pass both float[] and double[] arrays there, and don't want to have a duplicated code that accepts double[] instead.
Performance is also critical, so I don't want to create a new double[] array, cast float array to it, perform calcs, then update original array by casting back to floats.
Is there any solution to it that avoids duplicated code, but is also as fast as possible?
You have a few options. None of them match exactly what you want, but depending on what kind of operations you need you might get close.
The first is to use a generic method where the generic type is restricted, but the only operations you can do are limited:
public void Update<T>(T[] arr, int startIndex, int endIndex) : IComarable
{
if (condition1)
{
//Do some array manipulation
}
else if (condition2)
{
//Do some array manipulation
}
else if (condition3)
{
if (subcondition1)
{
//Do some array manipulation
}
}
}
And the conditions and array manipulation in that function would be limited to expressions that use the following forms:
if (arr[Index].CompareTo(arr[OtherIndex])>0)
arr[Index] = arr[OtherIndex];
This is enough to do things like find the minimum, or maximum, or sort the items in the array. It can't do addition/subtraction/etc, so this couldn't, say, find the average. You can make up for this by creating your own overloaded delegates for any additional methods you need:
public void Update<T>(T[] arr, int startIndex, int endIndex, Func<T,T> Add) : IComarable
{
//...
arr[Index] = Add(arr[OtherIndex] + arr[ThirdIndex]);
}
You'd need another argument for each operation that you actually use, and I don't know how that will perform (that last part's gonna be a theme here: I haven't benchmarked any of this, but performance seems to be critical for this question).
Another option that came to mind is the dynamic type:
public void Update(dynamic[] arr, int startIndex, int endIndex)
{
//...logic here
}
This should work, but for something called over and over like you claim I don't know what it would do to the performance.
You can combine this option with another answer (now deleted) to give back some type safety:
public void Update(float[] arr, int startIndex, int endIndex)
{
InternalUpdate(arr, startIndex, endIndex);
}
public void Update(double[] arr, int startIndex, int endIndex)
{
InternalUpdate(arr, startIndex, endIndex);
}
public void InternalUpdate(dynamic[] arr, int startIndex, int endIndex)
{
//...logic here
}
One other idea is to cast all the floats to doubles:
public void Update(float[] arr, int startIndex, int endIndex)
{
Update( Array.ConvertAll(arr, x => (double)x), startIndex, endIndex);
}
public void Update(double[] arr, int startIndex, int endIndex)
{
//...logic here
}
Again, this will re-allocate the array, and so if that causes a performance issue we'll have to look elsewhere.
If (and only if) all else fails, and a profiler shows that this is a critical performance section of your code, you can just overload the method and implement the logic twice. It's not ideal from a code maintenance standpoint, but if the performance concern is well-established and documented, it can be the worth the copy pasta headache. I included a sample comment to indicate how you might want to document this:
/******************
WARNING: Profiler tests conducted on 12/29/2014 showed that this is a critical
performance section of the code, and that separate double/float
implementations of this method produced a XX% speed increase.
If you need to change anything in here, be sure to change BOTH SETS,
and be sure to profile both before and after, to be sure you
don't introduce a new performance bottleneck. */
public void Update(float[] arr, int startIndex, int endIndex)
{
//...logic here
}
public void Update(double[] arr, int startIndex, int endIndex)
{
//...logic here
}
One final item to explore here, is that C# includes a generic ArraySegment<T> type, that you may find useful for this.
Just an idea. I have no idea what the performance implications are, but this helped me to go to sleep :P
public void HardcoreWork(double[] arr){HardcoreWork(arr, null);}
public void HardcoreWork(float[] arr){HardcoreWork(null, arr);}
public struct DoubleFloatWrapper
{
private readonly double[] _arr1;
private readonly float[] _arr2;
private readonly bool _useFirstArr;
public double this[int index]
{
get {
return _useFirstArr ? _arr1[index] : _arr2[index];
}
}
public int Length
{
get {
return _useFirstArr ? _arr1.Length : _arr2.Length;
}
}
public DoubleFloatWrapper(double[] arr1, float[] arr2)
{
_arr1 = arr1;
_arr2 = arr2;
_useFirstArr = _arr1 != null;
}
}
private void HardcoreWork(double[] arr1, float[] arr2){
var doubleFloatArr = new DoubleFloatWrapper(arr1, arr2);
var len = doubleFloatArr.Length;
double sum = 0;
for(var i = 0; i < len; i++){
sum += doubleFloatArr[i];
}
}
Don't forget that if the amount of elements you have is ridiculously small, you can just use pooled memory, which will give you zero memory overhead.
ThreadLocal<double[]> _memoryPool = new ThreadLocal<double[]>(() => new double[100]);
private void HardcoreWork(double[] arr1, float[] arr2){
double[] array = arr1;
int arrayLength = arr1 != null ? arr1.Length : arr2.Length;
if(array == null)
{
array = _memoryPool.Value;
for(var i = 0; i < arr2.Length; i++)
array[i] = arr2[i];
}
for(var i = 0; i < 1000000; i++){
for(var k =0; k < arrayLength; k++){
var a = array[k] + 1;
}
}
}
What about implementing the method using generics? An abstract base class can be created for your core business logic:
abstract class MyClass<T>
{
public void Update(T[] arr, int startIndex, int endIndex)
{
if (condition1)
{
//Do some array manipulation, such as add operation:
T addOperationResult = Add(arr[0], arr[1]);
}
else if (condition2)
{
//Do some array manipulation
}
else if (condition3)
{
if (subcondition1)
{
//Do some array manipulation
}
}
}
protected abstract T Add(T x, T y);
}
Then implement per data type an inheriting class tuned to type-specific operations:
class FloatClass : MyClass<float>
{
protected override float Add(float x, float y)
{
return x + y;
}
}
class DoubleClass : MyClass<double>
{
protected override double Add(double x, double y)
{
return x + y;
}
}
John's comment about macros, although completely inaccurate characterization of C++ templates, got me thinking about the preprocessor.
C#'s preprocessor is nowhere near as powerful as C's (which C++ inherits), but it still is able to handle everything you need except the duplication itself:
partial class MyClass
{
#if FOR_FLOAT
using Double = System.Single;
#endif
public void Update(Double[] arr, int startIndex, int endIndex)
{
// do whatever you want, using Double where you want the type to change, and
// either System.Double or double where you don't
}
}
Now, you need to include two copies of the file in your project, one of which has an extra
#define FOR_FLOAT
line at the top. (Should be fairly easy to automate adding that)
Unfortunately, the /define compiler option applies to the entire assembly, not per-file, so you can't use a hardlink to include the file twice and have the symbol only defined for one. However, if you can tolerate the two implementations being in different assemblies, you can include the same source file into both, using the project options to define FOR_FLOAT in one of them.
I still advocate using templates in C++/CLI.
Most code isn't so performance-critical that taking the time to convert from float to double and back causes a problem:
public void Update(float[] arr, int startIndex, int endIndex)
{
double[] darr = new double[arr.Length];
for(int i=startIndex; i<endIndex; i++)
darr[i] = (double) arr[i];
Update(darr, startIndex, endIndex);
for(int j=startIndex; j<endIndex; j++)
arr[j] = darr[j];
}
Here's a thought experiment. Imagine that instead of copying, you duplicated the code of the double[] version to make a float[] version. Imagine that you optimized the float[] version as much as necessary.
Your question is then: does the copying really take that long? Consider that instead of maintaining two versions of the code, you could spend your time improving the performance of the double[] version.
Even if you had been able to use generics for this, it's possible that the double[] version would want to use different code from the float[] version in order to optimize performance.

Fill List<int> with default values? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Auto-Initializing C# Lists
I have a list of integers that has a certain capacity that I would like to automatically fill when declared.
List<int> x = new List<int>(10);
Is there an easier way to fill this list with 10 ints that have the default value for an int rather than looping through and adding the items?
Well, you can ask LINQ to do the looping for you:
List<int> x = Enumerable.Repeat(value, count).ToList();
It's unclear whether by "default value" you mean 0 or a custom default value.
You can make this slightly more efficient (in execution time; it's worse in memory) by creating an array:
List<int> x = new List<int>(new int[count]);
That will do a block copy from the array into the list, which will probably be more efficient than the looping required by ToList.
int defaultValue = 0;
return Enumerable.Repeat(defaultValue, 10).ToList();
if you have a fixed length list and you want all the elements to have the default value, then maybe you should just use an array:
int[] x = new int[10];
Alternatively this may be a good place for a custom extension method:
public static void Fill<T>(this ICollection<T> lst, int num)
{
Fill(lst, default(T), num);
}
public static void Fill<T>(this ICollection<T> lst, T val, int num)
{
lst.Clear();
for(int i = 0; i < num; i++)
lst.Add(val);
}
and then you can even add a special overload for the List class to fill up to the capacity:
public static void Fill<T>(this List<T> lst, T val)
{
Fill(lst, val, lst.Capacity);
}
public static void Fill<T>(this List<T> lst)
{
Fill(lst, default(T), lst.Capacity);
}
Then you can just say:
List<int> x = new List(10).Fill();
Yes
int[] arr = new int[10];
List<int> list = new List<int>(arr);
var count = 10;
var list = new List<int>(new int[count]);
ADD
Here is generic method to get the list with default values:
public static List<T> GetListFilledWithDefaulValues<T>(int count)
{
if (count < 0)
throw new ArgumentException("Count of elements cannot be less than zero", "count");
return new List<T>(new T[count]);
}

Categories