Yöneticileriniz PHP ilk 5 değerleri tutulması

7 Cevap php

Ben puan alan filmlerin n numara geçer PHP küçük bir algoritma yazıyorum ve ilk 5 depolar. Ben bir veri dosyası okuma değilim, ama bir akışından yüzden sadece sipariş edemez Reytinge göre filmleri.

Benim soru akışı okumak gibi ilk 5 puan filmleri izlemek için en verimli yolu nedir? Şu anda aşağıdakileri yapın:

  1. Iki anahtar film [] [adı] ve filmler ile, (filmler [] adlı bir diziye) 5 filmlerde Oku [] [rating]
  2. Filmleri dizi Sipariş [rating]) (array_multisort kullanarak (en yüksek rating şimdi filmlerde oturur [4])
  3. Sonraki filmde Oku
  4. Bu yeni film oylaması> filmler [0] [rating] sonra bu yeni film ile [0] filmler değiştirebilirsiniz
  5. Yeniden sipariş listesi
  6. Bitirene kadar 3-5 tekrarlayın

Benim yöntem çalışır, ama her okuduktan sonra listede bir sıralama gerektirir. Ben bu çoğunlukla ben array_multisort kullanmak her zaman () Ben sadece sıralamak için dizin oluşturmak için 5 filmler döngüsü için yapmanız gereken aslında pahalı bir yöntem olduğuna inanıyorum. Herkes bu yaklaşım daha iyi bir yol önerebilirsiniz?

7 Cevap

Bağlantılı listeler burada çalışmak istiyorum.

Bağlantılı liste oluşturmak doğru sırayla zincirleri ilk 5 film olduğunu. Her yeni film için, sadece zincirin sonunda başlayacak ve film daha yüksek bir derece ile tek ve düşük bir derece ile biri arasında olana kadar yürümek. Daha sonra burada liste halinde bağlantısını yerleştirin. Film kötü daha iyi (ve böylece liste uzun şimdi 6), sadece zincirin son halkasını çıkarın ve geri 5 vardır.

Hayır sıralama, indeksleme.

Sizin algoritma iyi görünüyor. Ben diziler PHP nasıl uygulandığını emin değilim. Bakış bir algoritma noktadan: bir dizi yerine bir yığın kullanın.

Eğer gerçekten sadece yeni bir giriş eklemek gerekir çünkü yeniden sıralama anlamı yok sonra her okudum. Aşağıdaki algoritma kullanın, bu size en iyi hızı elde etmek olasıdır. Bu temelde bir unrolled döngü değil, en güzel kod.

set movies[0..4].rating to -1.
while more movies in stream:
    read in next movie.
    if movie.rating < movies[0].rating:
        next while
    if movie.rating < movies[1].rating:
        movies[0] = movie
        next while
    if movie.rating < movies[2].rating:
        movies[0] = movies[1]
        movies[1] = movie
        next while
    if movie.rating < movies[3].rating:
        movies[0] = movies[1]
        movies[1] = movies[2]
        movies[2] = movie
        next while
    if movie.rating < movies[4].rating:
        movies[0] = movies[1]
        movies[1] = movies[2]
        movies[2] = movies[3]
        movies[3] = movie
        next while
    movies[0] = movies[1]
    movies[1] = movies[2]
    movies[2] = movies[3]
    movies[3] = movies[4]
    movies[4] = movie

Sonunda, filmler sizin sınıflandırılmaktadır listesi var. 5 daha az varsa, bu diğerleri -1 derece olacak böylece onlar geçersiz olduğunu bileceksiniz. Bu gerçek bir film üzerinde değerlendirme sıfır veya daha yüksek olduğunu varsayarak ama onlar değil iseniz değerlerini ayarlayabilirsiniz.

Eğer fazla 5 film için ayarlamanız gerekiyorsa, bunu yapabilirsiniz. En iyi bahis tekrar döngü rulo olacaktır. Bir noktada, ancak, bu yöntemi kullanmak daha bunu sıralamak için daha verimli hale gelecek. Bu yöntem, küçük bir veri kümesi için sadece gerçekten iyi.

Benim yöntem çalışır, ama her okuduktan sonra listede bir sıralama gerektirir.

Eğer oylaması whos yeni bir film bulmak sonra hayır o, sadece bir tür gerektirir yok olduğunu> filmler [0] [derece].

Bu yöntem benim için verimli görünüyor. Sadece sıralama bazen daha az işlemek daha fazla film olacağını ilk 5 için yeni bir giriş var, ne zaman.

Liste ne kadar büyük? Ben bellekte tüm listesini tutmak ve sonunda onu sıralamak için bir seçenek değil tahmin ediyorum?

İşte ben yapardım:

// let’s say get_next_movie () returns array with 'rating' and 'name' keys

while ($m = get_next_movie ()) {

  $ratings[$m['rating']][] = $m['movie'];

  $temp_ratings = $ratings;
  $top5 = array ();
  $rating = 5;
  while (1) {
    if (count ($temp_ratings[$rating])) {
      $top5[] = array_shift ($temp_ratings[$rating]);
    } elseif ($rating > 0) {
      --$rating;
    } else {
      break;
    }
  }

  // $top5 has current top 5 :-)

}

$ Derecelendirme dizi böyle, her bir değerlendirme içinde film dizi var görünüyor:

Array
    (
    [5] => Array
        (
            [0] => Five!
        )

    [3] => Array
        (
            [0] => Three
            [1] => Threeeeee
            [2] => Thr-eee-eee
        )

    [4] => Array
        (
            [0] => FOR
        )
    )

Belki bu yardımcı olabilir.

class TopList {
    private $items = array();
    private $indexes = array();
    private $count = 0;
    private $total = 5;
    private $lowest;
    private $sorted = false;

    public function __construct($total = null) {
    	if (is_int($total))
    		$this->total = $total;

    	$this->lowest = -1 * (PHP_INT_MAX - 1);
    }

    public function addItem($index, $item) {
    	if ($index <= $this->lowest)
    		return;

    	$setLowest = $this->count === $this->total;
    	if ($setLowest) {
    		/* //remove first added
    		$lowestIndex = array_search($this->lowest, $this->indexes);
    		/*/ //remove last added
    		$lowestIndex = end(array_keys($this->indexes, $this->lowest));
    		//*/
    		unset($this->indexes[$lowestIndex], $this->items[$lowestIndex]);
    	} else {
    		++$this->count;
    		$setLowest = $this->count === $this->total;
    	}

    	$this->indexes[] = $index;
    	$this->items[] = $item;
    	$this->sorted = false;

    	if ($setLowest)
    		$this->lowest = min($this->indexes);
    }

    public function getItems() {
    	if (!$this->sorted) {
    		array_multisort($this->indexes, SORT_DESC, $this->items);
    		$this->sorted = true;
    	}
    	return $this->items;
    }
}

$top5 = new TopList(5);
foreach ($movies as $movie) {
    $top5->addItem($movie['rating'], $movie);
}
var_dump($top5->getItems());