didactics (4)

  • docx
  • 02.05.2020
Публикация на сайте для учителей

Публикация педагогических разработок

Бесплатное участие. Свидетельство автора сразу.
Мгновенные 10 документов в портфолио.

Иконка файла материала didactics (4).docx

C# array of strings

 

Array. The tiger hunts at night. It searches for its next kill. Its main targets include an array of animals: deer, moose, boars. A string array could represent these animals.

In programs, arrays are inside many things. An array has an element type. Its elements are accessed with an index. An array cannot be resized—it can only be created (and then replaced).Initialize Array

String arrays. We begin with string arrays. Square brackets are used for all arrays. The syntax is simple and easy to remember (with practice).

Version 1:This code creates a string array of 3 elements, and then assign strings to the array indexes (starting at 0).

Version 2:This string array is created with an array initializer expression. It is shorter and easier to type.

Version 3:Here we do not even declare the type of the array. The 3 versions are compiled to the same instructions.

Based on: .NET (2019)
 
C# program that uses string arrays, initializers and Length
 
using System;
 
class Program
{
    static void Main()
    {
        // Version 1: create empty string array, then assign into it.
        string[] animals = new string[3];
        animals[0] = "deer";
        animals[1] = "moose";
        animals[2] = "boars";
        Console.WriteLine("ARRAY 1: " + animals.Length);
 
        // Version 2: use array initializer.
        string[] animals2 = new string[] { "deer", "moose", "boars" };
        Console.WriteLine("ARRAY 2: " + animals2.Length);
 
        // Version 3: a shorter array initializer.
        string[] animals3 = { "deer", "moose", "boars" };
        Console.WriteLine("ARRAY 3: " + animals3.Length);
    }
}
 
Output
 
ARRAY 1: 3
ARRAY 2: 3
ARRAY 3: 3

Int array, parameter. Here is an int array that is passed as a parameter. The entire contents of the array are not copied—just the small reference.

Tip:We can think of an array as a class with a variable number of fields, each accessed with an index.

C# program that receives array parameter
 
using System;
 
class Program
{
    static void Main()
    {
        // Three-element array.
        int[] array = { -5, -6, -7 };
        // Pass array to Method.
        Console.WriteLine(Method(array));
    }
 
    /// <summary>
    /// Receive array parameter.
    /// </summary>
    static int Method(int[] array)
    {
        return array[0] * 2;
    }
}
 
Output
 
-10

Return. We can return arrays from methods. In this example program, we allocate a two-element array of strings in Method(). Then, after assigning its elements, we return it.

C# program that returns array reference
 
using System;
 
class Program
{
    static void Main()
    {
        // Write array from Method.
        Console.WriteLine(string.Join(" ", Method()));
    }
 
    /// <summary>
    /// Return an array.
    /// </summary>
    static string[] Method()
    {
        string[] array = new string[2];
        array[0] = "THANK";
        array[1] = "YOU";
        return array;
    }
}
 
Output
 
THANK YOU

First. How can we get the first element? The first element is at index 0. It can be accessed by using the indexer syntax. To be safe, we often must check for empty arrays.

C# program that gets first array element
 
using System;
 
class Program
{
    static void Main()
    {
        int[] array = new int[2]; // Create an array.
        array[0] = 10;
        array[1] = 3021;
 
        Test(array);
        Test(null); // No output.
        Test(new int[0]); // No output.
    }
 
    static void Test(int[] array)
    {
        if (array != null &&
            array.Length > 0)
        {
            int first = array[0];
            Console.WriteLine(first);
        }
    }
}
 
Output
 
10

Last. The last element's offset is equal to the array Length minus one. Often we need to check against null, and that the Length is greater than zero, before accessing the last element.

C# program that gets last array element
 
using System;
 
class Program
{
    static void Main()
    {
        string[] arr = new string[]
        {
            "cat",
            "dog",
            "panther",
            "tiger"
        };
        // Get the last string element.
        Console.WriteLine(arr[arr.Length - 1]);
    }
}
 
Output
 
