【问题标题】:Can I use class methods inside factory constructor via Dart我可以通过 Dart 在工厂构造函数中使用类方法吗
【发布时间】:2022-11-09 21:24:23
【问题描述】:

我有以下代码使用 Dart 创建 PriortyQueue 结构。但是由于我不能在构造函数或工厂构造函数中使用 heapify 函数,所以我不能用现有的 List 集初始化 PQ。有人可以指导我并向我展示如何在创建 PQ 实例时使用 heapify 以便我可以使用现有列表对其进行初始化吗?此外,如果您对做这样的事情有任何其他建议,也请帮助我。谢谢你

class PriorityQueue<T extends Comparable<T>> {
  List<T?> _tree;

  PriorityQueue._(List<T?> tree) : _tree = tree;

  factory PriorityQueue([List<T>? array]) {
    List<T?> newArray = [null, ...array ?? []];
    // ignore: todo
    //TODO: missing heapify
    return PriorityQueue._(newArray);
  }

  void insert(T node) {
    _tree.add(node);
    _swim(_tree.length - 1);
  }

  T getTop() {
    _swap(1, _tree.length - 1);
    T top = _tree.removeLast() as T;
    _sink(1);

    return top;
  }

  List<T> _heapify(List<T> array) {
    int sinkNodeIndex = (array.length - 1) ~/ 2;

    while (sinkNodeIndex >= 1) {
      _sink(sinkNodeIndex);
      sinkNodeIndex--;
    }
  }

  void _sink(int nodeIndex) {
    int leftChildIndex = nodeIndex * 2;
    int rightChildIndex = leftChildIndex + 1;
    int minNodeIndex = leftChildIndex;

    // index can be unreachable
    T? leftChild =
        leftChildIndex >= _tree.length ? null : _tree[leftChildIndex];
    T? rightChild =
        rightChildIndex >= _tree.length ? null : _tree[rightChildIndex];

    if (leftChild == null) {
      return;
    }

    if (rightChild != null && leftChild.compareTo(rightChild) > 0) {
      minNodeIndex = rightChildIndex;
    }

    if ((_tree[minNodeIndex] as T).compareTo(_tree[nodeIndex] as T) < 0) {
      _swap(nodeIndex, minNodeIndex);
      _sink(minNodeIndex);
    }
  }

  void _swim(int nodeIndex) {
    if (nodeIndex <= 1) return;

    int parentIndex = nodeIndex ~/ 2;

    if ((_tree[nodeIndex] as T).compareTo(_tree[parentIndex] as T) < 0) {
      _swap(nodeIndex, parentIndex);
      _swim(parentIndex);
    }
  }

  void _swap(int i, int j) {
    T temp = _tree[i] as T;
    _tree[i] = _tree[j];
    _tree[j] = temp;
  }

  @override
  String toString() {
    return _tree.toString();
  }
}

【问题讨论】:

    标签: dart constructor


    【解决方案1】:

    我会制作所有的辅助功能。 _heapify_sink/_swim,甚至_swap,都是以列表为参数的静态函数。 然后您可以在任何地方使用它们,包括在工厂构造函数内部。

    或者,您可以将构造函数更改为返回:

      return PriorityQueue._(newArray).._heapify();
    

    这将创建PriorityQueue 对象,然后在其上调用_heapify 方法,然后返回值。

    (我也会让_tree 具有List&lt;T&gt; 类型,而不是在开头插入额外的null。从索引中添加/减去1 比转换为T 更有效。)

    【讨论】:

    • return PriorityQueue._(newArray).._heapify();这个实现似乎效率更高,但我认为我们需要公开 heapify 才能像这样使用它。return PriorityQueue._(newArray)..heapify();
    【解决方案2】:

    我最终做了 Irn 的第一个建议。但是当我做静态函数时,他们丢失了类的类型,所以我需要为每个函数指定。此外,制作 List<T?> 而不是 List 最终导致我与编译器作斗争。

    class PriorityQueue<T extends Comparable<T>> {
      List<T?> _tree;
    
      PriorityQueue._(List<T?> tree) : _tree = tree;
    
      factory PriorityQueue([List<T>? array]) {
        List<T?> newArray = [null, ...array ?? []];
        _heapify(newArray);
    
        return PriorityQueue._(newArray);
      }
    
      bool get isNotEmpty {
        return _tree.isNotEmpty;
      }
    
      void insert(T node) {
        _tree.add(node);
        _swim(_tree, _tree.length - 1);
      }
    
      void insertMultiple(List<T> array) {
        for (var element in array) {
          insert(element);
        }
      }
    
      T? removeTop() {
        if (_tree.length == 1) return null;
    
        _swap(_tree, 1, _tree.length - 1);
        T top = _tree.removeLast() as T;
        _sink(_tree, 1);
    
        return top;
      }
    
      void removeAll() {
        _tree = [null];
      }
    
      static void _heapify<T extends Comparable<T>>(List<T?> array) {
        int sinkNodeIndex = (array.length - 1) ~/ 2;
    
        while (sinkNodeIndex >= 1) {
          _sink(array, sinkNodeIndex);
          sinkNodeIndex--;
        }
      }
    
      static void _sink<T extends Comparable<T>>(List<T?> tree, int nodeIndex) {
        int leftChildIndex = nodeIndex * 2;
        int rightChildIndex = leftChildIndex + 1;
        int minNodeIndex = leftChildIndex;
    
        T? leftChild = leftChildIndex >= tree.length ? null : tree[leftChildIndex];
        T? rightChild =
            rightChildIndex >= tree.length ? null : tree[rightChildIndex];
    
        if (leftChild == null) {
          return;
        }
    
        if (rightChild != null && leftChild.compareTo(rightChild) > 0) {
          minNodeIndex = rightChildIndex;
        }
    
        if ((tree[minNodeIndex] as T).compareTo(tree[nodeIndex] as T) < 0) {
          _swap(tree, nodeIndex, minNodeIndex);
          _sink(tree, minNodeIndex);
        }
      }
    
      static void _swim<T extends Comparable<T>>(List<T?> tree, int nodeIndex) {
        if (nodeIndex <= 1) return;
    
        int parentIndex = nodeIndex ~/ 2;
    
        if ((tree[nodeIndex] as T).compareTo(tree[parentIndex] as T) < 0) {
          _swap(tree, nodeIndex, parentIndex);
          _swim(tree, parentIndex);
        }
      }
    
      static void _swap<T extends Comparable<T>>(List<T?> tree, int i, int j) {
        T temp = tree[i] as T;
        tree[i] = tree[j];
        tree[j] = temp;
      }
    
      @override
      String toString() {
        return _tree.toString();
      }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-16
      相关资源
      最近更新 更多