Kshyhoo
12.03.2012, 18:30:34
Nie wiem, jak nazwać to, co chciałbym osiągnąć. Mianowicie, chciałbym wygenerować listę kombinacji liczb i pominąć pewne formy ich powtórzeń. Może przykład powie więcej:
Kod
1 2 3 4
1 2 3 5
1 2 3 6
1 2 3 7
1 2 3 8
1 2 3 9
1 2 3 10
1 2 4 5
1 2 4 6
1 2 4 7
1 2 4 8
1 2 4 9
1 2 4 10
1 2 5 6
1 2 5 7
1 2 5 8
1 2 5 9
1 2 5 10
1 2 6 7
1 2 6 8
1 2 6 9
1 2 6 10
1 2 7 8
1 2 8 9
1 2 8 10
1 2 9 10
itd
czyli z zakresu liczb 1-10 wybieram 4. Chciałbym pominąć wystąpienie np. trzech i czterech liczb po sobie a także takich wystąpień jak co 2, co 3 (1, 3, 5, 7 albo 1, 4, 7, 10).
Jak do tego się zabrać? Lepiej wygenerować i potem usunąć to co mi nie pasuje, czy od razu pomijać?
Poradziłem sobie z generowaniem. Nie mogę jednak skumać, jak pozbyć się co niektórych wpisów, np:
1,2,3,4
1,3,5,7
1,2,4,5
Jakieś pomysły?
jaslanin
12.03.2012, 18:39:47
Napisz bardziej dokładnie o co Ci chodzi. Bo to co napisałeś jest niezbyt zrozumiałem
1.
czyli z zakresu liczb 1-10 wybieram 4.
Wybierasz na jakich zasadach (dlaczego akurat 4, to jest stała, losowa, jakoś liczona liczba?), i co z nimi robisz domyślałam się (szklana kula) że chodzi o 4 kolumny
2.
Chciałbym pominąć wystąpienie np. trzech i czterech liczb po sobie a także takich wystąpień jak co 2, co 3 (1, 3, 5, 7 albo 1, 4, 7, 10).
Wystąpień w kolumnach czy wierszach.
3. inne
dlaczego w pierwszej kolumnie są same jedynki, w drugiej same dwójki, w trzeciej w kolejności rosnącej, a w czwartej rosnąco do dziesięciu, a potem cykl się powtarza
Po prostu nie rozumie.
Kshyhoo
12.03.2012, 18:57:10
Eh. Przecież napisałem w miarę jasno:
1. tablica zawiera liczby (1,2,3,4,5,6,7,8,9,10) i generuję kombinację bez powtórzeń tych liczb, jak na przykładzie w pierwszym poście.
2. skoro kombinacja zawiera 4 liczby, to jasne, że są to wiersze.
3. skoro kombinacja jest w wierszu, wpierw pobierane są pierwsze liczby z tablicy (1,2,3,4), w drugim trzy pierwsze i kolejna (1,2,3,5), potem trzy pierwsze i następna (1,2,3,6), itd...
Jak już napisałem, sobie poradziłem z wygenerowaniem takiej kombinacji. Chciałbym teraz usunąć te, które mi nie odpowiadają, czyli np. wszystkie po sobie (1,2,3,4), (2,3,4,5), co druga (1,3,5,7), (2,4,6,8), co trzecia (1,4,7,10), również dwie, czy trzy w kupie (1,2,5,6), (1,2,3,8)
nospor
14.03.2012, 09:06:53
No dobra, a jak wygląda kod na generowanie i jak wygląda tablica wynikowa.
ps: skoro generujesz nie potrzebne dane, to już podczas generowania je wyrzucaj
Kshyhoo
14.03.2012, 09:09:09
Kod:
$n=0;
$ar1=array(1
,2
,3
,4
,5
,6
,7
,8
,9
,10
);
for( $l1=0
, $size = count($ar1); $l1 <=$size-5; ++$l1) { for( $l2=$l1+1
, $size = count($ar1); $l2 < $size-4; ++$l2) { for( $l3=$l2+1
, $size = count($ar1); $l3 < $size-3; ++$l3) { for( $l4=$l3+1
, $size = count($ar1); $l4 < $size-2; ++$l4) { for( $l5=$l4+1
, $size = count($ar1); $l5 < $size-1; ++$l5) { for($l6=$l5+1
, $size = count($ar1); $l6 < $size; ++$l6) {
//echo $n=$n+1;
//echo ': ';
print $ar1[$l1].'|'.$ar1[$l2].'|'.$ar1[$l3].'|'.$ar1[$l4].'|'.$ar1[$l5].'|'.$ar1[$l6];
}
}
}
}
}
}
Wynik działania (część):
1|2|3|4|5|6
1|2|3|4|5|7
1|2|3|4|5|8
1|2|3|4|5|9
1|2|3|4|5|10
1|2|3|4|6|7
1|2|3|4|6|8
1|2|3|4|6|9
1|2|3|4|6|10
1|2|3|4|7|8
1|2|3|4|7|9
1|2|3|4|7|10
1|2|3|4|8|9
1|2|3|4|8|10
1|2|3|4|9|10
1|2|3|5|6|7
1|2|3|5|6|8
1|2|3|5|6|9
1|2|3|5|6|10
nospor
14.03.2012, 09:19:53
$n=0;
$ar1=array(1
,2
,3
,4
,5
,6
,7
,8
,9
,10
);
for( $l1=0
, $size = count($ar1); $l1 <=$size-5; ++$l1) { for( $l2=$l1+1
, $size = count($ar1); $l2 < $size-4; ++$l2) { for( $l3=$l2+1
, $size = count($ar1); $l3 < $size-3; ++$l3) { for( $l4=$l3+1
, $size = count($ar1); $l4 < $size-2; ++$l4) { for( $l5=$l4+1
, $size = count($ar1); $l5 < $size-1; ++$l5) { for($l6=$l5+1
, $size = count($ar1); $l6 < $size; ++$l6) {
//echo $n=$n+1;
//echo ': ';
$data = array($ar1[$l1],$ar1[$l2],$ar1[$l3],$ar1[$l4],$ar1[$l5],$ar1[$l6]); if (test($data,1) || test($data,2))
continue;
print $ar1[$l1].'|'.$ar1[$l2].'|'.$ar1[$l3].'|'.$ar1[$l4].'|'.$ar1[$l5].'|'.$ar1[$l6]; }
}
}
}
}
}
function test($data, $diff){
$i = 0;
$n = 0;
for ($i=0; $i < $c-1;$i++){
if ($data[$i+1] - $data[$i] == $diff)
$n++;
else
$n = 0;
if ($n>=2) return true; //bo chciałeś gdy 3 obok siebie to już wywalać
}
return false;
}
Kshyhoo
14.03.2012, 09:31:15
2, 3, 4, 5 obok siebie
co 2, 3, 4, 5...
Rozumiem, że mogę też tą funkcją wyszukiwać takie kombinacje z pliku? Bo mam zamiar przelecieć też to, co już wygenerowałem a potem zapisać ponownie w jednym pliku te, które są zgodne ze wzorcem a resztę w innym pliku.
nospor
14.03.2012, 09:41:27
Cytat
2, 3, 4, 5 obok siebie
co 2, 3, 4, 5...
Nie kumam o co ci teraz chodzi. Przecież ten kod pozbywa się właśnie wiersza 2,3,4,5. No przecież nie chciałeś liczb obok siebie.
Cytat
Rozumiem, że mogę też tą funkcją wyszukiwać takie kombinacje z pliku? Bo mam zamiar przelecieć też to, co już wygenerowałem a potem zapisać ponownie w jednym pliku te, które są zgodne ze wzorcem a resztę w innym pliku.
No funkcja przyjmuje tablicę. a skad ta tablica będzie to jej nie obchodzi. Równie dobrze może być z kosmosu - to twoja sprawa.
Kshyhoo
14.03.2012, 09:58:38
Już pisze o co chodzi.
- takie linie pomijam (albo zapisuję w pliku 1), bo jest 5 liczb obok siebie (podobnie, jeżeli jest 4, 3 lub 2):
1|2|3|4|5|6
1|2|3|4|5|7
1|2|3|4|5|8
1|2|3|4|5|9
1|2|3|4|5|10
- takie też, bo są pary, trójki:
1|2|5|7|8
1|2|3|8|9
- chciałbym usunąć też takie:
1|3|5|7|9
czyli co 2
1|4|7|10|13
czyli co 3
1|5|9|13|17
czyli co 4
...itd, do ostatniej liczby podanej w $ar1
I mam też pytanie: Wiem, że zwiększenie $ar1 ciągnie za sobą wzrost kombinacji, w przypadku $ar1=array(1,2,3,4,5,6,7,8,9,10); to:
$iloscKombinacji = (1 * 2 * 3 * 4 * 5 * 6) / (10 * 9 * 8 * 7 * 6 * 5);
Jak wyliczyć, ile kombinacji pominę, używając funkcji pomijania?
nospor
14.03.2012, 10:13:50
Cytat
- takie linie pomijam (albo zapisuję w pliku 1), bo jest 5 liczb obok siebie (podobnie, jeżeli jest 4, 3 lub 2):
1|2|3|4|5|6
1|2|3|4|5|7
1|2|3|4|5|8
1|2|3|4|5|9
1|2|3|4|5|10
- takie też, bo są pary, trójki:
1|2|5|7|8
1|2|3|8|9
- chciałbym usunąć też takie:
1|3|5|7|9
czyli co 2
1|4|7|10|13
czyli co 3
1|5|9|13|17
czyli co 4
No i to wszystko robi moja funkcja. Jedyne co musisz poprawic to to:
if ($n>=2) return true;
na
if ($n>=1) return true;
bo ty nawet pary chcesz usuwac
Cytat
Jak wyliczyć, ile kombinacji pominę, używając funkcji pomijania?
Sory, ale aż takim matematykiem nie jestem.
Na hama to zliczaj poprostu na bieżąco ile pominąłes i będziesz wiedział
Kshyhoo
29.03.2012, 16:17:42
Plik wynikowy rośnie i mam problemy z otwarciem nawet po zwiększeniu pamięci. Wydaje mi się, że lepiej operować na pojedynczej linii z pliku. Można takie cuda w PHP?
EDIT. Chyba się udało:
function test($data, $diff) {
$i = 0;
$n = 0;
for ($i=0; $i < $c-1;$i++) {
if ($data[$i+1] - $data[$i] == $diff)
$n++;
else
$n = 0;
if ($n>=5) return true; //bo chciałeś gdy 3 obok siebie to już wywalać
}
return false;
}
$n=0;
$uchwyt = @fopen("plik.txt", "r"); if ($uchwyt) {
while (($bufor = fgets($uchwyt, 4096
)) !== false) { if (test($bufor,1) || test($bufor,2)) {
continue;
}
}
echo "Błąd: niespodziewany błąd fgets()\n"; }
}
Pobiera linia po linii i usuwa mi te, które są zgodne z wzorcem. teraz tylko zapis do plików (zgodne do jednego a niezgodne do drugiego).
No lipa, działa dobrze tylko powyżej 4 obok siebie - 3 i 2 obok siebie wycina wszystko. czyli przy warunku
if ($n>=2) return true; powinno usuwać więcej niż 3 w kupie, czyli tak:
1,2,3,4,5,6
1,2,3,4,5,7
1,2,3,4,6,8
1,2,3,5,7,91,2,5,7,9,11a jest:
1,2,3,4,5,6
1,2,3,4,5,7
1,2,3,4,6,8
1,2,3,5,7,9
1,2,5,7,9,11
nospor
29.03.2012, 19:09:01
Cytat
czyli tak:
1,2,3,4,5,6
1,2,3,4,5,7
1,2,3,4,6,8
1,2,3,5,7,9
1,2,5,7,9,11
a jest:
1,2,3,4,5,6
1,2,3,4,5,7
1,2,3,4,6,8
1,2,3,5,7,9
1,2,5,7,9,11
Pokazałeś dokładnie dwa takie same kwadraty, a z kontekstu wypowiedzi wynika, że powinny się różnić. W czym więc problem?
Kshyhoo
29.03.2012, 19:29:48
Nie powinno wyciąć linii na niebiesko a to robi.
Np:
$uchwyt = @fopen("plik.txt", "r"); if ($uchwyt) {
while (($data = fgets($uchwyt, 4096
)) !== false) { if (test($data,1) || test($data,2)) {
// DOBRE (czerwony)
echo '<font color="#f00">'; echo $data.'</font><br>'; continue;
} else {
// WYCIĘTE (niebieski)
echo'<font color="#00f">'; echo $data.'</font><br>'; continue;
}
}
echo "Błąd: niespodziewany błąd fgets()\n"; }
}
nospor
29.03.2012, 19:32:39
Pokaz dokładnie jak na chwilę obecną wygląda funkcja test()
Kshyhoo
29.03.2012, 19:35:58
function test($data, $diff) {
$i = 0;
$n = 0;
for ($i=0; $i < $c-1; $i++) {
if ($data[$i+1] - $data[$i] == $diff)
$n++;
else
$n = 0;
if ($n>=2) return true; // 3 obok siebie usuwa
}
return false;
}
nospor
29.03.2012, 19:38:17
test($data,2)
No przecież badasz też dla różnicy DWA
A te dane:
1,2,5,7,9,11
spełaniają właśnie warunek dla różnicy DWA... no ksyhoooooooo mysl troche co piszesz
Kshyhoo
29.03.2012, 19:42:58
Odłożyłem ten skrypt na dwa tygodnie i nie mogę teraz skumać tej funkcji

