当前位置:首页 > 文章列表 > 文章 > 前端 > 打印队列

打印队列

来源:dev.to 2024-12-21 17:09:58 0浏览 收藏

大家好,今天本人给大家带来文章《打印队列》,文中内容主要涉及到,如果你对文章方面的知识点感兴趣,那就请各位朋友继续看下去吧~希望能真正帮到你们,谢谢!

打印队列

代码来临 2024 年第 5 天

第 1 部分

会有秩序!

这将会是一件很酷的事情。

我喜欢添加的警告,即不应考虑未包含在更新中的页面规则。

我对如何解决这个难题有一个模糊的想法。

但是我需要在这里制定我的策略以保持清晰并确保我准备好编写实际代码。

我希望跌跌撞撞地制定策略

这很有趣。我觉得我知道如何以过度检查的方式解决这个问题。

这就是我的想法。

将两个列表中的第一个转换为页码目录,其前面必须有任何/所有页面:

来自此:

47|53
97|13
97|61
...

对此:

{
  47: [53],
  97: [13, 61],
  ...
}

但是我该如何使用它呢?

等等。旋转!!

查看第一个示例页面更新:

75,47,61,53,29

并审查其正确顺序的深入证明......

...让我想到了过于乏味的方法:

find all page ordering rules whose two pages are both in the page update list
find the index of each page
if the first is less than the second
  the order is correct

性能方面的缺点:

  • 这需要遍历每个列表的整套页面顺序规则
  • 似乎是检查所有可能的数字对的任务中的阶乘

不太确定这种方法。

返回我的键对象和“之前”列表。

如果我让对象更全面怎么办:

47|53
97|13
97|61
...

becomes:

{
  47: [ [53], [] ],
  53: [ [], [47] ],
  97: [ [13, 61], [] ],
  13: [ [], [97] ],
  61: [ [], [97] ]
}
  • 第一个嵌套列表列出了必须位于其之前的数字
  • 第二个嵌套列表列出了其后必须出现的数字

理论上(和伪代码):

for each number in the list
  create an ordered list of the previous numbers
    check each one for inclusion in the catalogued list associated with that number
      if they are all in there
        set a flag to true
  create an ordered list of the subsequent numbers
    check each one for inclusion in the catalogued list associated with that number
      if they are all in there
        set a flag to true
  if both flags are true
    number is in the correct order

示例演练:

75

before: []
after: [47,61,53,29]

catalog:
{
  75: [ [29, 47, 53, 61, 13], [97] ]
}

before: empty - success

after: [true, true, true, true]

all true? yes - success

correct order

我绝对认为是时候编写一个至少可以构建我的目录对象的算法了。

构建编目算法

将规则从更新列表中分离出来:

let [rules, updates] = input.split('\n\n')

将输入解析为包含 2 项的列表,其中每个项目都是一个数字:

rules = rules.split('\n').map(el => el.split('|').map(number))

将该列表缩减为一个充满键和列表值的对象:

rules = rules.reduce((obj, item) => {
  if (!(item[0] in obj)) {
    obj[item[0]] = []
  }
  obj[item[0]].push(item[1])
  return obj
}, {})

这是否按预期工作?

是的,它输出这个对象:

{
  '29': [ 13 ],
  '47': [ 53, 13, 61, 29 ],
  '53': [ 29, 13 ],
  '61': [ 13, 53, 29 ],
  '75': [ 29, 53, 47, 61, 13 ],
  '97': [ 13, 61, 47, 29, 53, 75 ]
}

请注意,我回到只记录必须在任何给定数字之后的数字。

那是因为我认为我不必检查双方。

我可能错了。

但我将在这个假设下继续。

检查每个数字后面的所有数字

我将处理第一个示例更新,它应该显示为正确的。

首先,我需要将输入解析为数字列表:

updates = updates.split("\n").map((el) => el.split(",").map(number));

然后,提取第一个列表进行测试:

let test = updates[0];

现在开始真正的工作。

第一次尝试:

let results = test.map((num, index) => {
  if (num in rules) {
    let afters = test.slice(index + 1);
    let bools = afters.map((item) => rules[num].includes(item));
    return bools.every((el) => el == true) ? true : false;
  } else {
    return true;
  }
});

它似乎一直有效,直到我在第五个示例列表项上尝试它:

61, 13, 29

我的算法检查每个数字是否作为目录中的键存在,并检查其关联列表中的所有数字是否匹配。

但是13不在目录中。我的算法错误地假设了正确的判决。

当它达到 29 时,由于没有更多的数字,它也假设是正确的。

所以,我需要调整我的策略。

第二次尝试:

let results = test.map((num, index) => {
  let afters = test.slice(index + 1);
  if (afters.length) {
    let bools = afters.map((el) => {
      if (!(el in rules)) {
        return true;
      } else {
        return rules[el].includes(num) ? false : true;
      }
    });
    return bools.every((el) => el == true) ? true : false;
  } else {
    return true;
  }
});

这将为每个示例列表生成正确的答案!

它正确检查每个数字后面出现的数字子列表中的每个数字是否包含正在检查的数字(紧邻子列表之前的数字)。

因此,在以下情况下:

61, 13, 29

当遇到 13 时,它查找 29 并看到 13,这意味着它们的顺序错误。

将其插入到归约中并将中间数字相加

并没有我想象的那么难:

