• vue2+循环链表解决一个历史趣题


    最近楼主在看麦克米伦的《数据结构与算法JavaScript描述》一书,其中链表有个习题挺有趣,内容是这样的:

    传说在公元1世纪的犹太战争中,犹太历史学家弗拉维奥·约瑟夫斯和他的40个同胞被罗马士兵包围。犹太士兵决定宁可自杀也不做俘虏,于是商量出了一个自杀方案。他们围成一个圈,从一个人开始,数到第三个人时将第三个人杀死,然后再数,直到杀光所有人。约瑟夫和另外一个人决定不参加这个疯狂的游戏,他们快速地计算出了两个位置,站在那里得以幸存。写一段程序将n个人围成一圈,并且第m个人会被杀掉,计算一圈人中哪两个人最后会存活。使用循环链表解决该问题

    于是决定实现一下:全文源码如下

    <template>
      <div id="testActivity" class="main">
        <el-form :model="form" class="demo-form-inline">
          <el-form-item label="">
            <el-input v-model="form.value" placeholder="请输入要排队的序列,以逗号分隔" clearable @input="inputChange" />
          </el-form-item>
          <el-form-item label="">
            <el-input v-model="form.delValue" placeholder="请输入从第几个开始删" clearable @input="delValueChange" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="onSubmit">计算</el-button>
          </el-form-item>
          <p v-if="result">剩下的是:{{ result }}</p>
        </el-form>
      </div>
    </template>
    
    <script>
    var person = [] // 存放队列
    var len = 3 // 从第几个开始删,默认第3个
    // 替换中文逗号
    function ReplaceChina(obj) {
      while (obj.indexOf(',') !== -1) {
        obj = obj.replace(/,/ig, ',')
      }
      return obj
    }
    // LList类提供了对链表进行操作的方法。该类的功能包括插入删除节点、在列表中查找给定的值
    function LList() {
      this.head = new Node('head')
      this.head.next = this.head
      this.find = find
      this.insert = insert
      this.display = display
      this.findPrevious = findPrevious
      this.remove = remove
    }
    // Node类包含两个属性:element用来保存节点上的数据,next用来保存指向下一个节点的链接
    function Node(element) {
      this.element = element
      this.next = null
    }
    // 从链表中删除节点时,需要先找到待删除节点前面的节点。找到这个节点后,修改它的next属性,使其不再指向待删除节点,而是指向待删除节点的下一个节点。
    function findPrevious(item) {
      var currNode = this.head
      while (currNode.next.element !== item) {
        currNode = currNode.next
      }
      return currNode
    }
    // 显示结果
    function display() {
      var currNode = this.head
      const arr = []
      while (currNode.next.element !== 'head') {
        arr.push(currNode.next.element)
        currNode = currNode.next
      }
      return arr
    }
    // 辅助方法find(),该方法遍历链表,查找给定数据
    function find(item) {
      var currNode = this.head
      while (currNode.element !== item) {
        currNode = currNode.next
      }
      return currNode
    }
    // 插入一个节点
    // 将新节点的next属性设置为“后面”节点的next属性对应的值。然后设置“后面”节点的next属性指向新节点
    function insert(newElement, item) {
      var newNode = new Node(newElement)
      var current = this.find(item)
      newNode.next = current.next
      current.next = newNode
    }
    
    // 删除方法
    function remove(item) {
      var prevNode = this.findPrevious(item) // 上一个节点
      let nextDel = prevNode.next // 下一个需要删除的节点
      prevNode.next = prevNode.next.next // 删除item节点(把item上一个节点的指针指向item的下一个节点,即删除了item)
      let i = 0
      while (i < len) { // 找到第len个的元素,即下次要删除的节点
        if (nextDel.next.element === 'head') { // 如果到了最开头,则向后移一位,并退出此次循环,并不累计i的值
          nextDel = nextDel.next
          continue
        }
        nextDel = nextDel.next
        i++
      }
      return nextDel // 返回下次要删除的节点
    }
    
    export default {
      name: 'TestActivity',
      data() {
        return {
          form: {
            value: '',
            delValue: ''
          },
          result: '',
          person: []
        }
      },
      mounted() {
      },
      methods: {
        delValueChange(val) {
          len = Number(val) // 格式化为数值类型
        },
        inputChange(val) {
          person = val.split(',')// 把字符串存入队列数组
        },
        // 点击计算按钮,开始计算
        onSubmit() {
          // 一些校验
          if (!this.form.value || !this.form.delValue) {
            this.$alertMessage('error', '请输入必填项')
            return
          }
          const timesString = ReplaceChina(this.form.value) // 替换中文分号
          person = timesString.split(',')
          if (this.form.delValue > person.length) {
            this.$alertMessage('error', '开始删除的位置不能大于队列总数')
            return
          }
    
          const first = 'head'
          let i = 0
          const cities = new LList() // 实例化一个实例
          // 把person数组放入cities链表
          while (i < person.length) {
            if (i === 0) {
              cities.insert(person[0], first)
            } else {
              const j = i - 1
              cities.insert(person[i], person[j])
            }
            i++
          }
          // 显示当前排队情况
          cities.display()
          const length = len - 1
          let delName = person[length] // 当前要删掉的节点
          // 循环去删掉节点,留下最后2个
          while (person.length > 2) {
            delName = cities.remove(delName).element
            person = cities.display()
            this.result = person.join(',')// 最后的结果
          }
        }
      }
    }
    </script>
    <style  scoped>
    .main{
      padding: 20px ;
    }
    </style>
    

    因为只是简单实现一下功能,所以代码还有很多不完善的地方,大佬轻喷哈~  

  • 相关阅读:
    PHP的Tag标签
    PHP 常量
    MySQL知识点链接
    Codeforces Round #593 (Div. 2)D(螺旋形模拟)
    【PAT甲级】1060 Are They Equal (25 分)(需注意细节的模拟)
    【PAT甲级】1059 Prime Factors (25 分)
    【PAT甲级】1058 A+B in Hogwarts (20 分)
    【PAT甲级】1057 Stack (30 分)(分块)
    【PAT甲级】1056 Mice and Rice (25 分)
    Atcoder Grand Contest 039C(容斥原理,计数DP)
  • 原文地址:https://www.cnblogs.com/zhangxusong/p/14108922.html
Copyright © 2020-2023  润新知