• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem z programem c

VPS Starter Arubacloud
0 głosów
263 wizyt
pytanie zadane 30 grudnia 2017 w C i C++ przez kikosiak Obywatel (1,010 p.)

Witam !

Mam problem z wykonaniem programu ogólnie ma on za zadanie lączyć punkty od dołu do góry bądź od lewej do prawej (w kodzie na razie jest koncepcja jak to zrobić od dolu do góry) z tym, że program nie działa tak jak powinien. Mój zamysł był taki żeby znaleźć punkt który jest najniżej a poźniej szukać kolejne coraz wyżej (chyba można to zauważyć w kodzie). Czy mógłby ktoś wyjaśnić mi gdzie zrobiłem błąd?

#include <stdio.h>
#include <stdlib.h>
typedef double Tpoint[2];
typedef Tpoint Tpoints[];
typedef int Troad[];

void FindRoad(int n,Tpoints punkty,Troad results);

int main()
{
    int n=10;
    Tpoints punkty = {{7,2},{3,13},{11,4},{14,8},{5,10},{0,9},{6,16},{14,1},{3,17},{7,8}};
    Troad results={1,1,1,1,1,1,1,1,1,1};
          FindRoad(n,punkty,results);




    return 0;
}
void FindRoad(int n,Tpoints punkty,Troad results)
{   int i,licznik=0;
    double xmax=punkty[0][0],ymax=punkty[0][1];
    double miny=punkty[0][1],maxy[0][1];
    double roznica=10.0;
    double roznicamin=99.0;
    double h;
    int licznik1=1;
    for(i=0;i<n;i++)
    {
        printf("TO JEST I %d\n",i);
      if(punkty[i][0]>xmax)
            xmax=punkty[i][0];

        if(punkty[i][1]>xmax)
            ymax=punkty[i][1];

            if(punkty[i][1]<miny)
               {miny=punkty[i][1];
               results[0]=i;
                    }

    }

        if(xmax<ymax)//TO LEĆ PO Y
        {







double miny1=miny;

             int k;
            for(k=0; k<n;k++)
    {       printf("TO JEST K %d\n",k);


            int j;
            for(j=miny;j<=ymax;j++)
{   printf("TO JEST J %d\n",j);

    if(punkty[licznik][1]==miny)
    {
        int m;
        for(m=0;m<ymax;m++)
            if(punkty[m][1]==licznik)
        {//printf("TO JEST licznik %d a to m%d\n",licznik,m);
            results[licznik1]=m;
            licznik1++;
        }



    }
    licznik++;
    miny++;
}
printf("miny%lf,miny1:%lf",miny,miny1);
miny1++;
licznik=0;
miny=miny1;
        }



int z;
for(z=0;z<n;z++)
{
    printf("\n%d",results[z]);
}

}
}

 

2 odpowiedzi

0 głosów
odpowiedź 30 grudnia 2017 przez mokrowski Mędrzec (155,460 p.)
wybrane 2 stycznia 2018 przez kikosiak
 
Najlepsza

W kodzie masz błąd (IMHO) koncepcyjny. Radził bym zamiast takich karkołomnych aliasów na typ (typedef na tablicę), zrobić strukturę z elementami x i y. Choćby taką:

typedef struct {
    double x;
    double y;
} Tpoint;

Bardzo polepszy to czytelność kodu bo będziesz wyrażał to co się dzieje w kodzie a nie jakieś przesunięcia o 0 czy 1.

Zakładam jednak "że kazali" :-/ Więc nie będę polemizował.

Drugim problemem który tu widzę, to brak wydzielonych funkcji jasno pokazujących poprzez swoją nazwę co się dzieje w kodzie.

Trzeci problem to pomieszanie nazw angielskich z polskimi. Trochę boli od tego głowa :-/

Jeśli chcesz posortować dane, lepiej to wyrazić bezpośrednio. Np. tak:

#include <stdio.h>
#include <stdlib.h>

typedef double Tpoint[2];
typedef Tpoint Tpoints[];

int cmp_x(const void * v1, const void * v2) {
    Tpoint *arg1 = (Tpoint*) v1;
    Tpoint *arg2 = (Tpoint*) v2;
    if((*arg1)[0] < (*arg2)[0]) {
        return -1;
    } else if((*arg1)[0] == (*arg2)[0]) {
        return 0;
    }
    return 1;
}

