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
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:
a
11x
1 + a{12}x
2 + ... = r
1
a
21x
1 + a{22}x
2 + ... = r
2
Itd... I bede zerowac po kolei kolumnami
wiec musze wyzerowac wspolczynnik a
21
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