problem z wyświetlaniem tablicy

0

Witam

mam mały problem - generuję sobie macierz za pomocą metod. Po kliknięciu w button1, wyświetlam tą macierz w textboksie. Nowe kliknięcie w button1 - nowa, wygenerowana macierz.
Chcę aby po kliknięciu w button3 pojawiała się ostatnia, wygenerowana macierz. Lecz niestety, w tym kodzie, po kliknięciu w button3, macierz generuje się od nowa (efekt jak po kliknięciu w button1). Napisałem metodę Wyswietl(), która miała wyświetlać tą macierz, lecz nie za dobrze działa. Jak zrobić, aby wyswietlała ją, bez generowania od nowa?
Co robię źle? Metod dopiero się uczę, coś tam samemu kombinuję.

       
        public decimal[,] Zadeklaruj()
        {
            int rozmiar = Convert.ToInt32(numericUpDown1.Value);
            decimal[,] macierz_a = new decimal[rozmiar, rozmiar];
            return macierz_a;
        }
        public decimal[,] Generuj()
        {
            textBox1.Clear();
            var losowo = new Random();
            decimal[,] macierz_a = Zadeklaruj();
            for (int i = 0; i < macierz_a.GetLength(0); i++)
            {
                for (int j = 0; j < macierz_a.GetLength(1); j++)
                {
                    macierz_a[i, j] = Math.Round((decimal)losowo.NextDouble(), 2);
                }
            }
            return macierz_a;
        }
        public decimal[,] Wyswietl()
        {
            decimal[,] macierz_a = Generuj();
            for (int i = 0; i < macierz_a.GetLength(0); i++)
            {
                string line = string.Empty;
                for (int j = 0; j < macierz_a.GetLength(1); j++)
                {
                    line += macierz_a[i, j] + "zł" + "   ";
                }
                textBox1.AppendText(line + "\n");
            }
            return macierz_a;
        }

(..)

        private void button1_Click(object sender, EventArgs e)
        {
            Zadeklaruj();
            Generuj();
            Wyswietl();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Wyswietl();
        }
0

A jak może się od nowa nie generować skoro w metodzie Wyswietl() wywołujesz metodę Generuj()?

0

no dobrze, a jak mogę z metody Generuj() przenieść do metody Wyświetl() samą tablicę macierz_a?

0

To sobie zapisz gdzieś tą macierz, którą masz wyświetlić.

0

nie za bardzo rozumiem. Jak zapisać? gdzie zapisać? return w metodzie Generuj nie wystarcza?

0

W klasie formy np. zapisz sobie tą tablicę i zamiast zwracać wyniki (tablice) z tych funkcji zapisuj do tej zmiennej właśnie w klasie formy. W funkcji Wyświetl po prostu wyświetl tą tablicę. W Generuj wygeneruj do tej zmiennej.

0

O takie coś chodzi?
Ten kod poniższy nie chce się skompilować. Wyrzuca taki błąd

Error 2 A field initializer cannot reference the non-static field, method, or property

A o to sam kod: (podkresla na czerwono numericUpDown i [rozmiar,rozmiar] - na samym początku kodu)

    public partial class Form1 : Form
    {
        int rozmiar = Convert.ToInt32(numericUpDown1.Value);
        decimal[,] macierz_a = new decimal[rozmiar, rozmiar];

        public Form1()
        {
            InitializeComponent();

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            label1.Hide();
            label2.Text = "Wybierz rozmiar macierzy";
            button1.Text = "Generuj!";
        }
        public decimal[,] Generuj()
        {
            textBox1.Clear();
            var losowo = new Random();
            for (int i = 0; i < macierz_a.GetLength(0); i++)
            {
                for (int j = 0; j < macierz_a.GetLength(1); j++)
                {
                    macierz_a[i, j] = Math.Round((decimal)losowo.NextDouble(), 2);
                }
            }
            return macierz_a;
        }

        public decimal[,] Wyswietl()
        {
            for (int i = 0; i < macierz_a.GetLength(0); i++)
            {
                string line = string.Empty;
                for (int j = 0; j < macierz_a.GetLength(1); j++)
                {
                    line += macierz_a[i, j] + "zł" + "   ";
                }
                textBox1.AppendText(line + "\n");
            }
            return macierz_a;
        }
}
0