int cmp_y(const void * v1, const void * v2) {
    Tpoint * arg1 = (Tpoint*) v1;
    Tpoint * arg2 = (Tpoint*) v2;
    if((*arg1)[1] < (*arg2)[1]) {
        return -1;
    } else if(arg1[1] == arg2[1]) {
        return 0;
    }
    return 1;
}

void show_points(const Tpoints points, size_t size) {
    for(size_t i = 0; i < size; ++i) {
        printf("x = %5.2f y = %5.2f\n", points[i][0], points[i][1]);
    }
}

int main(void) {
    Tpoints points = {{7,2}, {3,13}, {11,4}, {14,8}, {5,10}, {0,9},
        {6,16}, {14,1}, {3,17}, {7,8}};
    const size_t points_len = sizeof(points) / sizeof(*points);

    puts("Pierwotne:");
    show_points(points, points_len);
    puts("Posortowane względem x:");
    qsort(&points, points_len, sizeof(*points), cmp_x);
    show_points(points, points_len);
    puts("Posortowane względem y:");
    qsort(&points, points_len, sizeof(*points), cmp_y);
    show_points(points, points_len);

    return EXIT_SUCCESS;
}

Napisałem to trochę szkolnie abyś zobaczył o co chodzi z funkcją porównującą.

komentarz 2 stycznia 2018 przez kikosiak Obywatel (1,010 p.)
Dzięki za odpowiedź, ale mam jeszcze parę pytań. Co oznacza taki kod (Tpoint*) v1?, Czemu funkcjom cmp_x,cmp_y nie trzeba dawać argumentów? I ostatnie czy jeśli bym chciał dostać wynik w postaci numerów punktów z pierwotnej tablicy. Chodzi mi już o następną tablicę u mnie w kodzie jest Troad. Czyli wynik dla tych punktów powinnien wychodzić taki :7,0,2,3,9,5,4,1,6,8. Acha jeszcze zdziwniło mnie że w qsort podałeś cmp_x, gdybyś mógł mi powiedzieć dlaczego?
komentarz 2 stycznia 2018 przez mokrowski Mędrzec (155,460 p.)

Co oznacza taki kod (Tpoint*) v1?

To jest rzutowanie z typu void * który przyjmuje funkcja cmp_x, na typ docelowy "wskaźnik na Tpoint" . Algorytm qsort(...) przyjmuje argumenty poprzez wskaźniki. To funkcja porównująca (czyli cmp_x(...) oraz cmp_y(...) ) ma wiedzieć jak traktować te argumenty a więc jakich są typów. W dużym skrócie qsort(...) informujesz na jakich danych ma pracować (a pracuje wyłącznie na wskaźnikach), z jakim przesunięciem adresów, ile ma być danych a sama funkcja qsort(...) pyta o wynik funkcje porównujące (czyli cmp_x/cmp_y).

Czemu funkcjom cmp_x,cmp_y nie trzeba dawać argumentów?

Funkcjom tym argumenty podaje qsort(...).

Acha jeszcze zdziwniło mnie że w qsort podałeś cmp_x, gdybyś mógł mi powiedzieć dlaczego?

Jeśli chcesz sortować względem x'a, używasz cmp_x. Jeśli względem y'reka, stosujesz cmp_y. Jak będziesz chciał sortować względem jakiegoś innego kryterium, napiszesz swoją własną funkcję wartościującą :-)

Czyli wynik dla tych punktów powinnien wychodzić taki :7,0,2,3,9,5,4,1,6,8

Bardzo prostym rozwiązaniem będzie wprowadzenie struktury ze współrzędnymi x i y oraz numerem punktu. Oczywiście można to rozwiązać także na inne sposoby. Zobacz jednak czy czytając kod tu umieszczony, rozumiesz co się dzieje :-) Dodałem sortowanie względem odległości od punktu [0, 0]:

#include <stdio.h>
#include <stdlib.h>
 
typedef struct {
	double x;
	double y;
	unsigned number;
} Tpoint;
 
int cmp_x(const void * v1, const void * v2) {
    Tpoint *arg1 = (Tpoint *) v1;
    Tpoint *arg2 = (Tpoint *) v2;
    if(arg1->x < arg2->x) {
        return -1;
    } else if(arg1->x == arg2->x) {
        return 0;
    }
    return 1;
}
 
int cmp_y(const void * v1, const void * v2) {
    Tpoint * arg1 = (Tpoint *) v1;
    Tpoint * arg2 = (Tpoint *) v2;
    if(arg1->y < arg2->y) {
        return -1;
    } else if(arg1->y == arg2->y) {
        return 0;
    }
    return 1;
}