let part1 = updates.reduce((total, list) => {
  let result = list
    .map((num, index) => {
      let afters = list.slice(index + 1);
      if (afters.length) {
        let bools = afters.map((el) => {
          if (!(el in rules)) {
            return true;
          } else {
            return rules[el].includes(num) ? false : true;
          }
        });
        return bools.every((el) => el == true) ? true : false;
      } else {
        return true;
      }
    })
    .every((el) => el == true);
  if (result) {
    total += list[math.floor(list.length / 2)];
  }
  return total;
}, 0);

它为示例输入生成正确的答案!

它会如何处理我的拼图输入???

它再次生成了正确答案!!!

呜呼!!!

我觉得我有一段时间想得太多了。当我看到什么不起作用时,答案就变得清晰了。

有趣的东西!

第二部分会带来哪些新挑战......?

第2部分

排序练习

我可能应该预见到这一点。

值得庆幸的是,我认为我的算法已经为此做好了准备。

我必须对每个列表进行排序。

排序的工作原理是比较两个值并根据三个结果之一执行两件事之一:

  • 如果排序函数返回 -1,则第一个值位于第二个值之前
  • 如果返回 1,则第二个值应位于第一个值之前
  • 如果返回 0,则不会移动任何值,因为它们相等

我的算法生成布尔值列表。

当所有布尔值都为 true 时,正确生成它们的数字位于所有布尔值之前。

但是,如果任何布尔值为 false,则其中一个数字应位于当前数字之前。

但是如果我要比较两个数字,并且它们的两个列表都有错误值,我怎么知道哪个应该排在第一位?

我真的只有一种方法来解决一个列表全部为真而另一个列表不为真,或者两者都为真的情况。

嗯嗯。

我认为我需要一次对两个数字而不是数字列表执行测试。

与排序的工作原理完全相同:a 与 b

将我的算法调整为一对一战斗而不是一对多战斗

经过一些令人头疼的事情、三元检查和事后猜测,我得出了一个可行的算法:

function orderer(a, b) {
  let atest = b in rules ? (rules[b].includes(a) ? false : true) : true;
  let btest = a in rules ? (rules[a].includes(b) ? false : true) : true;
  if (atest == false) {
    return 1;
  } else if (btest == false) {
    return -1;
  } else if (atest == btest) {
    return 0;
  }
}

在每个顺序不正确的示例更新上运行它会生成一个正确排序的列表!

我很高兴能在两个输入的所有列表上运行它,并希望今天能获得两颗当之无愧的金星!

俯瞰巨大...小细节

我在示例输入上运行了算法,得到的数字比显示的要大。

我不知道为什么。打印出每个正确排序的列表,证明其元素的顺序正确。

然后我重新阅读了说明:

仅限顺序错误的更新

说得有道理!我正在将每个列表的中间值相加!

修复此问题需要进行一点 slice() 复制列表,然后比较字符串化版本:

let part2 = updates.reduce((total, list) => {
  let copy = list.slice().sort(orderer);
  if (copy.join("") !== list.join("")) {
    total += copy[Math.floor(copy.length / 2)];
  }
  return total;
}, 0);

中提琴!我得到了示例输入的正确答案。

手指交叉,我得到它作为我的拼图输入!

确实!!!

甜甜!!

两颗金星。都是我的!

又一个有趣的谜题。

花了几天时间思考并得出一些策略。

但我最终在迷雾中找到了出路。

进入第六天!

今天关于《打印队列》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

版本声明
本文转载于:dev.to 如有侵犯,请联系study_golang@163.com删除
React State 综合指南:管理组件中的动态数据React State 综合指南:管理组件中的动态数据
上一篇
React State 综合指南:管理组件中的动态数据
提高效率的电脑快捷键:掌握这些实用技巧!
下一篇
提高效率的电脑快捷键:掌握这些实用技巧!
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • ljg-skills -
    ljg-skills
    ljg-skills 是李继刚开源的 AI 技能与提示词集合,面向大模型使用者整理了一批可复用的 prompt、角色设定和任务技能模板,适合用于学习提示词设计、搭建个人 AI 工作流和沉淀团队常用智能体能力。
    738次使用
  • MELO音乐 - AI 音乐生成平台,支持多模态创作能力
    MELO音乐
    MELO音乐是一站式AI视频与音乐制作助手,对标suno, udio的高品质体验。提供伴奏生成、原创写词、无损导出、哼唱识曲、混音变声等全套音频与短视频编辑工具。无论是流行Kpop、电音说唱、民谣古风、摇滚儿歌还是商用轻音乐,MELO为你免费谱曲,轻松做同款!
    744次使用
  • UniScribe - AI 免费在线音视频转文字平台
    UniScribe
    UniScribe 是一款 AI 音视频转文字与内容整理工具,支持上传音频、视频文件或粘贴 YouTube 链接,自动生成转写文本、摘要、思维导图和关键问题,并支持多格式导出,适合会议记录、课程学习、访谈整理和内容创作复盘。
    702次使用
  • 剧云 - 免费 AI 智能中文剧本创作平台
    剧云
    剧云是专业中文剧本创作平台,安全稳定运行十余年,集成AI编剧、剧本医生审核、人物小传、剧情关系图、大纲编写、多人协作、Word导入导出、版权管控功能,数据安全防护,轻松高效创作剧本。
    886次使用
  • 万象有声 - AI 一站式有声内容创作平台
    万象有声
    万象有声,一个专为有声创作者打造的新一代智能有声内容创作平台。平台提供专业的智能拆章、智能画本编辑、AI配音、AI生成音效、后期制作、智能对轨、智能审听等有声创作全流程工具,可以帮助创作者高效、低成本创作出引人入胜的有声作品。立即体验,让有声书制作更简单!
    852次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码