Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Jak to ugryźć , zbiór liczb i szukanie czy część suma części z nich da daną liczbę.
Forum PHP.pl > Forum > PHP
icemanwlkp
Witam , mam taki problem . Jest tabela z liczbami z dwoma miejscami po przecinku . I teraz mam napisać skrypt który wyłowi liczby z tej tablicy których suma da daną liczbę , lub stwierdzić iż nie ma takiej kombinacji .
Jak zabrać się do takiego skryptu ? Jakieś pomysły podpowiedzi ?

Przykład:

  1. $liczby = Array("2.56","1.74","1.69","2.44","1.53","2.45","1.21","2.62","2.33","1.21","2.69","3.24","1.87","1.75","2.02","1.80","1.78");
  2. $szukana = '20.00';
nospor
Tworzysz wszelkie mozliwe kombinacje sum i sprawdzasz ktora daje to czego szukasz
Oczywiscie mozesz to zoptymalizowac, np. gdy dana suma jest juz wieksza, to nie dokladasz kolejnych kombinacji do niej.
icemanwlkp
I nadal mam pustkę w głowie jak to rozpisać w php ? Zwłaszcza, że może to być tylko część liczb z tablicy .
nospor
Nie bardzo rozumiem. Nie wiesz jak zrobic wszystkie mozliwe kombinacje ze zbioru?
Pyton_000
Śmierdzi mi tu Amino, czyż nie ? biggrin.gif
Crozin
1. Na początek przemnóż sobie wszystkie liczby przez 100 by operować na liczbach całkowitych - ewentualnie przy wyświetlaniu podziel ponownie wszystko przez 100. Porównywanie liczb zmiennoprzecinkowych jest problematyczne - https://www.google.pl/search?q=what+every+p...me&ie=UTF-8
2. http://stackoverflow.com/questions/4632322...ach-a-given-sum
nospor
@Crozin niestety autor tematu nie oczekuje algorytmu tylko gotowego kodu w php.
Nawet jak dostal gotowce od markonix to ma problem bo tam sa teksty a nie liczby.

Tak wiec albo dajcie gotowca albo oszczedzcie sobie czasu na postowanie sad.gif

@Pyton rozwin watek biggrin.gif

@iceman
to jest bardzo mile
http://www.php.net/manual/en/function.shuffle.php#90615
zamiast tekstow wstaw liczby i masz rozwiazanie... no procz sum. Ale kurka, cos moglbys zrobic samodzielnie
lukaskolista
Nie wiem czy o to chodzi, tak bardzo ale to bardzo na szybko:
  1. <?php
  2.  
  3. $numbers = [1.11, 2.22, 3.33];
  4. $expectedSum = 5.55;
  5.  
  6. foreach ($numbers as $firstKey => $firstNumber) {
  7. foreach ($numbers as $secondKey => $secondNumber) {
  8. if ($firstKey !== $secondKey && (string) ($firstNumber + $secondNumber) == (string)$expectedSum) {
  9. echo 'Found: '.$firstNumber.' and '.$secondNumber;
  10. }
  11. }
  12. }
Pyton_000
@nospor chodziło o to że Amino jakiś czas temu w zupkach dawał kwoty. I jak się uzbierało np. 100 to można było wymienić na kasę smile.gif Warunkiem było uzyskanie pełnych kwot. a problem polegał na tym że właśnie były takie śmieszne sumy i zawsze albo brakowało troszkę albo za dużo biggrin.gif
nospor
@lukaskolista przeciez twoje rozwiazanie sumuje tylko dwie liczby

@Pyton biggrin.gif
icemanwlkp
Nie do Amino ,ale księgowa mnie meczy odnośnie takich dupereli.

Napisłem tyle ,ale tylko nei wiem czy włąściwie no i nie wiem jak wyświetlić użyte liczby tu mi nie znajduje wyniku 2000 .

  1. $tabelka = Array(256,174,169,244,153,245,121,262,233,121,269,324,187,175,202,180,178);
  2. $tabelka2 = $tabelka;
  3.  
  4. for ($x=0;$x<count($tabelka);$x++)
  5. {
  6. $nsuma = 0;
  7. for ($y=$x+1;$y<count($tabelka2);$y++)
  8. {
  9. $suma = $tabelka[$x]+$tabelka2[$y];
  10. $nsuma += $tabelka[$x]+$tabelka2[$y];
  11. echo $suma.'<br>';
  12. echo $nsuma.'<br>';
  13. }
  14. }
