「算法思想🌿」为了解决一个小问题,我写了 88 W 行代码! 🌧️

简介: 「算法思想🌿」为了解决一个小问题,我写了 88 W 行代码! 🌧️

前言


大家好,好久没有给大家整活儿了🔥,今天中午在我的前端早早睡群里有人发了这样一张截图:


网络异常,图片无法展示
|


当时大家都笑喷了,我也感觉很有趣,这个截图也给了我很大的灵感,我要不也写一份这样的代码给大家整个活儿?


遇事不决,穷举搞定


但是这个代码那么长,我是这么懒的人,咋肯定写这样的代码呢,于是我就需要用最简单的方式给大家整活儿,动态生成这 88 W 行代码。


代码实现


说代码实现之前,我还是列一下题目要求:


给出一个不多于 5 位的正整数,要求:

  • 求出他是几位数
  • 分别输出每一位数
  • 按照逆序输出各位数字,比如原数字是 12345,新的数字是 54321


主要思路还是用 node 的 fs 相关 api,完成文件写入。


const { writeFileSync } = require('fs');
const { join } = require('path');
const generateFunction = () => {
  let currentNum = 0;
  let str = '';
  while( currentNum < 100000) {
    const stringCurrentNum = String(currentNum);
    const numArr = stringCurrentNum.split('').reverse();
    const unitList = ['个', '十', '百', '千', '万']
    str += `    case ${currentNum}: \n`
    str += `      console.log('是 ${stringCurrentNum.length} 位数');\n`;
    numArr.forEach((char, index) => {
      str += `      console.log('${unitList[index]}位数是:${char}')\n`;
    })
    str += `      console.log('倒过来是:${Number(numArr.join(''))}');\n`;
    str += `      break;\n`;
    currentNum ++;
  }
  writeFileSync(join(__dirname, 'func.js'), `
  function handleNumber(num) {
    switch (num) {
      ${str}
    }
  }`, {
    encoding: 'utf-8'
  })
}
generateFunction();


注意处理反转之后开头的 0 哦,这里我直接转成了 Number~


之后大家可以看一下我生成的文件内容:


网络异常,图片无法展示
|


88 w 行代码,穷举法,永远的神!


准确的说是 888897 行代码。


之后我们看一下效果:


网络异常,图片无法展示
|

没有问题!


浅析算法思想


网络异常,图片无法展示
|


我对算法了解不足,如有错误,还请多多指教✨


那么写这个内容总不能就是博君一笑吧,我也想和大家说一说我的思考,并为大家延伸更多的东西。首先大家可能都觉得穷举法比较 LOW,那我先给大家讲个例子:


刘慈欣的《诗云》中通过人类的诗人与宇宙高级文明之间的对话,讨论了绝对的技术与人类的艺术之间的关系。高级文明想通过写出比李白还要好的诗证明技术胜过艺术,但无论他学李白喝酒还是穿李白的衣服,他都无法写出李白那样的诗。最后他想到了穷举的办法,通过量子储存,他将人类的汉字进行了所有的排列组合,包含着全部可能的诗词。


穷举法一直都是好用的手段(毕竟上文中的高级文明都要用),并且应用十分广泛(比如:计算机领域),对于很多问题穷举法都是极其好用或者最好用的手段,比如字符串匹配,就是从头开始遍历所有可能的结果,就算是大家耳熟能详的 KMP 算法也无非是通过之前的匹配情况去筛去不可能的结果,无非是经过处理更加高级的穷举。

既然说到穷举法,那本章寒草 🌿 就和大家简单聊聊几种算法思想,也算是对于这个问题的延伸。


本章内容参考:



穷举法


首先最好懂的,最简单的思想就是穷举,也叫做枚举。 穷举穷举,顾名思义,就是穷尽列举,穷举思想的应用场景十分广泛,也非常容易理解。简单来说,穷举就是将问题的可能解依次列举出来,然后一一带入问题检验,从而从一系列可能解中获得。