Spróbuj dać inicjalizację zmiennych do konstruktora.

0

Ideą i celem metody jest to, aby dobrze robiła JEDNĄ rzecz. Czyli metoda do generowania macierzy nie powinna używać żadnych TextBoxów. Poza tym powinna przyjmować rozmiar macierzy, którą trzeba wygenerować.

 
        private decimal[,] Generuj(int rozmiar)
        {
            decimal[,] macierz = new decimal[rozmiar, rozmiar];
            var losowo = new Random();
            for (int i = 0; i < macierz.GetLength(0); i++)
            {
                for (int j = 0; j < macierz.GetLength(1); j++)
                {
                    macierz[i, j] = Math.Round((decimal)losowo.NextDouble(), 2);
                }
            }
            return macierz;
        }

Z kolei metoda do wyświetlania ma wyświetlać - po co ma ona cokolwiek zwracać? Za to ona powinna czyścić TextBoxa.

private void Wyswietl(decimal[,] macierz)
        {
            textBox1.Clear();
            for (int i = 0; i < macierz.GetLength(0); i++)
            {
                string line = string.Empty;
                for (int j = 0; j < macierz.GetLength(1); j++)
                {
                    line += macierz[i, j] + "zł" + "   ";
                }
                textBox1.AppendText(line + "\n");
            }
        }

No i teraz obsługa przycisków:

// deklaracja pola
decimal[,] macierz_a;
// reszta kodu
private void button1_Click(object sender, EventArgs e)
        {
            this.macierz_a = this.Generuj();
            this.Wyswietl(this.macierz_a);
        }
 
        private void button3_Click(object sender, EventArgs e)
        {
            this.Wyswietl(this.macierz_a);
        }

Pytanie zasadnicze - czemu używasz typu decima?

0

dziękuję za rzeczowe informacje :) szczególnie o metodach!

@somekind & xeo545x39
zrobiłem tak jak radziliście. Wyszedł taki oto kod.

    public partial class Form1 : Form
    {
        int rozmiar;
        decimal[,] macierz_a;
        public Form1()
        {
            InitializeComponent();
            rozmiar = Convert.ToInt32(numericUpDown1.Value);
            macierz_a = new decimal[rozmiar, rozmiar];
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            label1.Hide();
            label2.Text = "Wybierz rozmiar macierzy";
            button1.Text = "Generuj!";
        }
        private decimal[,] Generuj(int rozmiar)
        {
            decimal[,] macierz = new decimal[rozmiar, rozmiar];
            var losowo = new Random();
            for (int i = 0; i < macierz.GetLength(0); i++)
            {
                for (int j = 0; j < macierz.GetLength(1); j++)
                {
                    macierz[i, j] = Math.Round((decimal)losowo.NextDouble(), 2);
                }
            }
            return macierz;
        }

        private void Wyswietl(decimal[,] macierz)
        {
            textBox1.Clear();
            for (int i = 0; i < macierz.GetLength(0); i++)
            {
                string line = string.Empty;
                for (int j = 0; j < macierz.GetLength(1); j++)
                {
                    line += macierz[i, j] + "zł" + "   ";
                }
                textBox1.AppendText(line + "\n");
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int rozmiar = Convert.ToInt32(numericUpDown1.Value);
            this.macierz_a = this.Generuj(rozmiar);
            this.Wyswietl(this.macierz_a);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            this.Wyswietl(this.macierz_a);
        }
    }

lecz powyższy kod nie chce się spompilować - wyrzuca błąd:

does not contain a definition for 'numericUpDown1_ValueChanged' and no extension method 'numericUpDown1_ValueChanged' accepting a first argument of type

(dla linijki rozmiar = Convert.ToInt32(numericUpDown1.Value); -> na samym początku).
Do tego podkreśla w Form1.Designer.cs atrybut "this.numericUpDown1.ValueChanged += new System.EventHandler(this.numericUpDown1_ValueChanged);".

Co jest nie tak?

0

Do numericUpDown1 dostałeś sobie zdarzenia ValueChanged, a potem ją skasowałeś z pliku, ale nie z listy zdarzeń tej kontrolki w designerze. Usuń je również stamtąd.

1

Czasem zdarza się też, że po usunięciu z listy zdarzeń w designerze i tak w pliku designer.cs zostaje. Najprościej jest wtedy usunąć ręcznie z tego pliku, ale tylko jeżeli wiesz co robisz.

0

już wczoraj sam do tego doszedłem, w każdym razie - dzięki wielkie za pomoc :) wszystko działa pięknie i jak należy.
Mam tylko kilka pytań as beginner as hell:
@somekind - czemu służy this. w obsłudze przycisków? (np -this.Wyswietl(this.macierz_a))
Próbowałem poczytać na msdnie o tym, lecz nie jest to za bardzo jasne dla mnie - mógłbyś mi to wyjaśnić?

