matematykaszkolna.pl
programowanie Filip: Witam, mam do zrobienia w jezyku C takie polecenie: Prosze zaprojektowac strukture " student" przechowujaca nastepujace dane: imie i nazwisko studenta, jego numer indeksu oraz liste ocen. Prosze napisac funkcje, ktora: a) DOdaje nową ocenę (oceny przechowywane są w pamieci od najstarszej do najonwszej). Sygnatura funkcji void dodajocene(struct student* s, double o); Pomoze ktos? Ja narazie tylko zaprojektowalem struktury, czy tak to bedzie wygladac? struct oceny { int ocena; struct oceny* next; }; struct student { char imie[50]; char nazwisko[50]; int numerindeksu; struct oceny* o; };
29 lis 16:52
HGH: z ciekawosci z jakiego to poziomu? Polecałbym wrzucić to na jakies forum informatyczne tutaj mozesz dosyć długo czekać za odpowiedzia. Ale jest tutaj tez kilka osob ogarnietych w kodowaniu emotka
29 lis 17:16
Filip: 1 rok studiow
29 lis 17:18
Pytający: > Ja narazie tylko zaprojektowalem struktury, czy tak to bedzie wygladac? Może tak to wyglądać. Ewentualnie można by tablice na imię i nazwisko alokować dynamicznie, ale dla uproszczenia tak jak napisałeś też powinno być ok. Na pewno zmieniłbym nazwę pola o, niezbyt wiele ona mówi. Pole next też dziwnie wygląda na tle pozostałych, polskich nazw. Co do funkcji: jakiś pomysł / próba / pytania? Czy oczekujesz gotowca?
29 lis 18:26
Filip: Co do funkcji, napisalem cos takiego: Cialo funkcji: struct marknode* m = s−>marks; while (m−>next != NULL) { m = m−>next; } struct marknode* el = malloc(sizeof*el); el−>mark = o; el−>next = NULL; m−>next = el;
29 lis 18:52
Filip: no i dostaje komunikat Core dumped, chyba powinnenem sprawdzac jeszcze, co w przypadku gdy lista ocen jest puta?
29 lis 18:53
Filip: Ok, juz mam, finalnie cialo funkcji wyglada tak: struct marknode* m = s−>marks; struct marknode* new = malloc(sizeof(*new)); new−>mark = o; new−>next = NULL; if (m == NULL) { s−>marks = new; } else { while (m−>next != NULL) { m = m−>next; } m−>next = new; }
29 lis 19:02
Pytający: Ok. Chyba że musisz sprawdzać, czy malloc faktycznie pomyślnie zaalokował pamięć (dla uproszczenia pewnie nie musisz). Jeśli jednak musisz to coś w tym stylu: struct mark_node* new = malloc(sizeof(*new)); if (new == NULL) { perror("malloc"); return; } powinno załatwić sprawę.
29 lis 19:25
Filip: Najprawdopodobniej bede to robil podczas rozwiazywania ukladu rownan metoda eliminacji Gaussa, takze jakos jutro wstawie zadania i/lub kod ktory udalo mi sie napisac
29 lis 22:15
Mariusz: Co do układów równań to jakiś czas temu poprawiłem pseudokod rozkładu LU który znalazłem na ważniaku i zmodyfikowałem go tak aby rozwiązywał układy równań metodą eliminacji Gaußa Jak chcesz zobaczyć ten kod to mogę go przesłać Artykuł na ważniaku http://wazniak.mimuw.edu.pl/index.php?title=MN05 Ciekawy jestem czy znajdziesz błędy Matematycy przedstawiają eliminację Gaußa czy rozkład LU w sposób który jest nieprzydatny programiście Mnożą przez macierze odwrotne do macierzy operacji elementarnych co jest niepotrzebne programiście
30 lis 14:18
Filip: Narazie mam sam problem ze zrozumieniem jak za pomoca operacji dzielenia oraz odejmowania przejsc do macierzy gornej trojkatnej
30 lis 14:27
Filip: Zakladajac ze mam taki uklad rownan: a11x1 + a{12}x2 + ... = r1 a21x1 + a{22}x2 + ... = r2 Itd... I bede zerowac po kolei kolumnami wiec musze wyzerowac wspolczynnik a21 To robie to tak:
 a21 
rownanie2 = rownanie2 − rownanie1 *

 a11 
 a31 
rownanie3 = rownanie3 − rownanie1 *

 a11 