int cmp_0_0_distance(const void * v1, const void * v2) {
	Tpoint * arg1 = (Tpoint *) v1;
	Tpoint * arg2 = (Tpoint *) v2;
	// Nie opłaca się wyciągać pierwiastka z odległości kartezjańskiej
	// bo porównanie kwadratów wystarczy.
	double distance1_2 = (arg1->x * arg1->x) + (arg1->y * arg1->y);	
	double distance2_2 = (arg2->x * arg2->x) + (arg2->y * arg2->y);	
	if(distance1_2 < distance2_2) {
		return -1;	
	} else if(distance1_2 == distance2_2) {
		return 0;
	}
	return 1;
}
 
void show_points(const Tpoint * points, size_t size) {
    for(size_t i = 0; i < size; ++i) {
        printf("num = %u x = %5.2f y = %5.2f\n",
			points[i].number, points[i].x, points[i].y);
    }
}
 
int main(void) {
    Tpoint points[] = {{7, 2, 0}, {3, 13, 1}, {11, 4, 2}, {14, 8, 3},
		{5, 10, 4}, {0, 9, 5}, {6, 16, 6}, {14, 1, 7}, {3, 17, 8},
		{7, 8, 9}};
    const size_t points_len = sizeof(points) / sizeof(*points);
 
    puts("Pierwotne:");
    show_points(points, points_len);
    puts("Posortowane względem x:");
    qsort(&points, points_len, sizeof(*points), cmp_x);
    show_points(points, points_len);
    puts("Posortowane względem y:");
    qsort(&points, points_len, sizeof(*points), cmp_y);
    show_points(points, points_len);
    puts("Posortowane względem odległości od [0, 0]:");
    qsort(&points, points_len, sizeof(*points), cmp_0_0_distance);
    show_points(points, points_len);
 
    return EXIT_SUCCESS;
}

 

komentarz 2 stycznia 2018 przez kikosiak Obywatel (1,010 p.)
Też pomyślałem żeby tak to zrobić ale tablica musi byc 2wymiarowa ponieważ tak jest wymagane w zadaniu a ten algorytm bedzie zaimplementowany w bibliotece dll.

Nie ma mowy o strukturze w zadaniu a wymaganiem jest mieć takie coś:

typedef double Tpoint[2];

typedef Tpoint Tpoints[];

typedef int Troad[];
komentarz 2 stycznia 2018 przez mokrowski Mędrzec (155,460 p.)
No to nic nie poradzę. "Kazali to kazali" :-/ No to wrócisz do poprzedniego przykładu który napisałem :-)

Dość że napisanie tego na strukturach nie jest problemem dla umieszczenia algorytmu w *.dll. Jedynie być może wymagania zewnętrzne każą Ci zrobić to na aliasach do typów tablicowych.
komentarz 2 stycznia 2018 przez kikosiak Obywatel (1,010 p.)
Ok, w każdym razie dziękuję za pomoc.
0 głosów
odpowiedź 30 grudnia 2017 przez obl Maniak (51,280 p.)

Nie wiem, czy rozumiem poprawnie to co chcesz zrobić. Jest sobie zbiór punktów, który chcesz (jeżeli dobrze rozumiem) połączyć tak, że najniżej (czyli mający najniższą wartość współczynnika y) łączył się kolejno z coraz wyżej położonymi elementami? Jeżeli tak i to jest to zwykły problem związany z sortowaniem tych punktów. Posortowane punkty względem y-ka będą stanowiły graf połączeń poprzez kolejność ich ułożenia w tablicy.

komentarz 30 grudnia 2017 przez kikosiak Obywatel (1,010 p.)
ok, można posortować punkty względem y tylko mała zagwozdka jak poźniej podać "numery" punktów do tablicy results?
komentarz 31 grudnia 2017 przez obl Maniak (51,280 p.)
W takim przypadku kolejność ułożenia puntów w tablicy już posortowanej będzie twoim rezultatem.

Podobne pytania

0 głosów
2 odpowiedzi 174 wizyt
pytanie zadane 30 listopada 2017 w C i C++ przez parogracz Początkujący (360 p.)
0 głosów
0 odpowiedzi 502 wizyt
0 głosów
1 odpowiedź 247 wizyt
pytanie zadane 4 listopada 2017 w C i C++ przez chucksqll Stary wyjadacz (12,930 p.)

92,452 zapytań

141,262 odpowiedzi

319,079 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...