大道至简,采用枚举法就能够很好的规避系统复杂性带来的冗余,同时或许在一定程度上还能够对空间进行缩减。


优化穷举法有两种方案:

  • 一是问题的简化,尽可能对需要处理的问题进行模型结构上的精简。这种精简具体可体现在问题中的变量数目,减少变量的数据,从而能够从根本上降低「可能解」的组合。
  • 二是对筛选「可能解」的范围和条件进行严格判断,尽可能的剔除大部分无效的「可能解」。


举一个例子,emmmm,算了,就比如上文中的例子吧,或者找出1到100之间的素数。


递推法


与枚举算法思想相比,递推算法能够通过已知的某个条件,利用特定的关系得出中间推论,然后逐步递推,直到得到结果为止。由此可见,递推算法要比枚举算法聪明,它不会尝试每种可能的方案。


递推算法可以不断利用已有的信息推导出新的东西,在日常应用中有如下两种递推 算法。


  • 顺推法:从已知条件出发,逐步推算出要解决问题的方法。例如斐波那契数列就可以通过顺推法不断递推算出新的数据。
  • 逆推法:从已知的结果出发,用迭代表达式逐步推算出问题开始的条件,即顺推法的逆过程。


有一种很好的方法让大家理解递推法,就是被数学证明题:


  1. 因为三角形内角和是 180 度,且其中两个角分别为 65 度和 70 度。
  2. 所以第三个角是 45 度。
  3. 因为平角是 180 度。
  4. 所以该角的外角是 135 度。


最后举一个例子,一对大兔子每月能生一对小兔子,且每对新生的小兔子经过一个月可以长成一对大兔子,具备繁殖能力,如果不发生死亡,且每次均生下一雌一雄,问一年后共有多少对兔子?


递归法


递归算法是把问题转化成规模更小的同类子问题,先解决子问题,再通过相同的求解过程逐步解决更高层次的问题,最终获得最终的解。所以相较于递推而言,递归算法的范畴更小,要求子问题跟父问题的结构相同。而递推思想从概念上并没有这样的约束。


用一句话来形容递归算法的实现,就是在函数或者子过程的内部,直接或间接的调用自己算法。所以在实现的过程中,最重要的是确定递归过程终止的条件,也就是迭代过程跳出的条件判断。否则,程序会在自我调用中无限循环。


举一个例子就是经典的汉诺塔问题。源于印度传说中,大梵天创造世界时造了三根金钢石柱子,其中一根柱子自底向上叠着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。


分治法


分治算法将一个规模为 N 的问题分解为 K 个规模较小的子问题,这些子问题相互独立且与原问题性质相同。只要求出子问题的解,就可得到原问题的解。


在编程过程中,经常遇到处理数据相当多、求解过程比较复杂、直接求解法会比较耗时的问题。在求解这类问题时,可以采用各个击破的方法。


具体做法是:先把这个问题分解成几个较小的子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个大问题的解。如果这些子问题还是比较大,还可以继续再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治算法的基本思想。


使用分治算法解题的一般步骤如下。

  • 分解,将要解决的问题划分成若干个规模较小的同类问题。
  • 求解,当子问题划分得足够小时,用较简单的方法解决。
  • 合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。

举个例子,比如归并排序


贪心算法


贪心算法也被称为贪婪算法,它在求解问题时总想用在当前看来是最好方法来实现。这种算法思想不从整体最优上考虑问题,仅仅是在某种意义上的局部最优求解。

虽然贪心算法并不能得到所有问题的整体最优解,但是面对范围相当广泛的许多问题时,能产生整体最优解或者是整体最优解的近似解。由此可见,贪心算法只是追求某个范围内的最优,可以称之为“温柔的贪婪”。


贪心算法从问题的某一个初始解出发,逐步逼近给定的目标,以便尽快求出更好的解。当达到算法中的某一步不能再继续前进时,就停止算法,给出一个近似解。由贪心算法的特点和思路可看出,贪心算法存在以下3个问题。


  • 不能保证最后的解是最优的。
  • 不能用来求最大或最小解问题。
  • 只能求满足某些约束条件的可行解的范围。