itd...
30 lis 14:36
Filip: Patrzac ogolnie, to chyba napisalem przejscie do macierzy gornej trojkatnej. Aby to zrozumiec musze pokazac troche kodu. Uklad rownanie reprezentuje w strukturze: struct ur { double* a; // macierz n x n double* r; //wektor wyrazow wolnych int n; //ilosc rownan i niewiadomych }* urt No i moj fragment gdzie to zeruje wyglada tak: int n = ur−>n double* a = ur−>a; double* r = ur−>r; for (int k = 0; k < n − 1; k++) { for (int w = k + 1; w < n; w++) { double wsp = *(a + w * n + k) / *(a + k * n + k) for (int j = k; j < n; j++) { *(a + w * n + j) −= *(a + k * n + j) * wsp } *(r + w) −= *(r + k) * wsp } }
30 lis 15:04
Mariusz: Zanim przejdziesz do eliminacji to wybierz w kolumnie element największy co do modułu i zamień wiersze jeśli ten element nie znajduje się na głównej przekątnej A spróbuj najpierw wyzerować elementy pierwszej kolumny poniżej głównej przekątnej Jeśli ci się to uda to później wystarczy tylko jedna pętla
30 lis 15:06
Mariusz: Ja napisałem coś takiego #include<stdio.h> #include<stdlib.h> #include<math.h> #include<conio.h> void gauss(double** Ab,int n,double *d) { int i,j,k,p; double temp,s; (*d) = 1.0; for( k = 0; k < n; k++) { p = k; for( j = k; j < n; j++) if( fabs(Ab[j][k]) > fabs(Ab[p][k]) ) p = j; for( j = 0; j <= n; j++) { temp = Ab[k][j]; Ab[k][j] = Ab[p][j]; Ab[p][j] = temp; } if(p != k) (*d) = −(*d); (*d) *= Ab[k][k]; if(Ab[k][k] == 0.0) return ; for( j = k + 1; j< n; j++) { s = (double)(Ab[j][k]/Ab[k][k]); for( i = k + 1; i <= n; i++ ) Ab[j][i] −= s * Ab[k][i]; } } } void backsub(double** Ab,int n) { int i,j; double sum; for(i = n − 1; i >=0 ;i−−) { sum = 0.0; for(j = i + 1; j < n;j++) sum += Ab[i][j]*Ab[j][n]; Ab[i][n] = (double)((Ab[i][n]−sum)/Ab[i][i]); } } int main() { int i,j,n; double d; double **A; char esc; do { printf("Rozwiazywanie ukladow rownan liniowych metoda eliminacji Gaussa\n"); printf("Podaj liczbe rownan \n"); scanf("%d",&n); A = (double**)malloc((n )*sizeof(double*)); for(i = 0;i < n;i++) A[i] = (double*)malloc((n+1)*sizeof(double)); for(i = 0;i < n; i++) { for(j = 0;j < n;j++) { printf("A[%d][%d]=",i,j); scanf("%lf",&A[i][j]); } printf("B[%d]=",i); scanf("%lf",&A[i][n]); } gauss(A,n,&d); for(i=0;i<n;i++) { for(j = 0;j<=n;j++) { printf("%lf ",A[i][j]); } printf("\n"); } if(d != 0) { backsub(A,n); for(i = 0;i < n;i++) printf("X[%d]=%.12lf\n",i,A[i][n]); } for(i = 0;i < n;i++) free(A[i]); free(A); esc = getch(); } while(esc != 27); }
30 lis 15:23
Filip: Wlasnie czy ty brales ten algorytm eliminacji Gaussa z tego linku, co podeslales powyzej? Jest tam kilka bledow, chociazby to, ze zewnetrzna petla wykonuje sie od k = 1 do N − 1 a powinna sie wykonywac do N
30 lis 15:27
Mariusz: Wziąłem ten algorytm z ich strony ale zauważone błędy poprawiłem Próbowałem do nich napisać na marudę aby zwrócić im uwagę na występujące u nich błędy ale nie reagują
30 lis 15:41
Mariusz: Jeśli nie chcesz ograniczać się do układów Cramera to poszukaj kodu programu sprowadzającego macierz do postaci schodkowej zredukowanej np rref.c Przykładowy kod widziałem na rosetta code
30 lis 15:51
Filip: Mariusz, masz ochote pomoc w jeszcze jedynm zadaniu (dosc trywialnym) jednak mam problem z zapisaniem tego w kodzie. Tresc zadania: Prosze napisac funkcje, ktora jako srgument przyjume vektor v1 typu int oraz jego dlugosc, oraz vektor v2 typu int i jego dlugosc. Funkcja ma sprawdzac, czy w wektorze v1 zawarty jest wektor v2. Jesli tak, ma zwracac indeks pierwszego elementu v2 w wektorze v1. W innym przypadku program na zwracac −1
30 lis 17:48
Mariusz: Szukałeś coś o wyszukiwaniu wzorca ? Twoje zadanie wydaje się dość podobne
30 lis 17:54
Filip: Podszedlem do tego "na jerza", cialo funkcji wyglada tak: if (nv2 > nv1) return −1; for (int i = 0; i < nv1; i++) { int counter = 1; if (ve1[i] == v2[0]) { int k = 1; for (int j = i + 1; j < nv2 + i + 1; j++) { if (v1[j] == v2[k++]) counter++; } if (counter == nv2) return i; } return −1; Nie jest to moze optymalny sposob, ale wyglada na to ze dzialajacy poprawnie
30 lis 18:24
Mariusz: Ja też napisałem ten program w sposób nieoptymalny #include<stdio.h> #include<stdlib.h> #include<conio.h> int znajdzWzorzec(int *v1,int n, int *v2,int m) { int i,j; int znaleziono,pasuje; // W C nie ma typu logicznego if(m > n) return −1; i = 0; znaleziono = 0; while(i < n && !znaleziono) { pasuje = 1; j = 0; while(j < m&& pasuje) { if(v1[i + j] != v2[j]) pasuje = 0; else j++; } if(pasuje) znaleziono = 1; else i++; } if(znaleziono) return i; else return −1; } int main() { char esc; int i,n,m; int *v1; int *v2; do { printf("Podaj dlugosc wektora 1 \n"); scanf("%d",&n); printf("Podaj dlugosc wektora 2 \n"); scanf("%d",&m); v1 = (int *)malloc(n*sizeof(int)); v2 = (int *)malloc(m*sizeof(int)); for(i=0;i<n;i++) { printf("v1[%d]=",i); scanf("%d",&v1[i]); } for(i=0;i<m;i++) { printf("v2[%d]=",i); scanf("%d",&v2[i]); } printf("%d\n",znajdzWzorzec(v1,n,v2,m));; esc = getch(); } while(esc != 27); } Może gdybyś poczytał o wyszukiwaniu wzorca udałoby ci się wymyślić lepszy algorytm
30 lis 18:50
Mariusz: A jeśli chodzi o układy równań liniowych to z Gaußem łączona jest także iteracyjna metoda rozwiązywania tych równań
1 gru 03:09