• JavaScript 算法 1_4 union-find 算法


    /**
     * quick-find 算法, find 操作速度很快, find 只需要返回 id[X],
     * 但它无法处理大型问题, 因为它在每一次 union 时都要扫描整个数组
     */
    
    const inquirer = require("inquirer");
    
    class UF{
      constructor(N) {
        // count 代表分量数量
        let count = N;
        // id 代表分量id, 以触点作为索引;
        // 这样创建的数组内容全空, 不能使用 map
        let id = new Array(N);
        for (let i = 0; i < N; i++) {
          id[i] = i;
        }
        this.getId = ()=>id;
    
        // 方法区
        // 获取私有变量, 连通分量的数量
        this.getCount = ()=> count;
    
        // 如果 p 和 q 存在于同一个分量中则返回 true
        this.connected = (p,q ) => this.find(p) === this.find(q);
    
        // 找到 p 所在的分量的标识符
        // quick-find 算法
        this.find  = p => id[p];
    
        // 在 p 和 q 之间添加一条连接
        this.union = (p, q) => {
          const pID = this.find(p);
          const qID = this.find(q);
    
          if(pID === qID) return;
    
          id = id.map(value => {
            if (value === pID){
              return qID;
            }else {
              return value;
            }
          })
          count--;
        }
      }
    }
    
    const uf = new UF(10);
    
    // 安装 npm install inquirer, 提供了很好的从命令行接收输入的解决方案
    const question1 = {
        type: 'number',
        name: 'count',
        message: "触点有多少个? 
    "
    }
    
    const question2 = {
      type: 'input',
      name: 'points',
      filter(input){
        return input.split(' ').map(value => Number(value))
      },
    }
    // 输入触手个数
    const prompt1 = inquirer.createPromptModule();
    // 连接位置
    const prompt2 = inquirer.createPromptModule();
    
    
    prompt1(question1)
        .then(answers => {
          console.log(`触点有${answers.count}个`)
          autoInput();
        })
        .catch(e =>{
          console.error(e)
        });
    
    // 输入连接位置
    function autoInput(){
      prompt2(question2)
          .then(answers =>{
            console.log(answers)
            if(answers.points.length !== 1){
              let p = answers.points[0];
              let q = answers.points[1];
              console.log(p, q)
              if(!uf.connected(p, q)) {
                uf.union(p, q);
              }
              autoInput();
            }else {
              console.log(uf.getId(), 'id')
              console.log(uf.getCount(), '基数');
              console.log(uf.connected(5, 0), '5和0 是否连接')
              console.log(uf.connected(5, 2), '5和2 是否连接')
            }
          })
          .catch(e => {
            console.log(e);
          })
    }
    
  • 相关阅读:
    fedora-coreos 试用podman
    博客主题更新了
    C stdarg.h:可变参数va_list、va_arg等宏的使用及原理简介
    静态、动态链接库的生成及使用
    notfastjson项目介绍
    The ANSI C Programming Language:C语言预处理机制
    语法分析:LL(1)语法分析的实现及扩展的巴科斯范式
    语法分析:LL(1)分析
    计算机系统基础:计算机系统概述
    计算机系统基础:数据的表示和存储
  • 原文地址:https://www.cnblogs.com/xiaxiangx/p/14314884.html
Copyright © 2020-2023  润新知