Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP] Pętla for oraz if
hunter777
post 5.11.2017, 08:47:54
Post #1





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 8.02.2017

Ostrzeżenie: (0%)
-----


mam takie zadanko,
sprawdź tablicę znaków np [1,1,3,4] i jeśli można za pomocą zabrania tylko jednego elementu sprawić by ciąg liczb był rosnący zwróć true.

zrobiłem to tak

  1. function almostIncreasingSequence($sequence) {
  2. $t = $sequence;
  3. $j = count($sequence);
  4.  
  5.  
  6.  
  7. for ($i=0; $i<$j; $i++) {
  8. $a[$i] = $t[$i];
  9. $b[$i] = $t[$i-1];
  10.  
  11. if ($b > $a) {
  12. $c = $c++;
  13.  
  14. return $c; }
  15. }
  16.  
  17. }
  18. if ($c > 2) {
  19.  
  20. return false;
  21.  
  22. } else {
  23.  
  24. return true;
  25. }


ale to niestety nie działa, wychodzi mi z pętli po jednym elemencie...
coś robię nie tak..

ja to wymyśliłem tak, sprawdź każdy element w tablicy i porównaj każdy kolejny z poprzednim i jeśli poprzedni jest większy od następnego to zwiększ licznik, jeśli licznik będzie większy niż 1 tzn, że mam więcej niż jedną liczbę...

poproszę o jakieś sugestie a nie gotowe rozwiązanie, z góry dziękuję
Go to the top of the page
+Quote Post
sabat24
post 5.11.2017, 11:30:52
Post #2





Grupa: Zarejestrowani
Postów: 175
Pomógł: 26
Dołączył: 13.09.2007
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


1. pętle for nie możesz zacząć od 0, skoro szukasz poprzednika.
2. tworzysz tablicę dla zmiennych $a i $b, a później porównujesz tak jakby to były wartości skalarne
3. bardziej optymalnie będzie wyjść z pętli w przypadku znalezienia dwóch liczb, które nie spełniają warunku, by nie iterować całej tablicy

Założenia:
wartości przekazane do metody są posortowane rosnąco
tablica co najmniej dwóch elementów

  1.  
  2. $sequence = [1,1,3,4];
  3. public function almostIncreasingSequence($sequence) {
  4. $j = count($sequence);
  5. $not_higher_than_previous = 0;
  6. for($i = 0; $i < $j - 1; $i++) {
  7. if ($sequence[$i] >= $sequence[($i + 1)]) {
  8. $not_higher_than_previous++;
  9. if ($not_higher_than_previous === 2) return FALSE;
  10. }
  11. }
  12.  
  13. return $not_higher_than_previous === 1 ? TRUE : FALSE;
  14. }



Go to the top of the page
+Quote Post
hunter777
post 5.11.2017, 17:23:42
Post #3





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 8.02.2017

Ostrzeżenie: (0%)
-----


dziękuję za sugestie przede wszystkim co do pamiętania o tym by trzymać się odpowiednich zmiennych... kod super - widać poziom! ale mam jeden problem, że w momencie tablicy np:

sequence: [1, 2, 1, 2]

daje nam wynik: true a powinno false, ponieważ niby ma tylko jedna niepasującą/większą ale to nie zmienia ciągu ponieważ jak wyrzucimy to 2 to i tak nie będzie w pełni rosnący... oczywiście próbuje to rozwiązać sam tylko nadmieniam o tym iż jest taka sytuacja.

pozdrawiam smile.gif
Go to the top of the page
+Quote Post
sabat24
post 5.11.2017, 17:34:01
Post #4





Grupa: Zarejestrowani
Postów: 175
Pomógł: 26
Dołączył: 13.09.2007
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


Dlatego dodałem założenia, że: "wartości przekazane do metody są posortowane rosnąco", czyli nie może być to tablica [1, 2, 1, 2], ale [1, 1, 2, 2], czyli albo zrób sort w tej metodzie, jeśli przekazujesz dane niesprawdzone albo wcześniej zrób sort.
Go to the top of the page
+Quote Post
kreatiff
post 5.11.2017, 22:25:55
Post #5





Grupa: Zarejestrowani
Postów: 324
Pomógł: 105
Dołączył: 7.08.2012

Ostrzeżenie: (0%)
-----


Inne rozwiązanie:
  1. function almostIncreasingSequence($a) {
  2. $bledy = 0;
  3. sort($a);
  4. foreach ($a as $biezacy) {
  5. if (!isset($poprzedni) || $poprzedni < $biezacy) {
  6. $poprzedni = $biezacy;
  7. continue;
  8. } else {
  9. $bledy++;
  10. }
  11. if ($bledy > 1) {
  12. return false;
  13. }
  14. }
  15. return true;
  16. }