贪心算法的基本思路如下。


  • 建立数学模型来描述问题。
  • 把求解的问题分成若干个子问题。
  • 对每一子问题求解,得到子问题的局部最优解。
  • 把子问题的局部最优解合并成原来解问题的一个解。


贪心算法的经典例子很多,比如背包问题,推销问题。


试探法


试探法也叫回溯法,它将问题的候选解按某种顺序逐一进行枚举和检验。当发现当前候选解不可能是正确的解时,就选择下一个候选解。


如果当前候选解除了不满足问题规模要求外能够满足所有其他要求时,则继续扩大当前候选解的规模,并继续试探。如果当前候选解满足包括问题规模在内的所有要求时,该候选解就是问题的一个解。在试探算法中,放弃当前候选解,并继续寻找下一个候选解的过程称为回溯。扩大当前候选解的规模,并继续试探的过程称为向前试探。


使用试探算法解题的基本步骤如下所示。


  • 针对所给问题,定义问题的解空间。
  • 确定易于搜索的解空间结构。
  • 以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。


试探法为了求得问题的正确解,会先委婉地试探某一种可能的情况。在进行试探的过程中,一旦发现原来选择的假设情况是不正确的,立即会自觉地退回一步重新选择,然后继续向前试探,如此这般反复进行,直至得到解或证明无解时才死心。


举个经典的例子,八皇后问题。在 8 × 8 格的国际象棋上摆放 8 个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,求摆法。


网络异常,图片无法展示
|


动态规划


可以去看看这个问答:www.zhihu.com/question/23…

这一节想加入一些自己的心得与编码实践,过一阵补上~


模拟法


许多真实场景下,由于问题规模过大,变量过多等因素,很难将具体的问题抽象出来,也就无法针对抽象问题的特征来进行算法的设计。这个时候,模拟思想或许是最佳的解题策略。


模拟的过程就是对真实场景尽可能的模拟,然后通过计算机强大的计算能力对结果进行预测。这相较于上述的算法是一种更为宏大的思想。在进行现实场景的模拟中,可能系统部件的实现都需要上述几个算法思想的参与。


模拟说起来是一种很玄幻的思想,没有具体的实现思路,也没有具体的优化策略。只能说,具体问题具体分析。


模拟法实践 ——— 求圆周率


比如我求圆周率,就可以转换为概率问题:随机打点落在扇形区域的概率


网络异常,图片无法展示
|



于是,我开始编码:


let i = 0;
let num = 0;
const sum = 100000000;
while(i < sum) {
    i ++;
    const x = Math.random();
    const y = Math.random();
    if(x * x + y * y < 1) {
        num++;
    }
}
console.log(4 * num / sum);


我模拟了 100000000 次,结果如下:


网络异常,图片无法展示
|


结束语


网络异常,图片无法展示
|


参考:



这篇文章灵感来自于那张图片,哈哈哈,整活儿很开心✨。


还有最近打算不整活儿了,打算重新学习前端,文章的内容和顺序按照之前的「 30天整理 |2W字长篇」用一篇文章明确前端学习路线并构筑知识体系🌿,可能我最开始复习的不会是 HTML 和 CSS ,而是一些通用技能,请大家保持期待。