tiger

Foreach-loop. With this loop, no indexes are needed—the loop itself handles the indexes. This makes some code simpler. We use string interpolation to display the colors.

Tip:For many programs, a foreach-loop is the clearest loop. If the logic does complicated things with indexes, use for.

C# program that uses foreach, array
 
class Program
{
    static void Main()
    {
        string[] array = { "red", "blue", "green" };
        // Loop with foreach and write colors with string interpolation.
        foreach (string color in array)
        {
            System.Console.WriteLine($"Color = {color}");
        }
    }
}
 
Output
 
Color = red
Color = blue
Color = green

For-loop. Here we use a for-loop to iterate over a string array. The length of this array is 2, so the valid indexes are 0 and 1. The variable "i" is set to each array index.

C# program that uses foreach, for-loops on array
 
using System;
 
class Program
{
    static void Main()
    {
        string[] array = new string[2];
        array[0] = "Socrates";
        array[1] = "Plato";
        // Loop over array by indexes.
        for (int i = 0; i < array.Length; i++)
        {
            string element = array[i];
            Console.WriteLine(element);
        }
    }
}
 
Output
 
Socrates
Plato

 

 

 

 

 

 


Instant Search

C# Example Pages

2D array. A glowing platform appears at the water's edge. The platform is solid. You step onto it. Suddenly an entire dimension is illuminated—a new world is revealed.

In this 2D world, an element is addressed with X and Y. Consider now C#. 2D arrays can store any element type. Jagged arrays can also represent our 2D space.Jagged Arrays

Let us begin. Here we show a two-dimensional string array. We initialize it. Then we use the indexing syntax to access all elements and display their values.

Tip:To access a two-dimensional array element, please use the syntax array[0, 0]. Each dimension is indexed starting at zero.

Result:The program creates a 2x2 string array and then prints out all 4 elements (with no loops).

Based on: .NET (2019)
 
C# program that creates 2D array
 
using System;
 
class Program
{
    static void Main()
    {
        // ... Create 2D array of strings.
        string[,] array = new string[,]
        {
            {"cat", "dog"},
            {"bird", "fish"},
        };
        // ... Print out values.
        Console.WriteLine(array[0, 0]);
        Console.WriteLine(array[0, 1]);
        Console.WriteLine(array[1, 0]);
        Console.WriteLine(array[1, 1]);
    }
}
 
Output
 
cat
dog
bird
fish

Debugger. Above we declare a 2D array. The syntax is somewhat confusing, with curly brackets and commas. We can examine the code in the Visual Studio debugger.

Info:The compiler sees the string[,] array as a string[2, 2] array. It inferred the size (good job, compiler).

GetUpperBound. This method receives the highest index of the specified rank (passed as an argument). It returns an int. This is probably not best for a simple 2D array.

C# program that uses GetUpperBound
 
using System;
 
class Program
{
    static void Main()
    {
        string[,] codes = new string[,]
        {
            {"AA", "BB"},
            {"CC", "DD"}
        };
 
        // Get the upper bound.
        // ... Use for-loop over rows.
        for (int i = 0; i <= codes.GetUpperBound(0); i++)
        {
            string s1 = codes[i, 0];
            string s2 = codes[i, 1];
            Console.WriteLine("{0}, {1}", s1, s2);
        }
    }
}
 
Output
 
AA, BB
CC, DD

Length-based loop. The fastest method for a 2D array is to do some arithmetic. In this example, there are five rows. GetUpperBound(0) will return 4.

And:If we take Length, which is 10, and divide by 2, we get 5. We can iterate until we reach 5.

C# program that uses length-based loop
 
using System;
 
class Program
{
    static void Main()
    {
        string[,] words = new string[,]
        {
            {"ONE", "TWO"},
            {"THREE", "FOUR"},
            {"FIVE", "SIX"}
        };
 
        // Loop based on length.
        // ... Assumes each subarray is two elements long.
        for (int i = 0; i < words.Length / 2; i++)
        {
            string s1 = words[i, 0];
            string s2 = words[i, 1];
            Console.WriteLine("{0}, {1}", s1, s2);
        }
    }
}
 
