sumowanie strukturalne

0

Zbieramy dane w postaci tablic, których elementy mają postać:

struct TCnt { int id_obiektu, licznik; }

każda taka tablica (inputowa) jest dodatkowo opatrzona grupą i typem:
int grupa, typ;

razem wygląda to tak:

struct Tab {
 int grupa, typ;
 int cnt; // liczba elementów
 TCnt t[1]; // faktycznie cnt sztuk
};

I takich tablic może być dowolnie dużo, całkiem bez kozery 1000;
każda ma od kilku do kilkuset elementów.

Należy szybko posumować te tablice ale oddzielnie dla każdej z grup,
i z uwzględnieniem typów, znaczy wyniki trzymamy w tablicach o innych elementach:

struct TFCnt { int id_obiektu, typ, licznik; }

wyniki zapisujemy do tablic typu:

struct TGrupa {
int grupa;
int cnt;
TFCnt t[1];
};

Typów jest tylko do 250 (bajt), a obiektów mogą być grube tysiące (int), grup mamy znowu setki.
Razem będzie tego dość dużo.

Można to jakoś sprawnie zrobić - haszem albo drzewem?

1

Oczywiście że można.
Po pierwsze struktura jest zła. Wyrzuciłbym grupę ze struktury i zrobił mapę która mapuje grupę na listę struktur Tab.
Jeśli sumowanie dla każdej z grup odbywa się po typie to znów możemy wyciągnąć z tego mapę której kluczem jest typ, tak że w strukturze Tab zostanie nam już tylko faktyczna tablica z danymi.

0
Shalom napisał(a):

Oczywiście że można.
Po pierwsze struktura jest zła. Wyrzuciłbym grupę ze struktury i zrobił mapę która mapuje grupę na listę struktur Tab.
Jeśli sumowanie dla każdej z grup odbywa się po typie to znów możemy wyciągnąć z tego mapę której kluczem jest typ, tak że w strukturze Tab zostanie nam już tylko faktyczna tablica z danymi.

Struktura jest zadana
na wejściu mamy te pierwsze tablice i należy to policzyć z rozbiciem na grupy.

Sumowanie odbywa się po: obiekt x typ, czyli te dwa razem są identyfikatorem - kluczem.

Tu liczymy jakieś przedmioty, np. samochody:
id_obiektu to marka, a typ to np. kolor,
wtedy grupa może być regionem - państwo, czy coś tam.

Albo liczymy posiadane przedmioty przez ludność - rodziny: pralki, lodówki, trampki, skutery śnieżne, itd.
To byłby obiekty, a typy wówczas mogłyby określać jakieś cechy posiadaczy albo i samych przedmiotów, które liczymy.

A grupy mogłyby oznaczać zawód posiadacza: młynarz, hurtownik, rolnik, policjant, księgowy.

0

Wszystkie TCnt skopiuj do osobnego kontenera jako TFCnt (dodaj typ). Posortuj strukturę ze względu na typ oraz ID złączając jednocześnie powtórzenia (sumując licznik).Nie! Przepraszam, nie doczytałem.

Dla każdej grupy z osobna, wszystkie TCnt danej grupy skopiuj do osobnego kontenera jako TFCnt (dodaj typ). Posortuj strukturę ze względu na typ oraz ID złączając jednocześnie powtórzenia (sumując licznik).

0
adf88 napisał(a):

Dla każdej grupy z osobna, wszystkie TCnt danej grupy skopiuj do osobnego kontenera jako TFCnt (dodaj typ). Posortuj strukturę ze względu na typ oraz ID złączając jednocześnie powtórzenia (sumując licznik).

Chyba powiedziałeś co należy zrobić, ale nie jak.

Sortować i scalać?
Dwóch takich samych kluczy chyba nie można dodać, a jeśli nawet to po co?

0
Lisa napisał(a):

Chyba powiedziałeś co należy zrobić, ale nie jak.
Powiedziałem jak, ale bez szczegółów. Chyba umiesz sortować? Dobór odpowiedniej metody pozostawiam tobie bo to ty znasz charakterystykę danych.

Lisa napisał(a):

Dwóch takich samych kluczy chyba nie można dodać, a jeśli nawet to po co?
([ID:porsche, TYP:zielone], LICZNIK:10) + ([ID:porsche, TYP:zielone], LICZNIK:15) -> ([ID:porsche, TYP:zielone], LICZNIK:25)

0
adf88 napisał(a):

Powiedziałem jak, ale bez szczegółów. Chyba umiesz sortować? Dobór odpowiedniej metody pozostawiam tobie bo to ty znasz charakterystykę danych.

Co chcesz sortować - tablicę wynikową?
Najpierw trzeba ją mieć.

Lisa napisał(a):

Dwóch takich samych kluczy chyba nie można dodać, a jeśli nawet to po co?
([ID:porsche, TYP:zielone], LICZNIK:10) + ([ID:porsche, TYP:zielone], LICZNIK:15) -> ([ID:porsche, TYP:zielone], LICZNIK:25)</quote>

To jest oczywiste.

Chodzi o metodę - szybką, czyli bez zbędnych czasochłonnych operacji, które sugerujesz.
Samo scalanie jest zbyteczne - trzeba od razu to sumować.

szukamy key:
brak -> dodajemy nowy klucz razem z licznikiem;
jest -> zwiększamy tylko licznik

0
Lisa napisał(a):

Chodzi o metodę - szybką, czyli bez zbędnych czasochłonnych operacji, które sugerujesz.
A jakie są te zbędne czasochłonne operacje, które sugeruje?

Nie pisałem kiedy scalać a kiedy sortować. Można to robić od razu podczas wstawiania, ale nie koniecznie. Zależy...

... Nie napisałaś nic więcej o tych danych. Ile będzie grup, ile typów, ile id, czy rozkładają się równomiernie? Decyzję nt. konkretnej metody trzeba podjąć na podstawie charakterystyki danych.

0

Średnio licząc:
250 typów x 10 000 obiektów x 1000 grup = 2.5 miliarda

ale w praktyce nigdy aż tyle nie będzie, ponieważ jeden obiekt ma zwykle jeden typ, sporadycznie dwa lub kilka.

Liczba grup jest znana, więc można się ograniczyć do jednej grupy.
Za to ilość tablic wejściowych - TCnt jest tu nieznana, one są czytane z dysku.

0

A jak się ma grupa do typu? Żadnych powiązań? Bo przykłady sugerują iż dany typ przynależy do jednej grupy.

0
adf88 napisał(a):

A jak się ma grupa do typu? Żadnych powiązań? Bo przykłady sugerują iż dany typ przynależy do jednej grupy.

Typy są w zasadzie niezależne od obiektów i grup.

W grupach te typu są wyodrębniane jako podgrupy,
a obiekty są tu tylko jakby dodatkową informacją - szczegółową.

Oprócz ilości pojawia się tu jeszcze wartość obiektu (w danej paczce - TCnt),
więc można sumować te wartości z rozbiciem na typy, a finalnie wyliczamy jeszcze wartość całej grupy, sumując wszystko naraz.

1 użytkowników online, w tym zalogowanych: 0, gości: 1