相关文章
|
9月前
|
机器学习/深度学习 人工智能 测试技术
昆仑万维开源 Skywork R1V:开源多模态推理核弹!视觉链式分析超越人类专家
Skywork R1V 是昆仑万维开源的多模态思维链推理模型,具备强大的视觉链式推理能力,能够在多个权威基准测试中取得领先成绩,推动多模态推理模型的发展。
267 4
昆仑万维开源 Skywork R1V:开源多模态推理核弹!视觉链式分析超越人类专家
|
4月前
|
Web App开发 搜索推荐 安全
火狐(Mozilla Firefox)浏览器安装教程,附火狐(Mozilla Firefox)安装包
火狐浏览器2025年8月最新版141.0.2发布,支持Windows、Mac、安卓系统,运行速度快,安全性高。提供离线安装包下载,支持多种网络标准,个性化定制功能丰富,安装简便,可自定义安装路径并恢复上次浏览标签,带来更流畅上网体验。
1836 6
|
10月前
|
存储 人工智能 自然语言处理
AI 剧本生成与动画创作解决方案评测
用了阿里云的 AI 剧本生成与动画创作解决方案后,我感觉 AI 在内容创作领域真的很有潜力。这个方案不仅简化了动画创作流程,降低了技术门槛,还提高了内容生产的速度和质量。虽然在内容多样性和交互体验上还有提升空间,但总体来说,它是个实用又高效的解决方案,能满足实际生产需求,给创作者带来全新的体验。
362 5
idea提示Your idea evaluation has expired. Your session will be limited to 30 minutes[亲测解决]
解决方法: 在idea中安装插件idea eval Reset,应用市场如果搜不到就安装离线的
2100 0
idea提示Your idea evaluation has expired. Your session will be limited to 30 minutes[亲测解决]
|
8月前
|
人工智能 语音技术 iOS开发
25.9K star!AI一键生成高清短视频,这个开源神器让内容创作起飞!
"MoneyPrinterTurbo 是基于AI大模型的全自动短视频生成工具,只需输入主题,3分钟即可生成包含智能脚本、AI配音、专业字幕和流畅画面的高清视频
366 1
|
数据采集 自然语言处理 监控
【优秀python毕设案例】基于python django的新媒体网络舆情数据爬取与分析
本文介绍了一个基于Python Django框架开发的新媒体网络舆情数据爬取与分析系统,该系统利用Scrapy框架抓取微博热搜数据,通过SnowNLP进行情感分析,jieba库进行中文分词处理,并以图表和词云图等形式进行数据可视化展示,以实现对微博热点话题的舆情监控和分析。
1359 110
【优秀python毕设案例】基于python django的新媒体网络舆情数据爬取与分析
|
10月前
|
人工智能 自然语言处理 API
销售易NeoCRM与Salesforce:优势特色大比拼
本文对比了销售易NeoCRM与Salesforce两款CRM系统。销售易NeoCRM功能涵盖销售、客户、营销管理等,具AI赋能和移动办公优势,界面现代化,价格灵活适合中小企业;Salesforce功能全面,AI平台强大,生态系统丰富,全球化支持出色,适合大型及跨国企业。两者各有优劣,企业应根据自身需求选择合适的CRM系统,以实现高效管理和业务增长。
|
11月前
|
人工智能 自然语言处理 算法
“破冰”探索两周年,AI和媒体碰撞出了什么火花?
2022年末,大模型浪潮席卷新闻媒体行业,引发内容生产方式的深刻变革。2023年1月,传播大脑科技公司在杭州成立,成为浙江新闻传媒领域的重要探索。两年后,大模型技术进一步重构新闻生产和分发逻辑,传播大脑通过整合资源、打破壁垒,推出了国内首个媒体垂类大模型,并在全国范围内推广“浙江模式”,助力多省份媒体融合进程。2025年初,传播大脑在智能化办公、内容创作和形式创新等方面取得显著成果,为媒体行业的未来提供了新的解决方案和启示。
255 14
|
9月前
|
城市大脑 安全 计算机视觉
课时13:城市数据大脑介绍
阿里云与杭州市合作打造的城市数据大脑,通过智能调控红绿灯、实时视频分析交通事件,提升了道路通行效率。如今,城市大脑不仅能主动发现并处理交通事故,还能为救护车规划最优路线,从被动接警转变为积极应对,使城市交通更加顺畅和安全。交警们希望通过这一系统,让杭州变得更加美好,实现更愉快的出行体验。
468 0
|
网络协议 数据挖掘 5G
适用于金融和交易应用的低延迟网络:技术、架构与应用
适用于金融和交易应用的低延迟网络:技术、架构与应用
644 5