Output
 
ONE, TWO
THREE, FOUR
FIVE, SIX

GetUpperBound, int example. We cache array bounds in local variables for better performance and clarity. Here we get the two dimensions of the array and iterate through them.

C# program that uses int array, GetUpperBound twice
 
using System;
 
class Program
{
    static void Main()
    {
        int[,] codes = new int[,]
        {
            {200, 400},
            {2000, 4176},
            {20000, 40000}
        };
 
        // Get all bounds before looping.
        int bound0 = codes.GetUpperBound(0);
        int bound1 = codes.GetUpperBound(1);
        // ... Loop over bounds.
        for (int i = 0; i <= bound0; i++)
        {
            for (int x = 0; x <= bound1; x++)
            {
                // Display the element at these indexes.
                Console.WriteLine(codes[i, x]);
            }
            Console.WriteLine();
        }
    }
}
 
Output
 
200
400
 
2000
4176
 
20000
40000

No initializers. We can create an empty 2D array by specifying its dimensions. All elements have the default value (for ints this is 0).

Also:We can use a 2D array reference like int[,] to refer to any array size. The element type must match.

C# program that creates arrays, no initializers
 
using System;
 
class Program
{
    static void Main()
    {
        // A two-dimensional array reference.
        int[,] array = new int[2, 2];
        array[0, 0] = 1;
        Console.WriteLine(array[0, 0]);
 
        // The same reference can hold a different size of array.
        array = new int[3, 3];
        array[2, 2] = 1;
        Console.WriteLine(array[2, 2]);
    }
}
 
Output
 
1
1

Arguments. A method may receive a 2D array by specifying the type of the elements. The dimensions are not used in the argument list—any 2D array of the correct element may be passed.

Tip:Changes to elements in the argument will also affect the original version. Only the reference is copied to the new method.

C# program that uses 2D array as argument
 
using System;
 
class Program
{
    static void PrintFirstElement(bool[,] values)
    {
        // Display value of first element in first row.
        Console.WriteLine(values[0, 0]);
    }
 
    static void Main()
    {
        // Any array size of the right element type can be used.
        bool[,] values = new bool[100, 100];
        values[0, 0] = true;
        PrintFirstElement(values);
    }
}
 
Output
 
True

Loops. 2D array loops are complicated. It is easy to cause errors related to invalid indexes. Here our 2D array is a four-element box, composed of two pairs.

Next:To begin our for-loop, we acquire the upper bound of the zero dimension, and the upper bound of the first dimension of the array.

For

Caution:The loop will not continue to work correctly if the array reference itself is modified or the array data is resized.

C# program that loops over 2D string array
 
using System;
 
class Program
{
    static void Main()
    {
        // Instantiate a new 2D string array.
        string[,] array = new string[2, 2];
        array[0, 0] = "top left";
        array[0, 1] = "top right";
        array[1, 0] = "bottom left";
        array[1, 1] = "bottom right";
 
        // Get upper bounds for the array
        int bound0 = array.GetUpperBound(0);
        int bound1 = array.GetUpperBound(1);
 
        // Use for-loops to iterate over the array elements
        for (int variable1 = 0; variable1 <= bound0; variable1++)
        {
            for (int variable2 = 0; variable2 <= bound1; variable2++)
            {
                string value = array[variable1, variable2];
                Console.WriteLine(value);
            }
            Console.WriteLine();
        }
        Console.ReadLine();
    }
}
 
Output
 
top left
top right
 
bottom left
bottom right

Note, nested loops. These are not always necessary. For example, if you are using a 2D array with only two elements in each row, you can index into positions 0 and 1 from a single for-loop.

Rank. Every array has a rank. This is the number of dimensions in the array. A one-dimensional array has a rank of 1. We access the Rank property from the Array base class.

Here:We design a method (Handle) that receives an array reference. It then tests the Rank of the parameter array.

And:It handles both 1D and 2D arrays in the same method. It uses GetValue to access the array elements.