No i na koniec - czy jest jakiś sposób na szybkie posortowanie wartości tablicy wielowymiarowych? Ewentualnie, znalezienie najmniejszej/największej wartości w tej tablicy? Array.Sort() działa tylko dla tablic jednowymiarowych, a czy jest jakaś metoda dla tablic n-wymiarowych? Czy trzeba będzie przenieść sobie jakiś algorytm sortowania na c#? a jak tak - to który najlepiej?

pzdr!

1

Słowa kluczowe this i base

A co do sortowania wielowymiarowych, wpisz w G: "sorting multidimensional arrays csharp".

0
Kokoszz napisał(a)

@somekind - czemu służy this. w obsłudze przycisków? (np -this.Wyswietl(this.macierz_a))
Próbowałem poczytać na msdnie o tym, lecz nie jest to za bardzo jasne dla mnie - mógłbyś mi to wyjaśnić?

Link od @xeo545x39 chyba wszystko wyjaśnia.

No i na koniec - czy jest jakiś sposób na szybkie posortowanie wartości tablicy wielowymiarowych?

A co to jest sortowanie tablic wielowymiarowych?
Bo np. dla takiej tablicy:
4 5 9
9 1 2
8 17 13

Posortowana jest taka:
9 1 2
4 5 9
8 17 13

Taka:
1 2 4
5 8 9
9 13 17

I taka:
4 5 9
8 17 13
9 1 2

Ewentualnie, znalezienie najmniejszej/największej wartości w tej tablicy?

Dwie pętle i zmienna pomocnicza. :)

0

co do słowa this. - zrozumiałem, super wytłumaczone :) dzięki!

Co do tablic wielowymiarowych i ich sortowania:
powiem szczerze że mało z tego rozumiem. Mam zadanie aby w takiej wygenerowanej tablicy znaleźć wartość największą/najmniejszą, oraz wyświetlić jej indeksy. Jak się do tego zabrać? Jakiś przykład?

EDIT
@somekind
1 2 4
5 8 9
9 13 17 -> o takie sortowanie mi chodziło, lecz w gruncie rzeczy bardziej chodzi mi o szukanie wartosci min/max w tej tablicy + wyświetlanie jej indeksu w danej tablicy.

Dwie pętle i zmienna pomocnicza. :)

How to do it?

0

Tablicę wielowymiarową można sortować np. według pierwszego elementu wiersza albo według sumy elementów w wierszu oraz na tysiąc innych sposobów.
Ale jeśli masz wyświetlić najmniejszą i największą wartość, to nie musisz, a nawet nie powinieneś, niczego sortować, a jedynie przejść po wszystkich elementach tablicy i określić, który jest najmniejszy, a który największy.
Nie napiszę Ci tego kodu, bo nie chcę Ci odbierać tej satysfakcji.

0

Nie napiszę Ci tego kodu, bo nie chcę Ci odbierać tej satysfakcji.

nawet tego nie oczekiwałem :) już sobie poradziłem, metoda napisana, wszystko działa - no i satysfakcja jest oczywiście :)

przy okazji. Poradziłem sobie inaczej z sortowaniem tablicy - a przynajmniej mam pewien pomysł. Można przenieść każdą wartość z macierzy do listy o długości n*n, gdzie n to wymiar macierzy. Potraktować ją .Sort() i mamy posortowaną listę elementów z macierzy_a. A potem pozostaje tylko wsadzić posortowane elementy z listy do macierzy_b. I tu jest problem, ale najpierw pokażę mój kod który udało mi się dopisać co do sortowania.