Go to the top of the page
+Quote Post
trueblue
post 5.11.2017, 22:57:04
Post #6





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


A czy na pewno posortowanie danych przed sprawdzeniem ciągu jest poprawne?
Bo wydaje mi się, że rzecz w tym, aby sprawdzić ciąg nieposortowany.

  1. $sequence = [1,1,2,3];
  2. if(count($sequence) - count(array_unique($sequence)) == 1){
  3. echo "mozna";
  4. }
  5. else{
  6. echo "nie mozna";
  7. }




Ten post edytował trueblue 5.11.2017, 23:02:57


--------------------
Go to the top of the page
+Quote Post
hunter777
post 6.11.2017, 16:08:56
Post #7





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 8.02.2017

Ostrzeżenie: (0%)
-----


posortowanie raczej odpada moim zdaniem... nic nie wnosi albo tego nie rozumiem...

odpowiedz kreatiffa także jest błędna ponieważ wysypuje się na tablicy - [1, 3, 2, 1]


zrobiłem coś takiego, sprawdza czy tablica nie ma duplikatów i porównuje je ale... znowu jest problem ponieważ gdy mamy tablice [1,3,2] to spełnia wszystkie te warunki a odpowiedz jest zła ponieważ jeśli zabierzemy 2 lub 3 to ciąg będzie rosnący... a on daje false, ponieważ nie ma duplikatów i raz znajduje większy poprzdeni wiersz... niby to proste ale nie za proste dla mnie...



  1. function almostIncreasingSequence($sequence) {
  2. $t = $sequence;
  3. $j = count($sequence);
  4.  
  5.  
  6.  
  7. for ($i=0; $i<$j-1; $i++) {
  8. $a[$i] = $t[$i];
  9. $b[$i] = $t[$i+1];
  10.  
  11. $c[$i] = ($a[$i] >= $b[$i]);
  12. }
  13. $e = count(array_filter($c));
  14. $f = count(array_unique($t));
  15. $g = $f == $j;
  16. if ($e >= 1 OR $g = true) {
  17. return false;
  18. } else {
  19. return true;
  20. }
  21. }


Ten post edytował hunter777 6.11.2017, 16:12:10
Go to the top of the page
+Quote Post
sabat24
post 6.11.2017, 16:12:15
Post #8





Grupa: Zarejestrowani
Postów: 175
Pomógł: 26
Dołączył: 13.09.2007
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


Sortowanie odpada, gdyż?
Go to the top of the page
+Quote Post
hunter777
post 6.11.2017, 19:48:17
Post #9





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 8.02.2017

Ostrzeżenie: (0%)
-----


Poniewaz sortowanie zakłamuje tablice. Zalozmy, że posiadamy tablice [1,5,2,4,3] to sort zrobi [1,2,3,4,5] i wyjdzie nam true a powinno false.
Go to the top of the page
+Quote Post
sabat24
post 6.11.2017, 20:23:19
Post #10





Grupa: Zarejestrowani
Postów: 175
Pomógł: 26
Dołączył: 13.09.2007
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


Myślałem, że chcesz osiągnąć coś innego na początku. Zobacz ten kod:

  1. class Sequences {
  2. public function almostIncreasingSequence(array $sequence) {
  3. $j = count($sequence);
  4. for($i = 0; $i < $j; $i++) {
  5. $subsequence_to_check = $sequence;
  6. array_splice($subsequence_to_check, $i, 1);
  7. $is_sequence_increasing = $this->_isSequenceIncreasing($subsequence_to_check);
  8. if ($is_sequence_increasing === TRUE) return $i;
  9. }
  10. return FALSE;
  11. }
  12.  
  13. private function _isSequenceIncreasing(array $sequence) {
  14. $j = count($sequence);
  15. if ($j === 0) return FALSE;
  16. for($i = 0; $i < $j - 1; $i++) {
  17. if ($sequence[$i] >= $sequence[($i + 1)]) return FALSE;
  18. }
  19. return TRUE;
  20. }
  21. }
  22.  
  23. $sequence = new Sequences();
  24. $result = $this->almostIncreasingSequence([1,5,2,4,3]);
  25.  


Zwraca FALSE jeśli się nie da uzyskać ciągu albo indeks, jaki należy usunąć, by otrzymać ciąg rosnący - może zwrócić 0. Też kwestia co powinno zwracać w przypadku przekazania ciągu 1 elementowego albo 2 elementowego, ale to już sobie możesz obsłużyć.

Ten post edytował sabat24 6.11.2017, 20:26:06
Go to the top of the page
+Quote Post
hunter777
post 6.11.2017, 20:50:16
Post #11





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 8.02.2017

Ostrzeżenie: (0%)
-----


Bede testował ten kod - dziekuje.