C# program that uses Rank
 
using System;
 
class Program
{
    static void Main()
    {
        // ... A one-dimensional array.
        int[] one = new int[2];
        one[0] = 1;
        one[1] = 2;
        Handle(one);
 
        // ... A two-dimensional array.
        int[,] two = new int[2, 2];
        two[0, 0] = 0;
        two[1, 0] = 1;
        two[0, 1] = 2;
        two[1, 1] = 3;
        Handle(two);
    }
 
    static void Handle(Array array)
    {
        Console.WriteLine("Rank: " + array.Rank);
        switch (array.Rank)
        {
            case 1:
                for (int i = 0; i < array.Length; i++)
                {
                    Console.WriteLine(array.GetValue(i));
                }
                break;
            case 2:
                for (int i = 0; i < array.GetLength(0); i++)
                {
                    for (int x = 0; x < array.GetLength(1); x++)
                    {
                        Console.Write(array.GetValue(i, x));
                    }
                    Console.WriteLine();
                }
                break;
        }
    }
}
 
Output
 
Rank: 1
1
2
Rank: 2
02
13

Add row, add column. You cannot add a new row or column to a 2D array—the array is fixed in size and a new array must be created to add elements. Here we introduce AddRow and AddColumn.

AddRow:This allocates a new 2D int array and copies the current array into the new one. It then copies a separate int array as a new row.

AddColumn:This allocates a new array with an extra column and copies the previous array. It copies an int array into a new column.

Note:These methods do not "add rows or columns" to a 2D array. Instead they create a new array and add to that.

Tip:For optimal performance, consider using a List and adding int arrays to that. Or add Lists of ints to a List in a 2D list.

C# program that adds row, column to 2D array
 
using System;
 
class Program
{
    static int[,] AddRow(int[,] original, int[] added)
    {
        int lastRow = original.GetUpperBound(0);
        int lastColumn = original.GetUpperBound(1);
        // Create new array.
        int[,] result = new int[lastRow + 2, lastColumn + 1];
        // Copy existing array into the new array.
        for (int i = 0; i <= lastRow; i++)
        {
            for (int x = 0; x <= lastColumn; x++)
            {
                result[i, x] = original[i, x];
            }
        }
        // Add the new row.
        for (int i = 0; i < added.Length; i++)
        {
            result[lastRow + 1, i] = added[i];
        }
        return result;
    }
 
    static int[,] AddColumn(int[,] original, int[] added)
    {
        int lastRow = original.GetUpperBound(0);
        int lastColumn = original.GetUpperBound(1);
        // Create new array.
        int[,] result = new int[lastRow + 1, lastColumn + 2];
        // Copy the array.
        for (int i = 0; i <= lastRow; i++)
        {
            for (int x = 0; x <= lastColumn; x++)
            {
                result[i, x] = original[i, x];
            }
        }
        // Add the new column.
        for (int i = 0; i < added.Length; i++)
        {
            result[i, lastColumn + 1] = added[i];
        }
        return result;
    }
 
    static void Display(int[,] array)
    {
        // Loop over 2D int array and display it.
        for (int i = 0; i <= array.GetUpperBound(0); i++)
        {
            for (int x = 0; x <= array.GetUpperBound(1); x++)
            {
                Console.Write(array[i, x]);
                Console.Write(" ");
            }
            Console.WriteLine();
        }
    }
 
    static void Main()
    {
        int[,] values = { { 10, 20 }, { 30, 40 } };
        Console.WriteLine("CURRENT");
        Display(values);
 
        // Add row and display the new array.
        int[,] valuesRowAdded = AddRow(values,
            new int[] { 50, 60 });
        Console.WriteLine("ADD ROW");
        Display(valuesRowAdded);
 
        // Add column and display the new array.
        int[,] valuesColumnAdded = AddColumn(valuesRowAdded,
            new int[] { -1, -2, -3 });
        Console.WriteLine("ADD COLUMN");
        Display(valuesColumnAdded);
    }
}
 
Output
 
