• 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++

Object Storage Arubacloud
0 głosów
591 wizyt
pytanie zadane 17 stycznia 2019 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 2019 przez MikDal Mądrala (5,660 p.)
I w czym dokładnie można Ci pomóc?

4 odpowiedzi

0 głosów
odpowiedź 17 stycznia 2019 przez RafalS VIP (122,820 p.)
wybrane 19 stycznia 2019 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 2019 przez niezalogowany
edycja 17 stycznia 2019

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 2019 przez j23 Mędrzec (194,920 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 2019 przez mokrowski Mędrzec (155,460 p.)
edycja 17 stycznia 2019 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ź 519 wizyt
pytanie zadane 4 maja 2020 w Python przez TeaCup Obywatel (1,370 p.)
0 głosów
0 odpowiedzi 233 wizyt
0 głosów
3 odpowiedzi 369 wizyt
pytanie zadane 17 grudnia 2018 w Java przez andrut Użytkownik (870 p.)

92,536 zapytań

141,376 odpowiedzi

319,452 komentarzy

61,920 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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy 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!

...