4

現在、私はと呼ばれるPHPクラスを持っていますCollection。配列を使用して、一意のオブジェクトのセットを保持します。それらは異なるメモリ アドレスを持っているという意味ではなく (明らかに違いますが)、セット内に同等のオブジェクトがないという意味で一意です。

私はSplObjectStorage、配列よりも速度が大幅に向上し、Collectionクラスよりも保守が容易である可能性があることについて読んでいます。私の問題は、SplObjectStorageそれ自体が等価性ではなく、同一性のみに関係していることです。例えば:

class Foo {
  public $id;

  function __construct($int){
    $this->id=$int;
  }

  function equals(self $obj){
    return $this->id==$obj->id;
  }
}

$f1a = new Foo(1);
$f1b = new Foo(1);//equivalent to $f1a
$f2a = new Foo(2);
$f2b = $f2a; //identical to $f2a

$s=new SplObjectStorage;
$s->attach($f1a);
$s->attach($f1b);//attaches (I don't want this)
$s->attach($f2a);
$s->attach($f2b);//does not attach (I want this)

foreach($s as $o) echo $o->id; //1 1 2, but I wish it would be 1 2

したがって、オブジェクトの等価性によって制限されるようにサブクラス化する方法について考えてきましたが、これまでのところ、オブジェクトを「等価署名」に設定SplObjectStorageする必要があり、見つけるまでデータ構造をループする必要があるようです一致する値。attach()$data

例えば:

class MyFooStorage extends SplObjectStorage {

  function attach(Foo $obj){
    $es=$obj->id;
    foreach($this as $o=>$data) {//this is the inefficient bit
      if($es==$data) return;
    }
    parent::attach($obj);
    $this[$obj]=$es;
  }
}

より良い方法はありますか?

4

1 に答える 1

3

平等を定義する唯一のものが別のオブジェクトに関連している場合、私はあなたが望むことは不可能であると恐れています。考えてみてください。すべてのオブジェクトをチェックしない限り、オブジェクトがすでに配列に含まれていると判断する方法はありません。そのため、何があってもO(n)の複雑さがあります。

ただし、等式を絶対値にすると、これは可能です。そのためには、各オブジェクトのハッシュ値を生成する必要があります。2つのオブジェクトは、ハッシュが等しい場合にのみ等しくなります。それができたら、HashMapを使用してO(1)を実現できます。

内部的には、これは、オブジェクトのアドレスをハッシュ値として使用することにより、SplObjectStorageが行うこととまったく同じです。

于 2011-03-04T21:26:12.830 に答える