CURRENT
10 20
30 40
ADD ROW
10 20
30 40
50 60
ADD COLUMN
10 20 -1
30 40 -2
50 60 -3

Error, cannot convert. A 2D array is not compatible with a 1D array—the types are different. So we cannot pass a 2D array to a method that accepts a 1D array (or the opposite case).

C# program that causes cannot convert error
 
class Program
{
    static void Main()
    {
        string[,] array = new string[10, 10];
        Test(array);
    }
 
    static void Test(string[] example)
    {
    }
}
 
Results
 
error CS1503: Argument 1: cannot convert from 'string[*,*]' to 'string[]'

Performance, GetUpperBound. GetUpperBound is slow. Its result should be stored in a local variable. This benchmark shows the performance decrease with GetUpperBound.

Version 1:This code uses GetUpperBound 0 to loop over the rows in a 2D array. It stores the result of GetUpperBound in a local.

Version 2:This version uses the fact that each row has 2 elements, so it can derive the total row count from the Length divided by 2.

Result:Using the Length property for a loop boundary is faster than using GetUpperBound.

Benchmark

But:If we access GetUpperBound rarely, and store its result in a local, the performance loss is going to be small in many programs.

C# program that shows GetUpperBound performance
 
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
 
class Program
{
    const int _max = 10000000;
    static void Main()
    {
        int[,] weights = new int[,]
        {
            {100, 20},
            {0, 0},
            {5, 10},
        };
        // Version 1: sum 2D array with GetUpperBound loop.
        var s1 = Stopwatch.StartNew();
        for (int i = 0; i < _max; i++)
        {
            int sum = 0;
            int top = weights.GetUpperBound(0);
            for (int z = 0; z <= top; z++)
            {
                sum += weights[z, 0] + weights[z, 1];
            }
            if (sum != 135)
            {
                return;
            }
        }
        s1.Stop();
        // Version 2: sum 2D array with Length-based loop.
        var s2 = Stopwatch.StartNew();
        for (int i = 0; i < _max; i++)
        {
            int sum = 0;
            int count = weights.Length / 2;
            for (int z = 0; z < count; z++)
            {
                sum += weights[z, 0] + weights[z, 1];
            }
            if (sum != 135)
            {
                return;
            }
        }
        s2.Stop();
        Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
            _max).ToString("0.00 ns"));
        Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) /
            _max).ToString("0.00 ns"));
    }
}
 
Results
 
15.42 ns    GetUpperBound
8.63 ns     Length / 2

Dimensions. In C# we can also specify arrays with more than two dimensions. We can use another comma in the indexing syntax. It will work as expected.Multidimensional Array

Flatten array. A 2D array can be flattened into a 1D array. This can yield some performance improvements. But it makes a program's syntax more complex.Flatten Array

Lists. You can use the generic type List to simulate a jagged or 2D List that is dynamically resizable. The syntax for this nested type is somewhat more confusing.ListList: nested

Tip:A List can solve problems that would otherwise require confusing 2D array resizing and copying.

Jagged array. An array element can have any type. This includes other arrays. With an array of arrays, we construct a jagged array—this gives us great flexibility.Jagged: Array of ArraysArrays

Research. In the CLI standard, I found material about the types of arrays. The Framework determines the type of an array by its rank (dimension count) and its element type.

So:Both parts are considered in determining type. Arrays are not all the same type.

Quote:The rank of an array is the number of dimensions. The type of an array (other than a vector) shall be determined by the type of its elements and the number of dimensions (The CLI Annotated Standard).

2D arrays have many uses. And they can be used in many ways: we showed several indexing approaches. It is easiest to use Length, but GetUpperBound is sometimes needed.

A review. We created 2D arrays and looped over them. We mutated them. We benchmarked them. Before you use 2D arrays, research jagged arrays. These can improve your code.

Dot Net Perls

Written by Sam Allen, info@dotnetperls.com (Dot Net Perls).

© 2007-2019 Sam Allen. All rights reserved.


 

Скачано с www.znanio.ru

Посмотрите также