Coś takze jest nie tak ze składnia chyba ale nie wiem co ponieważ teraz powinien na ciągu[1,2,1,2] dać false ponieważ nie ma unikalnego ciągu a daje mi true i już zgłupiałem sad.gif

  1. function almostIncreasingSequence($sequence) {
  2. $t = $sequence;
  3. $j = count($sequence);
  4.  
  5.  
  6.  
  7. for ($i=0; $i<$j-1; $i++) {
  8. $a[$i] = $t[$i];
  9. $b[$i] = $t[$i+1];
  10.  
  11. $c[$i] = ($a[$i] >= $b[$i]);
  12. }
  13. $e = count(array_filter($c));
  14. $f = count(array_unique($t));
  15. $g = $f == $j;
  16. if (($g = false) or ($e > 1)) {
  17. return false;
  18. } else {
  19. return true;
  20. }
  21. }
  22.  
Go to the top of the page
+Quote Post
trzczy
post 7.11.2017, 08:10:28
Post #12





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

Ostrzeżenie: (0%)
-----


Może to
  1. <?php
  2. function testAsc($array) {
  3. $memory=null;
  4. foreach($array as $member) {
  5. if ($memory)if($member<=$memory)return false;
  6. $memory=$member;
  7. }
  8. return true;
  9. }
  10.  
  11. function solution($array) {
  12. for($i=0;$i<count($array);$i++) {
  13. $currentArray=array_filter($array, function($index) use($i) {
  14. return $i != $index;
  15. }, ARRAY_FILTER_USE_KEY);
  16. if(testAsc($currentArray)) return implode($currentArray) . "\n";
  17. }
  18. return 'nie da sie' . "\n";
  19. }
  20.  
  21. echo solution([1, 2, 3, 4]);//234
  22. echo solution([1, 7, 7, 4]);//nie da sie
  23. echo solution([1, 7, 2, 4]);//124

https://3v4l.org/2CZ2N

Ten post edytował trzczy 7.11.2017, 08:15:17
Go to the top of the page
+Quote Post
hunter777
post 8.11.2017, 13:38:54
Post #13





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 8.02.2017

Ostrzeżenie: (0%)
-----


kolejna próba rozwiązania poniżej:

  1. function almostIncreasingSequence($sequence) {
  2. $t = $sequence;
  3. $j = count($sequence);
  4. // $s= sort($t);
  5.  
  6.  
  7.  
  8. for ($i=0; $i<$j; $i++) {
  9. $a[$i] = $t[$i];
  10. $b[$i] = $t[$i+1];
  11.  
  12. if (($b[$i] != null) and ($a[$i] >= $b[$i])) {
  13. unset($a[$i]);
  14.  
  15. }
  16. }
  17. $d = $a;
  18. $e = array_unique($d);
  19. $f = $a == $e;
  20. $k = $a;
  21. $l = sort($k);
  22. $m = $a == $k;
  23.  
  24.  
  25. if (($a > 1) and ($f = false) and ($m = false)) {
  26.  
  27. return false;
  28. } else
  29. {
  30. return true;
  31. }
  32. }


próbuję to teraz zrobić sam jak powyżej, ale coś mi to nie wychodzi, można w ogóle dać 3 warunki do if?

chciałem wyeliminować liczby w których większa liczba poprzedzająca występuje więcej niż 1 raz($a > 1)
i
ciąg jest unikalny czyli nie mamy powtórzeń liczb ($f = false)
i
na koniec mamy to czy tablica jest posortowana ponieważ wtedy też nie da się zrobić rosnącego zbioru ($m = 1)
ale gdy kiedyś uczyłem się o logice to nie kojarzę 3 zmiennych tylko dwie...
może ktoś doświadczony mnie naprowadzi... sad.gif chyba nici z mojego programowania jak takie zadanie mnie wykańcza sad.gif

Ten post edytował hunter777 8.11.2017, 13:40:17
Go to the top of the page
+Quote Post
trueblue
post 8.11.2017, 14:29:02
Post #14





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


W linii 25 są dwa błędy.


--------------------
Go to the top of the page
+Quote Post
hunter777
post 8.11.2017, 21:16:14
Post #15





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 8.02.2017

Ostrzeżenie: (0%)
-----


Chodzi o to iż zliczam a zamiast pętle? I mają być or a nie and?

I tak niestety jest źle pomimo różnych zmian...
Go to the top of the page
+Quote Post
trueblue
post 8.11.2017, 21:19:45
Post #16





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Tam porównujesz czy przypisujesz?


--------------------
Go to the top of the page
+Quote Post
hunter777
post 9.11.2017, 15:16:04
Post #17





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 8.02.2017

Ostrzeżenie: (0%)
-----


tak powinno być ==, dziękuję
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 26.04.2024 - 23:26