(...)        
        //**Przenosimy wartosci z macierzy_a do listy + sortujemy i zwracamy listę**//
        private List<decimal> Sortujlista(decimal[,] macierz)
        {
            dolisty.Clear();
            for (int i = 0; i < macierz.GetLength(0); i++)
            {
                for (int j = 0; j < macierz.GetLength(1); j++)
                {
                    dolisty.Add(macierz[i, j]);
                }
            }
            dolisty.Sort();
            return dolisty;
        }
        //**Pasiłoby ją wyświetlić w końcu, c'nie?**//
        private void Wyswietl_liste(List<decimal> lista)
        {
            textBox1.Clear();
            int ziomek = rozmiar * rozmiar;
            foreach (var i in Enumerable.Range(0, ziomek))
            {
                textBox1.AppendText(Convert.ToString(lista[i]) + "zł" + "   ");
            }
        }
        }
(...)
        private void button4_Click(object sender, EventArgs e)
        {
            this.Sortujlista(this.macierz_a);
            this.Wyswietl_liste(this.dolisty);
        }

Pierwsza rzecz - powyższy kod nie działa. Wcześniej miałem wszystko w jednej metodzie (która działała, ale nic nie zwracała - od razu robiła listę i generowała), ale chciałem rozbić to elegancko na osobno sortowanie(zwracanie listy) i wyświetlanie - teraz nie działa, nie wyświetla nic na textboksie. Co może być nie tak? Kod się kompiluje <magiczna kula wróżbity>

i na końcu - to moja wstępna i "na brudno" metoda do generowania macierzy_b z elementów listy "dolisty". Nie jestem pewny czy zadziała i czy w ogóle dobry pomysł przyjąłem.

        //**WAZZUP**//
        private decimal[,] Posortowana(int rozmiar, list<decimal> lista)
        {
            int p = 0;
            decimal[,] macierz_b = new decimal[rozmiar, rozmiar];
            for (int i = 0; i < macierz_b.GetLength(0); i++)
            {
                for (int j = 0; j < macierz_b.GetLength(0); j++)
                {
                    macierz_b[i, j] = lista[p];
                    p=p+1; // ???
                }
            }
            return macierz_b;
        }

Co jest nie tak z wyświetlaniem list? Czy ten pomysł na sortowanie tablic ma sens, czy lepiej go porzucić?

pzdr!

0

Co to znaczy "nie działa"? Nie sortuje się? Nie wyświetla?

Czemu w Sortujlista używasz jakiejś zmiennej dolisty, zamiast utworzyć ją sobie w tej metodzie?

Co ma niby robić ten kod, bo w ogóle go nie rozumiem?

        //**Pasiłoby ją wyświetlić w końcu, c'nie?**//
        private void Wyswietl_liste(List<decimal> lista)
        {
            textBox1.Clear();
            int ziomek = rozmiar * rozmiar;
            foreach (var i in Enumerable.Range(0, ziomek))
            {
                textBox1.AppendText(Convert.ToString(lista[i]) + "zł" + "   ");
            }
        }

Chyba chodziło Ci o coś takiego:

        private void WyswietlListe(List<decimal> lista)
        {
            textBox1.Clear();
            foreach (var d in lista)
            {
                textBox1.AppendText(d.ToString() + "zł" + "   ");
            }
        }

Ten fragment kodu powinien wyglądać raczej tak:

private void button4_Click(object sender, EventArgs e)
        {
            List<decimal> listaPosortowana = this.PosortujListę(this.macierz_a);
            this.WyswietlListę(listaPosortowana);
        }

BTW, trzymaj się jakiejś jednej konwencji, nazwy metod zaczyna się wielką literą i nie używa podkreślników, czyli tak: MojaMetoda a nie moja_Metoda.

Czy ten pomysł na sortowanie tablic ma sens, czy lepiej go porzucić?

Myślę, że jest chyba najprostszy w wykonaniu.

Czemu używasz typu decimal?

0

ogólnie dzięki za pomoc somekind :) mój programik został ukończony, działa jak trzeba. Również poradziłem sobie z sortowaniem macierzy, według mojego sposobu. Co do typu decimal - to pozostałość ze starego kodu, gdzie miałem w tablicy bardzo małe ułamki :)

pzdr!

1 użytkowników online, w tym zalogowanych: 0, gości: 1