Thread View: pl.comp.programming
16 messages
16 total messages
Started by Borneq
Mon, 18 Nov 2019 13:09
Jak zrobić grupowanie w kolejności
Author: Borneq
Date: Mon, 18 Nov 2019 13:09
Date: Mon, 18 Nov 2019 13:09
25 lines
1634 bytes
1634 bytes
Mam liczby 1,5,7,10,100,5,6,
jak zrobić grupy o co najmniej sumie 10, nie zmieniając kolejności tak jak:
(1,5,7),(10),(100),(5,6),
zamiast liczb mogą być długości stringów,
mogę najprościej:
vector<wstring> vec;
vector<wstring> veclongs;
int n = 0;
for (int i = 0; i < vec.size(); i++)
{
if (i == 0 || vec[i].length() > 10)
{
veclongs.push_back(vec[i]);
n++;
}
else veclongs.back() = veclongs.back() + vec[i];
}
return veclongs;
Jedna wada to i==0 bo inaczej nie da rady veclongs.back()
co gdy pierwszy będzie mały np 5 a pozostałe wystarczajace?
np: 5,10,10,10, - bez grupowania
a trzeba (5,10),10,10
Jak to zrobić, niby prosto bo bez zmiany kolejności
Re: Jak zrobić grupowanie w kolejności
Author: M.M.
Date: Mon, 18 Nov 2019 14:22
Date: Mon, 18 Nov 2019 14:22
7 lines
1474 bytes
1474 bytes
On Monday, November 18, 2019 at 2:09:47 PM UTC+1, Borneq wrote: > Mam liczby 1,5,7,10,100,5,6, > jak zrobić grupy o co najmniej sumie 10 Potrzebujesz dowolną grupę, jakąś konkretną, wszystkie grupy? Pozdrawiam
Re: Jak zrobić grupowanie w kolejności
Author: Borneq
Date: Mon, 18 Nov 2019 14:28
Date: Mon, 18 Nov 2019 14:28
10 lines
1673 bytes
1673 bytes
W dniu 18.11.2019 o 15:22, M.M. pisze: > On Monday, November 18, 2019 at 2:09:47 PM UTC+1, Borneq wrote: >> Mam liczby 1,5,7,10,100,5,6, >> jak zrobić grupy o co najmniej sumie 10 > > Potrzebujesz dowolną grupę, jakąś konkretną, wszystkie grupy? > > Pozdrawiam > Wszystkie, chcę łączyć stringi, aby miały conajmniej jakąś długość.
Re: Jak zrobić grupowanie w kolejności
Author: godek.maciek
Date: Mon, 18 Nov 2019 14:47
Date: Mon, 18 Nov 2019 14:47
38 lines
2523 bytes
2523 bytes
W dniu poniedziałek, 18 listopada 2019 14:09:47 UTC+1 użytkownik Borneq napisał:
> Mam liczby 1,5,7,10,100,5,6,
> jak zrobić grupy o co najmniej sumie 10, nie zmieniając kolejności tak jak:
> (1,5,7),(10),(100),(5,6),
> zamiast liczb mogą być długości stringów,
> mogę najprościej:
> vector<wstring> vec;
> vector<wstring> veclongs;
>
> int n = 0;
> for (int i = 0; i < vec.size(); i++)
> {
> if (i == 0 || vec[i].length() > 10)
> {
> veclongs.push_back(vec[i]);
> n++;
> }
> else veclongs.back() = veclongs.back() + vec[i];
> }
> return veclongs;
>
> Jedna wada to i==0 bo inaczej nie da rady veclongs.back()
> co gdy pierwszy będzie mały np 5 a pozostałe wystarczajace?
> np: 5,10,10,10, - bez grupowania
> a trzeba (5,10),10,10
> Jak to zrobić, niby prosto bo bez zmiany kolejności
W Haskellu na szybko:
groups :: [a] -> ([a] -> Bool) -> [[a]]
groups list c = f list []
where f (h:t) g | (c (g++[h])) = [g++[h]]++(f t [])
f (h:t) g = f t (g++[h])
f [] g = []
groups [1,5,7,10,100,5,6] (\x -> (sum x) >= 10)
[[1,5,7],[10],[100],[5,6]]
Re: Jak zrobić grupowanie w kolejności
Author: godek.maciek
Date: Mon, 18 Nov 2019 14:57
Date: Mon, 18 Nov 2019 14:57
44 lines
2959 bytes
2959 bytes
W dniu poniedziałek, 18 listopada 2019 15:47:23 UTC+1 użytkownik godek...@gmail.com napisał:
> W dniu poniedziałek, 18 listopada 2019 14:09:47 UTC+1 użytkownik Borneq napisał:
> > Mam liczby 1,5,7,10,100,5,6,
> > jak zrobić grupy o co najmniej sumie 10, nie zmieniając kolejności tak jak:
> > (1,5,7),(10),(100),(5,6),
> > zamiast liczb mogą być długości stringów,
> > mogę najprościej:
> > vector<wstring> vec;
> > vector<wstring> veclongs;
> >
> > int n = 0;
> > for (int i = 0; i < vec.size(); i++)
> > {
> > if (i == 0 || vec[i].length() > 10)
> > {
> > veclongs.push_back(vec[i]);
> > n++;
> > }
> > else veclongs.back() = veclongs.back() + vec[i];
> > }
> > return veclongs;
> >
> > Jedna wada to i==0 bo inaczej nie da rady veclongs.back()
> > co gdy pierwszy będzie mały np 5 a pozostałe wystarczajace?
> > np: 5,10,10,10, - bez grupowania
> > a trzeba (5,10),10,10
> > Jak to zrobić, niby prosto bo bez zmiany kolejności
>
>
> W Haskellu na szybko:
>
> groups :: [a] -> ([a] -> Bool) -> [[a]]
> groups list c = f list []
> where f (h:t) g | (c (g++[h])) = [g++[h]]++(f t [])
> f (h:t) g = f t (g++[h])
> f [] g = []
>
> groups [1,5,7,10,100,5,6] (\x -> (sum x) >= 10)
> [[1,5,7],[10],[100],[5,6]]
Ewentualnie jakbyś chciał, żeby ostatnia niepełna grupa też trafiała do listy, to wtedy zamiast ostatniego warunku byś musiał napisać:
f [] [] = []
f [] g = [g]
Re: Jak zrobić grupowanie w kolejności
Author: M.M.
Date: Mon, 18 Nov 2019 15:12
Date: Mon, 18 Nov 2019 15:12
17 lines
2109 bytes
2109 bytes
On Monday, November 18, 2019 at 3:28:24 PM UTC+1, Borneq wrote: > W dniu 18.11.2019 o 15:22, M.M. pisze: > > On Monday, November 18, 2019 at 2:09:47 PM UTC+1, Borneq wrote: > >> Mam liczby 1,5,7,10,100,5,6, > >> jak zrobić grupy o co najmniej sumie 10 > > > > Potrzebujesz dowolną grupę, jakąś konkretną, wszystkie grupy? > > > > Pozdrawiam > > > Wszystkie, chcę łączyć stringi, aby miały conajmniej jakąś długość. I tak że jeśli jakiś wyraz był na pozycji np. drugiej, a inny wyraz na pozycji trzeciej, to po złączeniu nie zamienią się kolejnością, tylko nadal będzie złączenie drugi+trzeci? Pozdrawiam
Re: Jak zrobić grupowanie w kolejności
Author: Borneq
Date: Mon, 18 Nov 2019 18:47
Date: Mon, 18 Nov 2019 18:47
8 lines
1568 bytes
1568 bytes
W dniu 18.11.2019 o 16:12, M.M. pisze: > I tak że jeśli jakiś wyraz był na pozycji np. drugiej, a inny wyraz > na pozycji trzeciej, to po złączeniu nie zamienią się kolejnością, tylko > nadal będzie złączenie drugi+trzeci? Tak, chodziło mi o najprostszy przypadek, napisałem szybko powyższą pętlę, tylko się okazuje że nie uwzględnia przypadków gdy pierwszy krótki a drugi długi.
Re: Jak zrobić grupowanie w kolejności
Author: Borneq
Date: Mon, 18 Nov 2019 18:51
Date: Mon, 18 Nov 2019 18:51
11 lines
1424 bytes
1424 bytes
W dniu 18.11.2019 o 15:47, godek.maciek@gmail.com pisze: > W dniu poniedziałek, 18 listopada 2019 14:09:47 UTC+1 użytkownik Borneq napisał: >> Mam liczby 1,5,7,10,100,5,6, > groups [1,5,7,10,100,5,6] (\x -> (sum x) >= 10) > [[1,5,7],[10],[100],[5,6]] > Ten przykład niezbyt dobry, bo 5 <10 i mój sposób też zadziała, ale weźmy: 1,10,7,3,10,100,5,6,
Re: Jak zrobić grupowanie w kolejności
Author: godek.maciek
Date: Mon, 18 Nov 2019 19:08
Date: Mon, 18 Nov 2019 19:08
19 lines
1916 bytes
1916 bytes
W dniu poniedziałek, 18 listopada 2019 19:51:20 UTC+1 użytkownik Borneq napisał: > > >> Mam liczby 1,5,7,10,100,5,6, > > groups [1,5,7,10,100,5,6] (\x -> (sum x) >= 10) > > [[1,5,7],[10],[100],[5,6]] > > > > Ten przykład niezbyt dobry, bo 5 <10 i mój sposób też zadziała, > ale weźmy: > 1,10,7,3,10,100,5,6, To mi daje coś takiego: [[1,10],[7,3],[10],[100],[5,6]] Tutaj sobie możesz potestować: https://rextester.com/HGC85517
Re: Jak zrobić grupowanie w kolejności
Author: godek.maciek
Date: Mon, 18 Nov 2019 22:40
Date: Mon, 18 Nov 2019 22:40
23 lines
2273 bytes
2273 bytes
W dniu poniedziałek, 18 listopada 2019 20:08:40 UTC+1 użytkownik godek...@gmail.com napisał: > W dniu poniedziałek, 18 listopada 2019 19:51:20 UTC+1 użytkownik Borneq napisał: > > > > > >> Mam liczby 1,5,7,10,100,5,6, > > > groups [1,5,7,10,100,5,6] (\x -> (sum x) >= 10) > > > [[1,5,7],[10],[100],[5,6]] > > > > > > > Ten przykład niezbyt dobry, bo 5 <10 i mój sposób też zadziała, > > ale weźmy: > > 1,10,7,3,10,100,5,6, > > To mi daje coś takiego: > > [[1,10],[7,3],[10],[100],[5,6]] > > Tutaj sobie możesz potestować: > > https://rextester.com/HGC85517 Trochę poprawiłem nazwy i formatowanie, może teraz będzie nieco czytelniejsze: https://rextester.com/CRWPJS53169
Re: Jak zrobić grupowanie w kolejności
Author: Borneq
Date: Tue, 19 Nov 2019 12:52
Date: Tue, 19 Nov 2019 12:52
17 lines
1743 bytes
1743 bytes
W dniu 18.11.2019 o 23:40, godek.maciek@gmail.com pisze:
>> [[1,10],[7,3],[10],[100],[5,6]]
> Trochę poprawiłem nazwy i formatowanie, może teraz będzie nieco czytelniejsze:
> https://rextester.com/CRWPJS53169
Wyniki daje dobre.
Trzeba by przeanalizować, jakie znaczenie ma ++ ?
jest tu jakiś sposób rekurencyjny
grouped [] [] = []
grouped [] g = [g]
Te dwa powyżej rozumiem
a
grouped (h:t) g
| (cond (g++[h])) = [g++[h]]++(grouped t [])
grouped (h:t) g = grouped t (g++[h])
?
Re: Jak zrobić grupowanie w kolejności
Author: godek.maciek
Date: Tue, 19 Nov 2019 16:11
Date: Tue, 19 Nov 2019 16:11
67 lines
3791 bytes
3791 bytes
W dniu wtorek, 19 listopada 2019 13:52:06 UTC+1 użytkownik Borneq napisał:
> >> [[1,10],[7,3],[10],[100],[5,6]]
> > Trochę poprawiłem nazwy i formatowanie, może teraz będzie nieco czytelniejsze:
> > https://rextester.com/CRWPJS53169
>
> Wyniki daje dobre.
> Trzeba by przeanalizować, jakie znaczenie ma ++ ?
++ to sklejanie list:
[1,2]++[3,4] daje [1,2,3,4]
Niestety w przypadku języków funkcyjnych dopisywanie elementu na koniec listy jest raczej kosztowne. No ale to szczegół
> jest tu jakiś sposób rekurencyjny
Jest rekurencyjny, ale to prosta rekurencja, którą można łatwo zamienic na pętlę.
Jakby co, to napisałem rozwiązanie rekurencyjne w Pythonie.
Wariant iteracyjny wygląda tak:
def igroups(l, cond):
result = []
group = []
for x in l:
group += [x]
if cond(group):
result += [group]
group = []
if group:
result += [group]
return result
> grouped [] [] = []
> grouped [] g = [g]
> Te dwa powyżej rozumiem
> a
> grouped (h:t) g
> | (cond (g++[h])) = [g++[h]]++(grouped t [])
> grouped (h:t) g = grouped t (g++[h])
>
> ?
W pierwszym przypadku jest tzn. "pattern guard", tzn. jeżeli funkcja "cond" dla argumentu g++[h] zwróci True, to zwracamy [g++[h]] ++ (grouped t []), albo innymi słowy - zamykamy bieżącą grupę z dopisanym bieżącym elementem i tworzymy nową pustą grupę, którą będziemy przetwarzać na pozostałych elementach listy.
Jeżeli "cond" nie jest spełnione, to dodajemy bieżący element do bieżącej grupy i przetwarzamy resztę listy.
Tutaj jest Pythonowa wersja, w której umieściłem Haskellowe patterny i guardy w komentarzach
def groups(l, cond):
def group(l, g):
if l: ### grouped (h:t) g -- lista niepusta
h, *t = l
if cond(g+[h]): ### | (cond (g++[h])) -- warunek spelniony
return [g+[h]]+group(t, [])
return group(t, g+[h]) ### -- warunek niespelniony
if g:
return [g] ### grouped [] g -- grupa jest niepusta
return [] ### grouped [] [] -- pusta grupa
return group(l, [])
Oba warianty możesz potestować tutaj:
https://rextester.com/FCY59693
Re: Jak zrobić grupowanie w kolejności
Author: Borneq
Date: Tue, 19 Nov 2019 16:36
Date: Tue, 19 Nov 2019 16:36
10 lines
1797 bytes
1797 bytes
W dniu 19.11.2019 o 17:11, godek.maciek@gmail.com pisze: > Tutaj jest Pythonowa wersja, w której umieściłem Haskellowe patterny i guardy w komentarzach > return group(t, g+[h]) ### -- warunek niespelniony > if g: > return [g] ### grouped [] g -- grupa jest niepusta > return [] ### grouped [] [] -- pusta grupa > return group(l, []) To jest jakaś rekurencja ogonowa, którą można przenieść na pętlę nie zajmując stosu?
Re: Jak zrobić grupowanie w kolejności
Author: Borneq
Date: Tue, 19 Nov 2019 17:25
Date: Tue, 19 Nov 2019 17:25
4 lines
1791 bytes
1791 bytes
W dniu 19.11.2019 o 17:11, godek.maciek@gmail.com pisze: > Tutaj jest Pythonowa wersja, w której umieściłem Haskellowe patterny i guardy w komentarzach Wielkie dzięki, Python da już radę być przerobiony na C++
Re: Jak zrobić grupowanie w kolejności
Author: godek.maciek
Date: Tue, 19 Nov 2019 17:29
Date: Tue, 19 Nov 2019 17:29
37 lines
3305 bytes
3305 bytes
W dniu wtorek, 19 listopada 2019 17:37:28 UTC+1 użytkownik Borneq napisał:
> > Tutaj jest Pythonowa wersja, w której umieściłem Haskellowe patterny i guardy w komentarzach
> > return group(t, g+[h]) ### -- warunek niespelniony
> > if g:
> > return [g] ### grouped [] g -- grupa jest niepusta
> > return [] ### grouped [] [] -- pusta grupa
> > return group(l, [])
>
> To jest jakaś rekurencja ogonowa, którą można przenieść na pętlę nie
> zajmując stosu?
Nie, w tym przypadku rekurencja nie jest ogonowa, bo jedno z wywołań rekurencyjnych jest zagnieżdżone w wywołanie innej funkcji (sklejania list).
Chodzi konkretnie o linię:
return [g+[h]]+group(t, [])
Typowo jeśli chcielibyśmy przekształcić taką rekurencję w rekurencję ogonową, musielibyśmy stworzyć dodatkowy argument reprezentujący wynik.
Możemy tak zrobić, jeśli strukutra rekurencji jest liniowa (albo inaczej: nie-drzewiasta). Wersja Pythonowa zapisana z rekurencją ogonową wyglądałaby tak:
def trgroups(l, cond):
def group(l, g, out):
if l:
h, *t = l
if cond(g+[h]):
return group(t, [], out+[g+[h]])
return group(t, g+[h], out)
if g:
return out+[g]
return out
return group(l, [], [])
Takie coś rzeczywiście nie powinno zajmować stosu w implementacjach optymalizujących rekurencję ogonową (do których Pythony raczej się nie zaliczają)
Tutaj link:
https://rextester.com/FCY59693
Re: Jak zrobić grupowanie w kolejności
Author: M.M.
Date: Wed, 20 Nov 2019 00:00
Date: Wed, 20 Nov 2019 00:00
111 lines
4773 bytes
4773 bytes
On Monday, November 18, 2019 at 2:09:47 PM UTC+1, Borneq wrote:
> Mam liczby 1,5,7,10,100,5,6,
> jak zrobić grupy o co najmniej sumie 10, nie zmieniając kolejności tak jak:
> (1,5,7),(10),(100),(5,6),
> zamiast liczb mogą być długości stringów,
> mogę najprościej:
> vector<wstring> vec;
> vector<wstring> veclongs;
>
> int n = 0;
> for (int i = 0; i < vec.size(); i++)
> {
> if (i == 0 || vec[i].length() > 10)
> {
> veclongs.push_back(vec[i]);
> n++;
> }
> else veclongs.back() = veclongs.back() + vec[i];
> }
> return veclongs;
>
> Jedna wada to i==0 bo inaczej nie da rady veclongs.back()
> co gdy pierwszy będzie mały np 5 a pozostałe wystarczajace?
> np: 5,10,10,10, - bez grupowania
> a trzeba (5,10),10,10
> Jak to zrobić, niby prosto bo bez zmiany kolejności
A w jednej grupie mogą być opuszczenia wyrazów, czy nie?
Jak nie mogą, czyli jak muszą być kolejne, to tak:
#include <QTextStream>
#include <QTextCodec>
#include <QByteArray>
#include <QRegExp>
#include <QStringList>
static void groups(
QTextStream &sout ,
const QStringList &words ,
const int start ,
const int minLen ,
QStringList &stack
) {
bool found = false;
for( int i=start ; i<words.size() ; i++ ) {
int len = 0;
for( int j=i ; j<words.size() ; j++ ) {
len += words[j].size();
if( len < minLen ) {
continue;
}
found = true;
stack.push_back( words.mid(i,j-i+1).join('|') ) ;
groups( sout , words , j+1 , minLen , stack );
stack.pop_back();
}
}
if( ! found && stack.size() > 0 ) {
sout << stack.join(", ") << endl;
}
}
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
QTextStream sinp(stdin);
QTextStream sout(stdout);
sinp.setCodec("UTF-8");
sout.setCodec("UTF-8");
const int minLen = sinp.readLine().toInt();
const QString line = sinp.readLine();
const QStringList words = line.split( QRegExp("\\s+") , QString::SkipEmptyParts );
QStringList stack;
groups( sout , words , 0 , minLen , stack );
return 0;
}
8
aaaa bbb ccc ddd eee fffffffff gg
aaaa|bbb|ccc, ddd|eee|fffffffff
aaaa|bbb|ccc, ddd|eee|fffffffff|gg
aaaa|bbb|ccc, eee|fffffffff
aaaa|bbb|ccc, eee|fffffffff|gg
aaaa|bbb|ccc, fffffffff
aaaa|bbb|ccc, fffffffff|gg
aaaa|bbb|ccc|ddd, eee|fffffffff
aaaa|bbb|ccc|ddd, eee|fffffffff|gg
aaaa|bbb|ccc|ddd, fffffffff
aaaa|bbb|ccc|ddd, fffffffff|gg
aaaa|bbb|ccc|ddd|eee, fffffffff
aaaa|bbb|ccc|ddd|eee, fffffffff|gg
aaaa|bbb|ccc|ddd|eee|fffffffff
aaaa|bbb|ccc|ddd|eee|fffffffff|gg
bbb|ccc|ddd, eee|fffffffff
bbb|ccc|ddd, eee|fffffffff|gg
bbb|ccc|ddd, fffffffff
bbb|ccc|ddd, fffffffff|gg
bbb|ccc|ddd|eee, fffffffff
bbb|ccc|ddd|eee, fffffffff|gg
bbb|ccc|ddd|eee|fffffffff
bbb|ccc|ddd|eee|fffffffff|gg
ccc|ddd|eee, fffffffff
ccc|ddd|eee, fffffffff|gg
ccc|ddd|eee|fffffffff
ccc|ddd|eee|fffffffff|gg
ddd|eee|fffffffff
ddd|eee|fffffffff|gg
eee|fffffffff
eee|fffffffff|gg
fffffffff
fffffffff|gg
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads