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

Sortowanie wierszy według jednego stringa opisującego dzień tygodnia w C++

0 głosów
114 wizyt
pytanie zadane 17 stycznia w C i C++ przez Fizek78 Nowicjusz (170 p.)

Witam, tworząc projekt na zajęcia z programowania trafiłem na problem, którego nie potrafię przejść.
Mam plik tekstowy, w którym znajdują się takie informacje:
07:23-19:34 cz gr1 Astronomia
10:15-11:45 wt gr2 Fizyka

Muszę teraz posortować dane w tym pliku w taki sposób, by linia w której znajduję się "wt" była nad "cz", czyli inaczej mówiąc po prostu chronologicznie wg. dnia tygodnia. Oczywiście takich linijek może być dużo więcej i dni tygodnia zapisywane są : "pn,wt,sr,cz,pt,sb,nd" a jeżeli pojawią się zajęcia, które są w tym samym dniu to muszą być posortowane wg. godziny w której mają miejsce.Mój kod źródłowy na tym etapie wygląda tak:

#include <iostream>
#include <string>
#include <cstdlib>
#include <fstream>
#include <sstream>
using namespace std;
struct dane                  //struktura z danymi i wskaznikiem na nastepny element
{
    string godzina;
    string dzien;
    string grupa;
    string nazwisko;
    string przedmiot;
    dane *nast;
};
typedef dane* lista;
lista glowa = NULL;
lista wsk = NULL;
void dodawanie(lista &glowa, string godzina, string dzien, string grupa, string nazwisko, string przedmiot) // dodawanie nowego elementu do listy
{
    glowa = new dane;
    glowa->godzina = godzina;
    glowa->dzien = dzien;
    glowa->grupa = grupa;
    glowa->nazwisko = nazwisko;
    glowa->przedmiot = przedmiot;

    glowa->nast = wsk;
    wsk = glowa;

};
void zapisz(lista glowa)//zapisywanie listy do osobnego pliku
{

    lista kolejny;
    kolejny = glowa;
    while (kolejny != NULL)
    {
        fstream plik_wyjsciowy;
        plik_wyjsciowy.open(kolejny->nazwisko + ".txt", ios::out | ios::app);
        plik_wyjsciowy << kolejny->godzina << " ";
        plik_wyjsciowy << kolejny->dzien << " ";
        plik_wyjsciowy << kolejny->grupa << " ";
        plik_wyjsciowy << kolejny->przedmiot << endl;
        kolejny = kolejny->nast;
    }
    cout << "\n";
};

int main()
{
    fstream plik;
    string sciezka;
    cout << "Wpisz nazwe/sciezke do pliku zawierajcego dane:";
    cin >> sciezka;
    plik.open(sciezka);
    if (plik.is_open())
    {
        string wers;
        string godzina, dzien, grupa, nazwisko, przedmiot;
        cout << "Plik wczytano poprawnie!" << endl;
        int liczby;
        string a, b;
        while (!plik.eof())
        {

            getline(plik, wers);
            istringstream is(wers);   //dzielenie wersu  na czesci
            is >> godzina >> dzien >> grupa >> nazwisko >> przedmiot;

            dodawanie(glowa, godzina, dzien, grupa, nazwisko, przedmiot);  //dodanie pobranych danych z pliku do listy

        }
    }
    else
    {
        cout << "Plik nie zostal wczytany, sprobuj ponownie" << endl;
    }

    zapisz(glowa);
    return 0;
}

Widziałem już podobny temat na innym forum, chłopak chyba miał ten sam temat projektu co ja tylko inaczej wtedy wyglądał. Ja muszę stworzyć pliki dla każdego osobnego wykładowcy i do tych plików z jego nazwiskiem umieścić jego zajęcia, a zajęcia mają być posortowane chronologicznie. Z tego co widziałem jemu się to nie udało. Muszę nadmienić, że w warunkach projektu zakazane jest używanie publicznych kontenerów typu vector, czy list.

komentarz 17 stycznia przez MikDal Mądrala (5,160 p.)
I w czym dokładnie można Ci pomóc?

4 odpowiedzi

0 głosów
odpowiedź 17 stycznia przez RafalS VIP (110,660 p.)
wybrane 19 stycznia przez Fizek78
 
Najlepsza
Jesli nie musisz to nie męcz się z sortowaniem listy. Przeczytaj plik 2 razy. Za pierwszym razem policz linijki. Stworz odpowiednio długą tablice i wczytaj wszystko do tablicy.
0 głosów
odpowiedź 17 stycznia przez Raptor Mądrala (5,750 p.)
edycja 17 stycznia przez Raptor

Hmm ja bym to zrobił tak:

Wczytywał bym po kolei każda linijkę pliku i dzielił te stringi na tablice , a dzielnikiem byłaby spacja.
Potem stworzyłbym tablice, w które będą do odpowiedniego klucza np "wt" przypisywać się zajęcia z tego właśnie dnia.

Na końcu wypisujesz wszystko w  jakiej chcesz kolejności.

A tutaj kod mojego rozwiązania:

<?php

$sortby = Array('pn', 'wt', 'sr', 'cz', 'pt');

$zajecia = Array(
    "07:23-10:34 pn gr1 Mandaryński",
    "08:23-12:34 cz gr1 Bułgarski",
    "07:23-13:34 cz gr1 Astronomia",
    "07:23-13:34 sr gr1 Matematyka",
    "10:15-11:45 wt gr2 Fizyka",
    "08:15-09:45 pt gr2 Polski",
    "11:15-13:45 pt gr1 Angielski"
    );
    
    $arr = [];
    foreach($zajecia as $value){
        $tmp = explode(' ', $value); 
        $arr[$tmp[1]][] = $value;
    }
    
    foreach($sortby as $day){
        if(array_key_exists($day, $arr)){ // sprawdza czy dany dzień występuje w tablicy
            for($i=0;$i<count($arr[$day]);$i++){
                echo $arr[$day][$i]."\n";
            } 
        }
    }

Niestety w php bo c++ nie znam na tyle, musiałbyś sobie przepisać pod swój jezyk :)

0 głosów
odpowiedź 17 stycznia przez j23 VIP (103,060 p.)

Możesz użyć np. takiej funkcji do porównywania:

int compare_by_day(const dane &d1, const dane &d2)
{
	const char* days = "pn,wt,sr,cz,pt,sb,nd";
	return strstr(days, d1.dzien.c_str()) - strstr(days, d2.dzien.c_str());
}

i przed wstawieniem do listy szukaj ostatniego elementu mniejszego (<0) od wstawianego elementu.

0 głosów
odpowiedź 17 stycznia przez mokrowski VIP (105,020 p.)
edycja 17 stycznia przez mokrowski

Masz tu prościutki, prymitywny vector dla wartości int. Resztę już bez problemu zrobisz:

#include <iostream>
#include <cstdlib>
#include <cassert>

class Vector {
	Vector(const Vector&);
	Vector& operator=(const Vector&);
public:
	Vector(std::size_t size_): size(size_), capacity(size_) {
		assert(size > 0);
		data = static_cast<int *>(malloc(size * sizeof(int)));
		assert(data != NULL);
	}
	~Vector() {
		free(data);
	}
	void push_back(int value) {
		if(size == capacity) {
			int * ptr = static_cast<int *>(realloc(data, sizeof(int) * size * 2));
			assert(ptr != NULL);
			capacity = size * 2;
			data = ptr;
		}
		data[size++] = value;
	}
	int operator[](std::size_t index) const {
		assert(index < size);
		return data[index];
	}
	int& operator[](std::size_t index) {
		assert(index < size);
		return data[index];
	}
	std::size_t size;
	std::size_t capacity;
	int * data;
};

void fill_vector(Vector& vec) {
	assert(vec.size > 0);
	for(std::size_t i = 0U; i < vec.size; ++i) {
		vec[i] = 42;
	}
}

void show_vector(const Vector& vec) {
	std::cout << "Vector size: " << vec.size
		<< ", capacity: " << vec.capacity << ", data: " << vec.data << ". values: ";
	for(std::size_t i = 0U; i < vec.size; ++i) {
		std::cout << vec[i] << ' ';
	}
	std::cout << '\n';
}

int main() {
	Vector vec(10);
	fill_vector(vec);
	std::cout << "Before push_back(...)\n";
	show_vector(vec);
	vec.push_back(100);
	std::cout << "After push_back(...)\n";
	show_vector(vec);
}

Nie robiłem metod dostępowych bo miał być "na szybko" :)

Podobne pytania

0 głosów
1 odpowiedź 68 wizyt
0 głosów
3 odpowiedzi 90 wizyt
pytanie zadane 17 grudnia 2018 w Java przez andrut Użytkownik (870 p.)
0 głosów
2 odpowiedzi 84 wizyt
pytanie zadane 11 czerwca 2018 w PHP, Symfony, Zend przez michau0709 Początkujący (490 p.)
Porady nie od parady
Odznacz odpowiedź zieloną fajką, jeśli uważasz, że jest ona najlepsza ze wszystkich i umożliwiła ci rozwiązanie problemu.Najlepsza odpowiedź

64,048 zapytań

110,437 odpowiedzi

231,288 komentarzy

47,817 pasjonatów

Przeglądających: 192
Pasjonatów: 6 Gości: 186

Motyw:

Akcja Pajacyk

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

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...