nospor
Dostales gotowe kody, szczegolnie fajny ten co ci podalem jako ostatni.
To co napisales ma sie srednio do twojego problemu
markonix
Weź mój przykład, zamiast tekstu rób tablice, będziesz miał tablicę wszystkich możliwych kombinacji bez powtórzeń, potem tylko foreach + break w momencie znalezienia pierwszej kombinacji, która spełnia warunek tej sumy.
Jeżeli foreach przeleci bez break oznacza to brak.
icemanwlkp
Cosik mi nie wychodzi , kurka ... wyniki , są ale jakby sklejone do siebie

  1. $array = array(1,2,3,4,5,6,7,8,9);
  2.  
  3. function depth_picker($arr, $temp_string, &$collect) {
  4. if ($temp_string != "")
  5. $collect []= $temp_string;
  6.  
  7. for ($i=0; $i<sizeof($arr);$i++) {
  8. $arrcopy = $arr;
  9. $elem = array_splice($arrcopy, $i, 1);
  10. if (sizeof($arrcopy) > 0) {
  11. depth_picker($arrcopy, $temp_string[]=$elem[0], $collect);
  12. } else {
  13. $collect []= $temp_string[]=$elem[0];
  14. }
  15. }
  16. }
  17.  
  18. $collect = array();
  19. depth_picker($array, "", $collect);
  20. print_r($collect);
nospor
Wlasnie sprawdzilem przyklad do ktorego cie odeslalem. Dziala bez zadnych przerobek. Tylko skopiowac i wkleic do siebie. Widze lubisz sobie na sile utrudniac zycie
icemanwlkp
Dla 5 liczb działa , powyżej nie wywala już nic , gdzie tkwi problem ?


  1. function power_perms($arr) {
  2.  
  3. $power_set = power_set($arr);
  4. $result = array();
  5. foreach($power_set as $set) {
  6. $perms = perms($set);
  7. $result = array_merge($result,$perms);
  8. }
  9. return $result;
  10. }
  11.  
  12. function power_set($in,$minLength = 1) {
  13.  
  14. $count = count($in);
  15. $members = pow(2,$count);
  16. $return = array();
  17. for ($i = 0; $i < $members; $i++) {
  18. $b = sprintf("%0".$count."b",$i);
  19. $out = array();
  20. for ($j = 0; $j < $count; $j++) {
  21. if ($b{$j} == '1') $out[] = $in[$j];
  22. }
  23. if (count($out) >= $minLength) {
  24. $return[] = $out;
  25. }
  26. }
  27.  
  28. //usort($return,"cmp"); //can sort here by length
  29. return $return;
  30. }
  31.  
  32. function factorial($int){
  33. if($int < 2) {
  34. return 1;
  35. }
  36.  
  37. for($f = 2; $int-1 > 1; $f *= $int--);
  38.  
  39. return $f;
  40. }
  41.  
  42. function perm($arr, $nth = null) {
  43.  
  44. if ($nth === null) {
  45. return perms($arr);
  46. }
  47.  
  48. $result = array();
  49. $length = count($arr);
  50.  
  51. while ($length--) {
  52. $f = factorial($length);
  53. $p = floor($nth / $f);
  54. $result[] = $arr[$p];
  55. array_delete_by_key($arr, $p);
  56. $nth -= $p * $f;
  57. }
  58.  
  59. $result = array_merge($result,$arr);
  60. return $result;
  61. }
  62.  
  63. function perms($arr) {
  64. $p = array();
  65. for ($i=0; $i < factorial(count($arr)); $i++) {
  66. $p[] = perm($arr, $i);
  67. }
  68. return $p;
  69. }
  70.  
  71. function array_delete_by_key(&$array, $delete_key, $use_old_keys = FALSE) {
  72.  
  73. unset($array[$delete_key]);
  74.  
  75. if(!$use_old_keys) {
  76. $array = array_values($array);
  77. }
  78.  
  79. return TRUE;
  80. }
  81.  
  82. $in = array("256","174","169","244","153","245","121","262","233","121","269","324","187","175","202","180","178");
  83. $power_perms = power_perms($in);
  84.  
  85. foreach ($power_perms as $p)
  86. {
  87. print_r($p);
  88. echo '<br>';
  89. }
nospor
MI tam dziala do 12. Potem sie wywala spowodu pamieci. Zwieksz pamiec smile.gif
icemanwlkp
ini_set("memory_limit",-1); wstawiłem realnie przy 128 GB pamięci , ile liczb mogę brać pod uwagę ? rozumiem, że 1000 liczb to 1000 do potęgi 1000 , czyli tragicznie to będzie długo się robić i raczej zapcha pamięć .
nospor
Dlatego w pierwszym poscie wspomnialem o optymalizacji takich skryptow, by nie szukaly dalej gdy suma zostanie osiagnieta. To oszczedzi sporo czasu i pamieci.
Crozin w swoim poscie zapodal ciekawego linka. Niestety nie ma kodu w php. Trzeba przerobic.
icemanwlkp
No w sumie tworzy się sporo tablic zbędnych , ale to nie realne przy 10 000 licz gdzie może się okazać ,że nie ma właściwej konfiguracji , czyli skrypt przeleci po wszystkim , jedynie można by określić wstępnie minimalną i maksymalną liczbę liczb jakie muszą być w tablicy
nospor
Cytat
że nie ma właściwej konfiguracji
Nie ze nie ma wlasciwej, ale gdy wszystkie sumy sa ponizej zakladanej. Drobna roznica. Tylko w tym przypadku, gdy wszystkie sumy sa mniejsze to skrypt przeleci wszystkie kombinacje
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.
Invision Power Board © 2001-2025 Invision Power Services, Inc.