Tablice dynamiczne i klasa Array. Visual Studio C#
Pracę z tablicami ułatwia klasa Array. Szerszy opis metod tej klasy znajdziesz pod tym linkiem zobacz. W tym temacie zostanie przedstawiony sposób zwiększania rozmiaru już istniejącej tablicy, sortowanie od A do Z oraz od Z do A przy użyciu metod z klasy Array.
Cel: Napisz aplikację, która będzie bazować na dwóch tablicach jednowymiarowych typu float oraz tablic wielowymiarowej służącej do przechowywania elementów poprzednich tablic oraz wyników podstawowych działań arytmetycznych. Zastosuje sortowanie tablic i dynamicznie zwiększenie ich rozmiaru.
Krok 1. Układ komponentów
- GroupBox- sztuk 4
- Label- sztuk 1
- Button- sztuk 7
- TextBox- sztuk 4
Wybranym kontrolkom właściwość pola Dock ustaw na Fill
Przypisz tryb pracy w układzie wielu linii.
Dodaj możliwość przewijania zawartości w pionie
Proponowany układ kontrolek
Krok 2. Deklaracja zmiennych
Zadeklarujemy zmienne lokalne w klasie Form1 związane z funkcjonowaniem aplikacji. Przeznaczenie zmiennych jest podane w komentarzach podanego fragmentu kodu
Wskazówka:
public partial class Form1 : Form
{
//poczatkowy rozmiar tablic
static int rozmiar = 1;
//tablice jednowymiarowe
float[] t1 = new float[rozmiar],
t2 = new float[rozmiar];
//tablica wielowymiarowa
float[,] tabWynikow;
//generator liczb losowych
Random los = new Random();
public Form1()
{
Krok 3. Inicjujemy początkowe wartości tablic jednowymiarowych
W konstruktorze klasy Form wykonamy przypisanie początkowych losowych wartości tablicom jednowymiarowym
Wskazówka:
public Form1()
{
InitializeComponent();
for (int i = 0; i < t1.GetLength(0); i++)
{
t1.SetValue(los.Next(0, 100), i);
t2.SetValue(los.Next(0, 100), i);
}
}
Aby się przekonać jakie wartości zostały wylosowane napiszemy uniwersalną funkcję wypisującą zawartość tablicy jednowymiarowej. Funkcja będzie wywoływana w kilku miejscach tworzonego kodu.
Wskazówka:
void wypiszTablice(Array t, TextBox tb)
{
tb.Clear();
for(int i=0;i<t.GetLength(0); i++)
tb.AppendText((i + 1).ToString() + ") "
+ t.GetValue(i).ToString()
+Environment.NewLine);
}
Jej pierwsze wywołanie wykonamy z zdarzeniu Load formatki głównego okna aplikacji
Wskazówka:
private void Form1_Load(object sender, EventArgs e)
{
wypiszTablice(t1, textBox1);
wypiszTablice(t2, textBox2);
}
Skompiluj program i sprawdź efekt działania. Poniższa ilustracja przedstawia funkcjonowanie bieżącego kodu aplikacji
Krok 4. Zwiększamy rozmiar tablic
Napiszemy uniwersalną funkcję zwiększającą rozmiar tablic już istniejących bez zmiany dotychczasowych wartości wylosowanych elementów
Wskazówka:
void zwiekszRozmiarTablicy(ref float[] t, int rozmiar)
{
//odczytaj stary rozmiar tablicy
int staryRozmiar = t.GetLength(0);
//ustaw nowy rozmiar
Array.Resize(ref t, rozmiar);
//
for (int i = staryRozmiar; i < rozmiar; i++)
t.SetValue(los.Next(0, 100), i);
}
Efekt zwiększania rozmiaru i dopisywania nowych elementów wywołamy w zdarzeniu Click kontrolki button1
Wskazówka:
private void button1_Click(object sender, EventArgs e)
{
int rozmiar = Convert.ToInt16(textBox4.Text);
zwiekszRozmiarTablicy(ref t1,t1.GetLength(0) + rozmiar);
wypiszTablice(t1, textBox1);
zwiekszRozmiarTablicy(ref t2, t2.GetLength(0) + rozmiar);
wypiszTablice(t2, textBox2);
}
Skompiluj program i sprawdź efekt działania. Prawidłowo działającą aplikację przedstawia poniższa ilustracja
Krok 5. Sortowanie zawartości tablic w kierunku od A do Z
Wykorzystamy wbudowaną funkcję Sort klasy Array. Jej podstawowe wywołanie zawiera poniższy kod
Wskazówka:
void Sortuj_AdoZ_i_Wypisz(ref float[] t,TextBox tb)
{
Array.Sort(t);
wypiszTablice(t, tb);
}
Działanie sprawdzimy w metodzie Click kontrolki button2
Wskazówka:
private void button2_Click(object sender, EventArgs e)
{
Sortuj_AdoZ_i_Wypisz(ref t1, textBox1);
}
Skompiluj program i sprawdź efekt działania. Efekt przedstawia poniższa ilustracja
Krok 6. Sortowanie zawartości tablicy w kierunku od Z do A
To funkcjonowanie programu jest odwrotne do poprzedniego działania. Wykorzystamy metody klasy Array sortowania i odwracania pozycji elementów w tablicy
Wskazówka:
void Sortuj_ZdoA_i_Wypisz(ref float[] t, TextBox tb)
{
Array.Sort(t);
Array.Reverse(t);
wypiszTablice(t, tb);
}
Działanie sprawdzimy w metodzie Click kolejnej kontrolki Button
Wskazówka:
private void button7_Click(object sender, EventArgs e)
{
Sortuj_ZdoA_i_Wypisz(ref t2, textBox2);
}
Skompiluj program i sprawdź efekt działania. Działanie przedstawia poniższa ilustracja
Krok 7. Funkcja sumowania i przypisywania wyniku do tablicy wielowymiarowej
Piszemy uniwersalna funkcję wykonującą dodawanie elementów z dwóch równoległych indeksów tablic jednowymiarowych i przypisanie tych elementów oraz wyniku sumowania do tablicy wielowymiarowej. Jest to proponowany kod rozwiązania zasad pracy z tablicami przedstawiony w celach dydaktycznych.
Wskazówka:
void Dodawanie(float[] tA,float[] tB,ref float[,] tWynik,TextBox tb)
{
tb.Clear();
int rozmiar = tA.GetLength(0);
tWynik = new float[rozmiar, 3];
for(int i = 0; i < rozmiar; i++)
{
tWynik[i,0] = tA[i];
tWynik[i,1] = tB[i];
tWynik[i,2] = tWynik[i,0] + tWynik[i,1];
tb.AppendText((i + 1).ToString() + ")"
+ tabWynikow[i, 0].ToString()
+ "+" + tabWynikow[i, 1].ToString()
+ "=" + tabWynikow[i, 2].ToString()
+ Environment.NewLine);
}
}
Wywołanie tej funkcji wykonamy w zdarzeniu Click z zastosowaniem rzutowania obiektów rozpoznawanych pod właściwości Tag w funkcji switch
Wskazówka:
private void button3_Click(object sender, EventArgs e)
{
Button bt = sender as Button;
switch (bt.Tag)
{
case "+":Dodawanie(t1, t2,ref tabWynikow,textBox3); break;
}
}
Skompiluj program i sprawdź efekt działania. Wynik dodawania wraz z dodawanymi elementami przedstawia poniższa ilustracja
Ćwiczenie sprawdzające: Napisz uniwersalne funkcje odejmowania, mnożenia i dzielenia wraz z zabezpieczeniem przed dzieleniem przez zero.
Rozwiązanie pod konsolę
Zrzut ekranu
Kod rozwiązania
Wskazówka:
namespace tablice_dynamiczne_i_klasa_array
{
internal class Program
{
//poczatkowy rozmiar tablic
static int rozmiar = 1;
//tablice jednowymiarowe
static float[] t1 = new float[rozmiar],
t2 = new float[rozmiar];
//tablica wielowymiarowa
static float[,] tabWynikow;
//generator liczb losowych
static Random los = new Random();
static void wypiszTablice(Array t)
{
for (int i = 0; i < t.GetLength(0); i++)
Console.WriteLine(i + "\t" + t.GetValue(i));
}
//ref- słowo kluczowe dotyczące wartości zwracanej przez odwołanie
static void zwiekszRozmiarTablicy(ref float[] t, int rozmiar)
{
//odczytaj stary rozmiar tablicy
int staryRozmiar = t.GetLength(0);
//ustaw nowy rozmiar
Array.Resize(ref t, rozmiar);
//
for (int i = staryRozmiar; i < rozmiar; i++)
t.SetValue(los.Next(0, 100), i);
}
static void Sortuj_AdoZ_i_Wypisz(ref float[] t)
{
Array.Sort(t);
wypiszTablice(t);
}
static void Sortuj_ZdoA_i_Wypisz(ref float[] t)
{
Array.Sort(t);
Array.Reverse(t);
wypiszTablice(t);
}
static void Dodawanie(float[] tA, float[] tB, ref float[,] tWynik)
{
int rozmiar = tA.GetLength(0);
//rób tablicę o trzech wymiarach
tWynik = new float[rozmiar, 3];
for (int i = 0; i < rozmiar; i++)
{
tWynik[i, 0] = tA[i];
tWynik[i, 1] = tB[i];
tWynik[i, 2] = tWynik[i, 0] + tWynik[i, 1];
Console.WriteLine(tWynik[i,0]+"\t"
+ tWynik[i,1]+"\t"
+ tWynik[i,2]);
}
}
static void Odejmowanie(float[] tA, float[] tB, ref float[,] tWynik)
{
int rozmiar = tA.GetLength(0);
//rób tablicę o trzech wymiarach
tWynik = new float[rozmiar, 3];
for (int i = 0; i < rozmiar; i++)
{
tWynik[i, 0] = tA[i];
tWynik[i, 1] = tB[i];
tWynik[i, 2] = tWynik[i, 0] - tWynik[i, 1];
Console.WriteLine(tWynik[i, 0] + "\t"
+ tWynik[i, 1] + "\t"
+ tWynik[i, 2]);
}
}
static void Mnozenie(float[] tA, float[] tB, ref float[,] tWynik)
{
int rozmiar = tA.GetLength(0);
//rób tablicę o trzech wymiarach
tWynik = new float[rozmiar, 3];
for (int i = 0; i < rozmiar; i++)
{
tWynik[i, 0] = tA[i];
tWynik[i, 1] = tB[i];
tWynik[i, 2] = tWynik[i, 0] * tWynik[i, 1];
Console.WriteLine(tWynik[i, 0] + "\t"
+ tWynik[i, 1] + "\t"
+ tWynik[i, 2]);
}
}
static void Dzielenie(float[] tA, float[] tB, ref float[,] tWynik)
{
int rozmiar = tA.GetLength(0);
tWynik = new float[rozmiar, 3];
for (int i = 0; i < rozmiar; i++)
{
tWynik[i, 0] = tA[i];
tWynik[i, 1] = tB[i];
if (tWynik[i, 1] != 0)
{
tWynik[i, 2] = tWynik[i, 0] / tWynik[i, 1];
Console.WriteLine(tWynik[i, 0] + "\t"
+ tWynik[i, 1] + "\t"
+ tWynik[i, 2].ToString("F3"));
}
else Console.WriteLine("Dzielenie przez zero!");
}
}
static void Main(string[] args)
{
Console.WriteLine("Witaj w CzD!");
//rób tablice o poczatkowym rozmiarze
for (int i = 0; i < t1.GetLength(0); i++)
{
t1.SetValue(los.Next(0, 100), i);
t2.SetValue(los.Next(0, 100), i);
}
Console.WriteLine("Zawartość tablicy t1");
wypiszTablice(t1);
Console.WriteLine("Zawartość tablicy t2");
wypiszTablice(t2);
Console.WriteLine("Wybierz działanie (klawisze: +, -, *, /," +
"r-zmiana rozmiaru,a- sortuj A-Z," +
"z- sortuj Z-A, Esc- koniec)");
ConsoleKeyInfo klawiszInfo;
do
{
klawiszInfo = Console.ReadKey();
switch (klawiszInfo.KeyChar)
{
case '+': Dodawanie(t1, t2, ref tabWynikow); break;
case '-': Odejmowanie(t1, t2, ref tabWynikow); break;
case '*': Mnozenie(t1, t2, ref tabWynikow); break;
case '/': Dzielenie(t1, t2, ref tabWynikow); break;
case 'a': Sortuj_AdoZ_i_Wypisz(ref t1); break;
case 'z': Sortuj_ZdoA_i_Wypisz(ref t1); break;
case 'r':
Console.WriteLine("Podaj nowy rozmiar tablicy: ");
int rozmiar= int.Parse(Console.ReadLine());
zwiekszRozmiarTablicy(ref t1, t1.GetLength(0) + rozmiar);
Console.WriteLine("Zawartośc tab. 1");
wypiszTablice(t1);
zwiekszRozmiarTablicy(ref t2, t2.GetLength(0) + rozmiar);
Console.WriteLine("Zawartośc tab. 2");
wypiszTablice(t2);
break;
}
} while (klawiszInfo.Key != ConsoleKey.Escape);
}
}
}