Czyli linia:
if (test($data,1) || test($data,2)) {
sprawdza, jak liczby stoją daleko od siebie?
A linia:
if ($n>=2) return true;
w funkcji w takim razie?
nospor
29.03.2012, 19:46:24
Linia pierwsza co pokazałeś wywołuje funkcje test()...
Drugim argumentem funkcji test jest różnica jaką ma sprawdzać. Różnica między dwoma liczbami znajdującymi się obok siebie.
$n - liczb różnic (znajdujących sie obok siebie) pasujących do drugiego argumentu.
Kshyhoo
29.03.2012, 19:52:53
Czyli test($data,1) oznacza, że liczby są po kolei (1,2,3,4,5) a test($data,2), że co druga (1,3,5,7,9) - innymi słowy, sprawdza oddalenie liczb (np. co 2, co 3...)?
if ($n>=2) return true; a myślałem, że to sprawdza, ile liczb jest obok siebie (w tym wypadku 3)...
nospor
29.03.2012, 19:58:11
Cytat
Czyli test($data,1) oznacza, że liczby są po kolei (1,2,3,4,5) a test($data,2), że co druga (1,3,5,7,9) - innymi słowy, sprawdza oddalenie liczb (np. co 2, co 3...)?
Tak.
Cytat
if ($n>=2) return true; a myślałem, że to sprawdza, ile liczb jest obok siebie (w tym wypadku 3)...
Bo to właśnie robi, ale bierze pod uwagę różnicę. Dla różnicy 2, to liczby 1,3,5,7 są obok siebie. Dla różnicy 1 te libczy 1,3,5,7 nie są obok siebie. Dla różnicy 1 te liczby 1,2,3,4 są obok siebie.
Kshyhoo
29.03.2012, 20:06:48
No właśnie, przedobrzone

Bo powinno usunąć też przykład na niebiesko, czyli 2 liczby obok siebie - a nie robi tego, gdy wywołuje się funkcję kilka razy z innym parametrem.
Dodam, że dla warunku if ($n>=1) return true;
nospor
29.03.2012, 20:10:11
Cytat
No właśnie, przedobrzone
Było zrobione wg. twoich początkowych założeń. Jak nie chcesz sprawdzać dla różnicy DWA to ją poprostu wywal z tego warunku
if (test($data,1) || test($data,2))
Nikt ci tego nie broni.
Kshyhoo
1.04.2012, 11:04:19
Spoko, po prostu myślałem, że tylko rozróżnia kilka obok siebie a tu taka miła niespodzianka

Jeszcze raz dzięki za pomoc.
Mam jeszcze jeden problem: chciałbym zachować np. taką kombinację:
1,3,8,15,27,33
a takie usuwać:
1,3,5,8,15,27
czyli np. w rozstawie co 2 zachować pary a powyżej usuwać - analogicznie w rozstawie co 3, również zachować pary a usuwać powyżej, itp, dla 4, 5... 10.
nospor
1.04.2012, 11:09:44
Przeanalizuj wkoncu funkcje TEST(). Toż to pare linijek jest tylko.
No musisz ten warunek zmienic: if ($n>=1)
Kshyhoo
1.04.2012, 11:21:13
Sądzisz, że nie kombinowałem?
Zmieniałem w funkcji:
if ($n>=1) return true; // 2 obok siebie usuwa
if ($n>=2) return true; // 3 obok siebie usuwa
if ($n>=3) return true; // 4 obok siebie usuwa
if ($n>=4) return true; // 5 obok siebie usuwa
if ($n>=5) return true; // 6 obok siebie usuwa
Grzebałem też tu:
if ($data[$i+1] - $data[$i] == $diff)
żeby zmienić różnicę. Nawet zmieniałem to:
if (test($data,1)) {
Żeby zmienić rozstawienie...
Bez efektu ;(
nospor
1.04.2012, 11:40:26
Cytat
if ($n>=1) return true; // 2 obok siebie usuwa
if ($n>=2) return true; // 3 obok siebie usuwa
if ($n>=3) return true; // 4 obok siebie usuwa
if ($n>=4) return true; // 5 obok siebie usuwa
if ($n>=5) return true; // 6 obok siebie usuwa
No i tak jest. To nie kumam jaki masz problem.
Kshyhoo
1.04.2012, 12:10:33
Bo usuwa wszystkie a ja chciałbym zachować pary w rozstawieniu...
nospor
2.04.2012, 06:26:50
Cytat
zachować pary w rozstawieniu...
Sorry ale nadal nie kumam co to znaczy.
Kshyhoo
2.04.2012, 07:30:09
Tu napisałem, ale powtórzę. Funkcja usuwa kombinacje np. co 2, czyli:
1,3,5,7,9,111,3,5,7,9,12
1,3,5,7,10,15
1,3,5,8,11,25
1,3,6,9,12,15
bo są liczby ulokowane co 2. Ja chciałbym zachować ostatni przykład, czyli pary (przypadek 1,3 albo 12,14) ... a już 3 usuwać (1,3,5 czy 12,14,16).
Nie mogę skumać, jaki warunek dać, żeby zostawiło takie kombinacje a usunęło inne.
Podobnie chcę zrobić z "trójkami", "czwórkami", ... czyli jak trafi
1,4,7,11,25 to usunie (bo różnica 3 ale 4 w kupie) a jak 2,8,
15,17,25,33 to zostawi (bo różnica 3 ale tylko 2 w kupie).
Nie jestem "zawodowym" programistą a samoukiem, umiem generalnie to, co potrzebne do napisania strony www - jak przychodzi coś konkretniejszego, nie łapię tematu.
nospor
2.04.2012, 07:48:09
No to dodaj kolejny parametr do funkcji TEST() np. $nn i zamiast:
if ($n>=1)
rób
if ($n>=$nn)
A ten $nn bedziesz sam ustalał przy wywoływaniu funkcji TEST()
Kshyhoo
2.04.2012, 08:36:35
Też już pisałem, że tak kombinowałem i mi nie działało z założeniami. Nie wiem, co robię źle. Wkleję jak wrócę od medyka to, co udało mi się spłodzić.
nospor
2.04.2012, 08:46:15
Nie, nie pisałeś, że sparametryzowałeś $n
Kshyhoo
2.04.2012, 09:11:34
No właśnie nie wiem, jak zmienić to if ($n>=$2), bo generalnie działa. Jeżeli $n jest większa lub równa 2, to wykop... a nie wiem, jak zamienić to wykop na "jeżeli tylko będzie więcej niż jedna różnica".
No dobra, chyba działa:
function test($data, $diff) {
$i = 0;
$n = 0;
for ($i=0; $i < $c-1; $i++) {
if ($data[$i+1] - $data[$i] == $diff)
$n++;
else
$n = 1; // <<<<<<<<< tu zmiana
if ($n>=2) return true; // 3 obok siebie usuwa
}
return false;
}
// i w wywołaniu
if (test($data,2)) {
Przykład:
1,3,5,7,9,11
1,3,5,7,9,12
1,3,5,7,10,15
1,3,5,8,12,181,3,8,15,21,33niezgodnezgodne
nospor
2.04.2012, 09:12:15
nie: $n>=$2
a: $n>=$nn
Przeciez pisałem....
A $nn to trzeci parametr funkcji test()
singollo
2.04.2012, 09:12:52
Przeczytałem cały wątek i nadal nie jestem pewien, czy dobrze rozumiem zadanie. Możecie mnie upewnić:
Dany jest zbiór uporządkowanych ciągów liczb. Należy z niego usunąć ciągi, które spełniają co najmniej jeden z poniższych warunków:
- zawierają N1 lub więcej liczb różniących się dokładnie o 1 (np. 1,2,3; 6,7,4; 9,10,11 itp). Długość takiego podciągu wynosi co najmniej N1.
- zawierają N2 lub więcej liczb różniących się dokładnie o 2 (np. 1,3,5; 2,4,6; itp). Długość takiego podciągu wynosi co najmniej N2.
- zawierają N3 lub więcej liczb różniących się dokładnie o 3 (np. 1,4,7; 2,5,8; itp). Długość takiego podciągu wynosi co najmniej N3.
....
- zawierają Nm lub więcej liczb różniących się dokładnie o m (np. 1,1+m,1+2m; 2,2+m,2+2m; itp). Długość takiego podciągu wynosi co najmniej Nm.
Dobrze zrozumiałem? Jeśli podacie wielkości N1, N2, ..., Nm to chyba będę w stanie zaproponować rozwiązanie...
Kshyhoo
2.04.2012, 09:23:18
Aaaaa, teraz kumam

Sprawdzę, jak wrócę od medyka a międzyczasie zobaczę, czy działa to, co ja spłodziłem (na przykładzie działa dobrze).
1. zakres liczb kombinacji (bez powtórzeń) 1-x (x może być np. 100, choć to da sporo kombinacji)
2. liczb w kombinacji 6 (1,2,3,4,5,6)
3. kombinacje liczb, gdzie wszystkie liczby są po kolei - WYKLUCZONE
4. kombinacje liczb, gdzie liczby są rozstawione co 2, 3, 4, 5, ..., n, WYKLUCZONE powyżej trzeciej (np. 1,
5,7,9,11,18 usuwa ale 1,
5,7,15,19,33 zostaje - bo 5 i 7 to 2 liczby)
to chyba na tyle...
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę
kliknij tutaj.