跳至正文
  • Scratch
  • Python
  • C++
  • 创客
  • 科创课题
  • 关于我们
  • OJ
  • Scratch
  • Python
  • C++
  • 创客
  • 科创课题
  • 关于我们
  • OJ

1 乐高STEAM

  • 乐高课程简介
  • Wedo2.0科学机器人
    • Wedo2.0 官方课程包
    • WeDo2.0如何培养计算思维
    • WeDo2.0机械部件与编程模块
    • 第1期
      • 001 遥控小车
      • 002 拉力小车
      • 003 麦乐机器人
      • 004 毛毛虫
      • 005 小叉车
      • 006 可爱的小鸟
      • 007 淘气的猴子
      • 008 环保垃圾车
      • 009 家用跑步机
      • 010 工程升降机
      • 011 工程塔吊机
      • 012 弹涂鱼
    • 第2期
      • 01 科学漫游器
      • 02 运动传感器
      • 03 巡线小车
      • 04 骏马奔驰
      • 05 采油机
      • 06 操纵杆
      • 07 测量器
      • 08 转向叉车
      • 09 操作版叉车
      • 10 蜗轮叉车
      • 11 厨师机器人
      • 12 小轮船

2 Scratch

  • Scratch课程介绍
  • Icode专项训练
    • 密码保护:001 ICode基础入门
    • 密码保护:002 路线规划
    • 密码保护:003 重复执行1-2
    • 密码保护:004 重复执行3-4
    • 密码保护:005 识别重复规律
    • 密码保护:006 变量入门1-2
    • 密码保护:007 变量练习1-2
    • 密码保护:008 变量应用1-2
    • 密码保护:Icode积木模式集训-1
  • Scratch竞赛考级测试
    • 2023年GESP
    • 2024年GESP
    • 密码保护:PSTK答案
    • Scratch-1级 PSTK A
    • Scratch-1级 PSTK B
    • Scratch-1级 PSTK C
    • Scratch-2级 PSTK A
    • Scratch-2级 PSTK B
    • Scratch-2级 PSTK C
    • Scratch-3级 PSTK A
    • Scratch-3级 PSTK B
    • Scratch-3级 PSTK C
    • Scratch-NOC2023
  • Scratch第1期-初阶
    • 01 初识Scratch
    • 02 会说话的喵星人
    • 03 鱼儿水中游1
    • 04 鱼儿水中游2
    • 05 动感舞蹈
    • 06 魔法蛋糕1
    • 07 魔法蛋糕2
    • 08 魔法气球
    • 09 蝴蝶飞舞
    • 10 城市快餐车
    • 11 会飞的小猫
    • 12 鲨鱼吃螃蟹
    • 13 侏罗纪公园
    • 14 秋季运动会
    • 15 森林舞会1
    • 16 森林舞会2
    • 17 十五的月亮
    • 18 抗击病毒
    • 19 我爱运动
    • 20 天降苹果
    • 21 小狗追足球
    • 22 山地足球
    • 23 保卫农场
    • 24 音乐之声
    • 25 打击乐器
    • 26 节日快乐
    • 27 牛牛变脸
    • 28 病毒区域检测
    • 29 百米跨栏
    • 30 海星吃螃蟹
  • Scratch第2期-初阶
    • 31 聪明的甲壳虫1
    • 32 聪明的甲壳虫2
    • 33 沙漠小熊1
    • 34 沙漠小熊2
    • 35 魔术表演1
    • 36 魔术表演2
    • 37 赛车游戏1.0
    • 38 赛车游戏2.0
    • 39 魔法圈1
    • 40 魔法圈2
    • 41 神笔马良1
    • 42 神笔马良2
    • 43 画平行线
    • 44 画田字格
    • 45 小小画家1
    • 46 小小画家2
    • 47 端午安康1
    • 48 端午安康2
    • 49 星际穿越1
    • 50 星际穿越2
    • 51 飞向火星1
    • 52 飞向火星2
    • 53 飞天大脸猫1
    • 54 飞天大脸猫2
    • 55 蝴蝶进城
    • 56 双人赛龙舟
    • 57 连环画1
    • 58 连环画2
    • 59 小小收音机
    • 60 怀旧电视机
  • Scratch第3期-中阶
    • 061 砖块消消乐1
    • 062 砖块消消乐2
    • 063 神奇的克隆
    • 064 打砖块2.0
    • 065 可爱的北极熊
    • 066 炫彩烟花
    • 067 苹果乐园
    • 068 彩色泡泡
    • 069 白马飞飞
    • 070 看你往哪躲
    • 071 小猫打螃蟹1
    • 072 小猫打螃蟹2
    • 073 打蝴蝶1
    • 074 打蝴蝶2
    • 075 走出迷宫1
    • 076 走出迷宫2
    • 077 走出迷宫3
    • 078 走出迷宫4
    • 079 趣玩贪吃蛇1
    • 080 趣玩贪吃蛇2
    • 081 趣玩贪吃蛇3
    • 082 趣玩贪吃蛇4
    • 083 墙上的钟表1
    • 084 墙上的钟表2
    • 085 趣味问答1
    • 086 趣味问答2
    • 087 趣味加减法1
    • 088 趣味加减法2
    • 089 电子加餐1
    • 090 电子加餐2
  • Scratch第4期-中阶
    • 091 定制菜单1
    • 092 定制菜单2
    • 093 打字游戏1
    • 094 打字游戏2
    • 095 打字游戏3
    • 096 游戏进度条
    • 097 神奇的画笔
    • 098 画正多边形1
    • 099 画正多边形2
    • 100 解构复杂图形1
    • 101 解构复杂图形2
    • 102 自制积木(画多边形)
    • 103 圆形的画法
    • 104 彩虹扇1
    • 105 彩虹扇2
    • 106 多彩五角星
    • 107 妙笔生花
    • 108 大风车
    • 110 彩色轮盘1
    • 111 彩色轮盘2
    • 112 古诗算术1
    • 113 古诗算术2
    • 114 古诗算术3
    • 115 猴子吃桃
    • 116 蜗牛爬树
    • 117 冰雹猜想
    • 118 顺序查找法
    • 119 二分查找1
    • 120 二分查找2
  • Scratch第5期-高阶
    • 121 直尺与量角器
    • 122 迭代算法求和
    • 123 迭代算法-最大公约数
    • 124 小猫找余数
    • 密码保护:125 冒泡排序1
    • 密码保护:126 冒泡排序2
    • 密码保护:127 选择排序1
    • 密码保护:128 选择排序2
    • 密码保护:129 插入排序1
    • 密码保护:130 插入排序2
    • 131 圆形与分数1
    • 132 圆形与分数2
    • 133 数的集合1
    • 134 数的集合2
    • 135 平均数与小数1
    • 136 平均数与小数2
    • 137 多边形面积1
    • 138 多边形面积2
    • 139 圆的周长与面积1
    • 140 圆的周长与面积2
    • 141 扇形统计及比例1
    • 142 扇形统计及比例2
  • Scratch经典游戏
    • 002 幸运转盘2
    • 003 神枪手1
    • 004 神枪手2
    • 005 打地鼠1
    • 006 打地鼠2
    • 007 打地鼠3
    • 008 打地鼠4
    • 009 愤怒的小鸟1
    • 010 愤怒的小鸟2
    • 011 植物大战僵尸1
    • 012 植物大战僵尸2
    • 013 植物大战僵尸4

3 Python

  • Python课程介绍
  • ICode专项训练
    • 密码保护:01 ICode Python集训 – 1
  • Python 竞赛考级测试
    • 2023年GESP
    • 2024年GESP
    • Python PSTK – 5 模拟卷 A
    • Python PSTK – 5 模拟卷 B
    • 密码保护:Python NOC – 模拟试卷
    • Python PSTK – 4 模拟卷 A
    • Python PSTK – 4 模拟卷 B
    • Python PSTK – 6 模拟卷 A
    • Python PSTK – 6 模拟卷 B
    • 密码保护:答案
  • Python第 01 期 - 基础
    • 001 Python简介
    • 密码保护:001_1 PyGame
    • 002 Python在Windows下的环境搭建
    • 003 交互式编程
    • 004 变量
    • 005 标识符和关键字
    • 006 集成开发环境 – PyCharm
    • 007 字符串 – 初识字符串
    • 008 字符串与数字的转换
    • 008_自学课 数据类型
    • 密码保护:009 第一次月考(1至9课)
    • 009 输入输出
    • 010 运算符 – 算术运算符
    • 011 运算符 – 赋值运算符
    • 012 运算符 – 比较运算符
    • 013 运算符 – 逻辑运算符
    • 014 运算符 – 优先级
    • 015 语句和注释
    • 016 程序调试
    • 016_自学课 流程图标准符号
    • 017 Turtle – 初识Turtle
    • 018 Turtle – 画笔的简单使用
    • 密码保护:018 第二次月考(10至18课)
    • 019 分支结构 – 条件语句 if
    • 020 分支结构 – 条件语句 if…else
    • 021 分支结构 – 条件语句 if…elif…else
    • 022 分支结构 – 条件语句嵌套
    • 023 Turtle – 条件语句的应用
    • 024 循环结构 – 初识 while 循环
    • 025 循环结构 – while 无限循环
    • 密码保护:025 第三次月考(19至25课)
    • 026 Turtle – while 循环语句的应用 1
    • 027 Turtle – while 循环语句的应用 2
    • 028 字符串 – 长度和索引
    • 029 字符串 – 截取
    • 029_自学课 字符串 – 转义字符和长字符串
    • 030 数据结构 – 初识列表
    • 031 数据结构 – 列表基本操作
    • 032 循环结构 – 初识 for 循环
    • 密码保护:032 第四次月考(26至32课)
  • Python第 02 期 - 基础
    • 033 Turtle – for循环语句的应用 1
    • 034 Turtle – for循环语句的应用 2
    • 035 字符串 – 格式化及内置函数
    • 036 函数 – 初识函数
    • 037 函数 – 参数定义
    • 038 函数 – 返回值
    • 039 Turtle – 函数的应用 1
    • 040 Turtle – 函数的应用 2
    • 密码保护:040 第五次月考(33至40课)
    • 041 数据结构 – 列表的常用内置函数
    • 041_自学课 代码书写规范
    • 041_自学课 可迭代对象的概念
    • 042 数据结构 – 列表的推导表达式 一层循环
    • 042_自学课 数据结构 – 列表的拷贝
    • 043 数据结构 – 列表的推导表达式 多层循环
    • 044 数据结构 – 列表的推导表达式 一层判断
    • 045 数据结构 – 列表的推导表达式 多层判断
    • 046 综合实战一 – 时钟的制作 1
    • 047 综合实战一 – 时钟的制作 2
    • 048 综合实战一 – 时钟的制作 3
    • 密码保护:049 第六次月考(41至49课)
    • 049 综合实战一 – 时钟的制作 4
    • 050 数据结构 – 二维列表
    • 051 数据结构 – 初识元组
    • 052 数据结构 – 初识字典
    • 053 数据结构 – 字典基本操作
    • 054 数据结构 – 字典内置函数
    • 055 运算符 – 成员运算符
    • 056 数据结构的遍历
    • 057 zip的使用
    • 058 字典的合并及zip解包
    • 密码保护:058 第七次月考(50至58课)
    • 059 综合实战二 – 学生信息管理系统1
    • 060 综合实战二 – 学生信息管理系统2
    • 061 综合实战二 – 学生信息管理系统3
    • 062 综合实战二 – 学生信息管理系统 4
    • 063 综合实战二 – 学生信息管理系统5
    • 密码保护:064 第八次月考(59至64课)
    • 064 综合实战二 – 学生信息管理系统 6
  • Python第 03 期 - 基础
    • 065 数据结构 – 初识集合
    • 066 数据结构 – 集合的基本操作
    • 067 数据结构 – 集合的基本运算
    • 068 文件 – 读文件
    • 069 文件 – 写文件
    • 070 文件 – with关键字及推导表达式
    • 071 综合实战三 – 随机试卷1
    • 072 综合实战三 – 随机试卷2
    • 073 综合实战三 – 随机试卷3
    • 密码保护:074 第九次月考(65至74课)
    • 074 综合实战三 -随机试卷 4
    • 075课 模块 – 初识模块
    • 076课 模块 – 包
    • 077 模块 – random包的使用 1
    • 078 模块 – random包的使用 2
    • 079 模块 – math包的使用 1
    • 079_自学课 模块 random包的使用 3
    • 080 模块 – math包的使用 2
    • 密码保护:080 第十次月考(75至80课)
    • 080_自学课 模块 – math包的使用 3
    • 081 综合实战四 – 数据可视化1
    • 082 综合实战四 – 数据可视化2
    • 083 综合实战四 – 数据可视化3
    • 084 综合实战四 -数据可视化 4
    • 085 函数 – 可变类型与不可变类型
    • 086 函数 – 默认参数与可变参数
    • 087 函数 – 关键词参数及参数的组合
    • 088 函数 – 匿名函数 lambda
    • 密码保护:088 第十一次月考(81至88课)
    • 089 函数 – 高阶函数 1
    • 089_自学课 数据结构 – 字典排序
    • 090 数据结构 – 字典推导表达式
    • 090_自学课 函数 – 高阶函数 2
    • 091 综合实战五 – 文本数据的简单清洗1
    • 092 综合实战五 – 文本数据的简单清洗2
    • 093 综合实战五 – 文本数据的简单清洗3
    • 094 综合实战五 – 模块化编程1
    • 095 综合实战五 – 模块化编程2
    • 密码保护:096 第十二次月考(89至96课)
    • 096 综合实战五 – 模块化编程3
  • Python第 04 期 - 应用
    • 097 面向对象 – 初识面向对象
    • 098 面向对象 – 类定义
    • 099 面向对象 – 类构造方法
    • 100 面向对象 – 类对象的创建和使用
    • 101 面向对象 – self使用详解
    • 102 面向对象 – 类变量的创建和使用
    • 103 面向对象 – 类的继承
    • 104 图形化编程 – 初识图形化编程
    • 105 图形化编程 – PyQt5安装配置
    • 106 图形化编程 – PyQt5框架和常用界面
    • 107 图形化编程 – PyQt5 菜单和工具栏
    • 108 图形化编程 – PyQt5 控件 1
    • 109 图形化编程 – PyQt5 控件 2
    • 110 图形化编程 – PyQt5 控件 3
    • 111 图形化编程 – PyQt5 控件 4
    • 112 图形化编程 – PyQt5 控件 5
    • 113 图形化编程 – PyQt5 控件 6
    • 114 图形化编程 – PyQt5 控件 7
    • 115 图形化编程 – PyQt5 对话框 1
    • 116 图形化编程 – PyQt5 对话框 2
    • 117 图形化编程 – 事件和信号 1
    • 118 图形化编程 – 事件和信号 2
    • 119 图形化编程 – 控件实践 1
    • 120 图形化编程 – 控件实践 2
    • 121 图形化编程 – 控件实践 3
    • 122 图形化编程 – 控件实践 4
    • 123 图形化编程 – 控件实践 5
    • 124 图形化编程 – 控件实践 6
    • 125 图形化编程 – 控件实践 7
    • 126 图形化编程 – 布局 1
    • 127 图形化编程 – 布局 2
    • 128 图形化编程 – 布局 3
  • Python第 05 期 - 应用
    • 129 字数统计小程序1
    • 130 字数统计小程序2
    • 131 字数统计小程序3
    • 132 字数统计小程序4
    • 133 万年历实现1
    • 134 万年历实现2
    • 135 万年历实现3
    • 136 万年历实现4
    • 137 简化版Excel1
    • 138 简化版Excel2
    • 139 简化版Excel3
    • 140 简化版Excel4
    • 141 图形化编程 – 应用一 猜数字1
    • 142 图形化编程 – 应用一 猜数字2
    • 143 程序打包 – pyinstaller
    • 144 pyqt小应用-计算器 1
    • 145 pyqt小应用-计算器 2
    • 146 pyqt小应用-计算器 3
    • 147 pyqt小应用-计算器 4
    • 148 pyqt小应用-计算器 5
    • 149 pyqt小应用-计算器 6
    • 150 pyqt小应用-播放器 1
    • 151 pyqt小应用-播放器 2
    • 152 pyqt小应用-播放器 3
    • 153 pyqt小应用-播放器 4
    • 154 pyqt小应用-播放器 5
    • 155 pyqt小应用-播放器 6
    • 156 pyqt小应用-画图 1
    • 157 pyqt小应用-画图 2
    • 158 pyqt小应用-画图 3
    • 159 pyqt小应用-画图 4
    • 160 pyqt小应用-画图 5
    • 161 pyqt小应用-画图 6
  • Python第 06 期 - 游戏制作
    • 161 初识游戏编程
    • 162 PyGame安装配置
    • 163 PyGame Display学习
    • 164 PyGame Draw学习
    • 165 PyGame Font学习
    • 166 PyGame Event学习
    • 167 复合实践 1 – 2048游戏 1
    • 168 复合实践 1 – 2048游戏 2
    • 169 复合实践 1 – 2048游戏 3
    • 170 复合实践 1 – 2048游戏 4
    • 171 复合实践 1 – 2048游戏 5
    • 172 复合实践 1 – 2048游戏 6
    • 173 PyGame Surface学习
    • 174 PyGame Transform学习
    • 175 PyGame Time学习
    • 176 PyGame Rect学习
    • 177 复合实践 2 – 接金币游戏 1
    • 178 复合实践 2 – 接金币游戏 2
    • 179 复合实践 2 – 接金币游戏 3
    • 180 复合实践 2 – 接金币游戏 4
    • 181 复合实践 2 – 接金币游戏 5
    • 182 复合实践 2 – 接金币游戏 6
    • 183 PyGame其他模块自学
    • 184 复合实践 3 – 消消乐游戏 1
    • 185 复合实践 3 – 消消乐游戏 2
    • 186 复合实践 3 – 消消乐游戏 3
    • 187 复合实践 3 – 消消乐游戏 4
    • 188 复合实践 3 – 消消乐游戏 5
    • 189 复合实践 3 – 消消乐游戏 6
    • 190 复合实践 4 – 24点游戏 1
    • 191 复合实践 4 – 24点游戏 2
    • 192 复合实践 4 – 24点游戏 3
    • 193 复合实践 4 – 24点游戏 4
    • 194 复合实践 4 – 24点游戏 5
    • 195 复合实践 4 – 24点游戏 6
  • Python第 07 期 - 游戏制作
    • 196 打地鼠1
    • 197 打地鼠2
    • 198 打地鼠3
    • 199 打地鼠4
    • 200 打地鼠5
    • 201 打地鼠6
    • 202 打地鼠7
    • 203 打地鼠8
    • 204 五子棋1
    • 205 五子棋2
    • 206 五子棋3
    • 207 五子棋4
    • 208 五子棋5
    • 209 五子棋6
    • 210 五子棋7
    • 211 五子棋8
    • 212 贪吃蛇1
    • 213 贪吃蛇2
    • 214 贪吃蛇3
    • 215 贪吃蛇4
    • 216 贪吃蛇5
    • 217 贪吃蛇6
    • 218 贪吃蛇7
    • 219 植物大战僵尸1
    • 220 植物大战僵尸2
    • 221 植物大战僵尸3
    • 222 植物大战僵尸4
    • 223 植物大战僵尸5
    • 224 植物大战僵尸6
    • 225 植物大战僵尸7
    • 226 植物大战僵尸8
    • 227 Turtle游戏1-赛龟
  • Python第 08 期 - 算法
    • 229 高精度计算算法介绍
    • 230 高精度计算加法
    • 231 高精度计算减法
    • 232 高精度计算乘法
    • 233 高精度计算除法
    • 234 python内置高精度计算
    • 235 高精度计算综合实战1
    • 236 高精度计算综合实战2
    • 237 排序算法介绍
    • 238 排序算法复杂度
    • 239 冒泡排序算法
    • 240 快速排序算法
    • 241 插入排序算法
    • 242 希尔排序算法
    • 243 选择排序算法
    • 244 堆排序算法基础
    • 245 堆排序算法
    • 246 归并排序算法基础
    • 247 归并排序算法
    • 248 桶排序算法
    • 249 计数排序算法
    • 250 排序算法总结1
    • 251 排序算法总结2
    • 252 排序算法综合实战1
    • 253 排序算法综合实战2
    • 254 递推算法介绍
    • 255 顺推算法
    • 256 逆推算法
    • 257 斐波那契数列
    • 258 汉诺塔问题
    • 259 平面分隔问题1
    • 260 平面分隔问题2
    • 261 猴子摘桃问题
    • 261 递归算法1
    • 262 母牛的问题
    • 262 递归算法2
    • 263 昆虫繁殖问题
    • 263 阶乘的求解
    • 264 五人分鱼问题
    • 264 斐波那契数列
  • Python第 09 期 - 算法
    • 265 杨辉三角
    • 266 集合的划分
    • 267 数的计数
    • 268 汉诺塔问题
    • 269 波兰表达式
    • 270 回溯算法1
    • 271 回溯算法2
    • 272 效益问题
    • 273 子集和问题
    • 274 素数环
    • 275 八皇后问题
    • 276 回文字符串寻找
    • 277 数字的拆分
    • 278 苹果放置
    • 279 马的遍历
    • 280 迷宫问题
    • 281 递归与回溯算法的总结
    • 282 贪心算法1
    • 283 贪心算法2
    • 284 背包问题
    • 285 排队打水问题
    • 286 活动选择1
    • 287 活动选择2
    • 288 整数区间
    • 289 删数问题
    • 290 均分纸牌
    • 291 最大子序列和
    • 292 分糖果问题
  • Python第 10 期 - 数据结构
    • 293 栈
    • 294 链栈的实现1
    • 295 链栈的实现2
    • 296 斐波那契数列1
    • 297 斐波那契数列2
    • 298 括号的匹配1
    • 299 括号的匹配2
    • 300 队列
    • 301 队列的实现1
    • 302 队列的实现2
    • 303 用队列实现栈1
    • 304 用队列实现栈2
    • 305 约瑟夫问题1
    • 306 约瑟夫问题2
    • 307 链表
    • 308 链表的实现1
    • 309 链表的实现2
    • 310 合并有序链表1
    • 311 合并有序链表2
    • 312 双向链表实现双端队列1
    • 313 双向链表实现双端队列2
    • 314 树
    • 315 二叉树
    • 316 树的存储结构及实现1
    • 317 树的存储结构及实现2
    • 318 树的先序遍历
    • 319 树的层序遍历
    • 320 哈夫曼树1
    • 321 哈夫曼树2
    • 322 图
    • 323 图的实现1
    • 324 图的实现2
    • 325 dijkstra算法1
    • 326 dijkstra算法2
    • 327 floyd算法1
    • 328 floyd算法2
  • Python第11期 - 人工智能
    • 密码保护:329 人工智能简介
    • 密码保护:330 交通标志分类 1
    • 密码保护:331 卷积神经网络介绍
    • 密码保护:332 卷积层
    • 密码保护:333 池化层
    • 密码保护:334 激活函数
    • 密码保护:335 损失函数
    • 密码保护:336 梯度下降
  • Python第13期 - 树莓派
    • 001 树莓派介绍
  • 华东师大
    • 基于Python的数据分析入门与实践
    • 第10讲 Numpy的创建 array
    • 第11讲 Numpy 基础运算
    • 第12讲 Numpy array的合并与分割
    • 第13讲 Pandas DataFrame与数据选择
    • 第14讲 Pandas的日常用法
    • 第1讲 基础语法和开发环境
    • 第2讲 运算符与字符串
    • 第3讲 分支与循环
    • 第4讲 函数与面向对象
    • 第5讲 数据结构与文件
    • 第6讲 模块与Turtle画图
    • 第7讲 图形界面与程序打包
    • 第8讲 数据爬取、处理与可视化
    • 第9讲 数据处理
  • 常用模块
    • Python标准库与第三方库
    • 模块:re
    • 模块:requests
    • 模块:tkinter
      • 01 第一个Tkinter程序
      • 02 Tkinter常用控件及其属性
      • 03 Tkinter控件的颜色和大小
      • 04 Tkinter Frame控件
      • 05 Tkinter pack()布局
      • 06 Tkinter grid()布局
      • 07 Tkinter place()布局
      • 08 Tkinter事件介绍
      • 09 Tkinter鼠标事件处理
      • 10 Tkinter键盘事件处理
      • 11 Tkinter拦截系统信息
      • 12 Tkinter Button:按钮控件
      • 13 Tkinter Canvas:绘图控件
      • 14 Tkinter Checkbutton:复选框控件
      • 15 Tkinter Entry:单行文本框
      • 16 Tkinter Label:标签控件
      • 17 Tkinter Listbox:列表框控件
      • 18 Tkinter Menu:菜单控件
      • 19 Tkinter Message:消息框
      • 20 Tkinter Radiobutton:单选按钮控件
      • 21 Tkinter Scale:滑动条控件
      • 22 Tkinter Scrollbar:滚动条控件
      • 23 Tkinter Text:文本框控件
      • 24 Tkinter Toplevel:独立窗口控件
      • 25 Tkinter messagebox:消息提示对话框
      • 26 Tkinter filedialog:文件对话框
      • 27 Tkinter colorchooser:颜色选取对话框
      • 28 Tkinter实现简易的聊天窗口

4 C++

  • C++ 课程介绍
  • C++ CSP-J1 基础入门
    • CSP-J 001 初识C++
    • CSP-J 002 基本数据类型(整型)
    • CSP-J 003 基本数据类型(实型)
    • CSP-J 004 基本数据类型(bool、char)& 关系运算符
    • CSP-J 005 分支结构 – if
    • CSP-J 006 逻辑运算符
    • CSP-J 007 分支结构 – switch & 三目运算符
    • CSP-J 008 分支结构综合应用
    • CSP-J 009 循环结构 – while & do while
    • CSP-J 010 作用域 & 循环结构 – for
    • CSP-J 011 循环结构 – for嵌套
    • CSP-J 012 循环结构综合应用
    • CSP-J 013 进制转换
    • CSP-J 014 变量自增与自减 & 位运算
    • CSP-J 015 计算机内存 & 数据类型转化
    • 密码保护:CSP-J 016 综合应用
  • C++ CSP-J2 基础进阶
    • CSP-J 017 一维数组
    • CSP-J 018 二维数组
    • CSP-J 019 数组综合应用
    • CSP-J 020 字符串
    • CSP-J 021 string
    • CSP-J 022 字符串综合应用
    • CSP-J 023 变量地址 & 指针
    • CSP-J 024 函数的定义与调用
    • CSP-J 025 函数参数 & 常量与变量的作用范围
    • CSP-J 026 递归函数
    • CSP-J 027 结构体
    • CSP-J 028 联合体
    • CSP-J 029 scanf & printf
    • CSP-J 030 文件的基本读写
    • 密码保护:CSP-J 031 STL模版
    • 密码保护:CSP-J 032 综合应用
  • C++ CSP-J3 算法与数据结构入门
    • CSP-J 033 算法概念与描述
    • CSP-J 034 枚举&模拟
    • CSP-J 035 递推法
    • CSP-J 036 递归法
    • CSP-J 037 二分法
    • CSP-J 038 高精度算法
    • CSP-J 039 排序算法
    • CSP-J 040 链表
    • CSP-J 041 队列
    • CSP-J 042 栈
    • CSP-J 043 树
    • CSP-J 044 二叉树
    • CSP-J 045 二叉树的遍历
    • CSP-J 046 哈夫曼树
    • CSP-J 047 二叉搜索树
    • CSP-J 048 图
  • C++ CSP-J4 算法与数据结构进阶
    • CSP- J 051 搜索与回溯
    • CSP-J 049 倍增法
    • CSP-J 050 贪心
    • CSP-J 051 动态规划 – 引论
    • CSP-J 052 动态规划 – 背包问题
    • CSP-J 053 动态规划 – 区间规划问题
    • CSP-J 054 动态规划综合
  • C++ Qt
    • 01 Qt简介
    • 02 Qt开发环境搭建
    • 03 第一个Qt程序
    • 04 UI常用组件
    • 05 UI布局管理器
    • 06 信号和槽
    • 07 程序界面美化
    • 08 多窗口交互
    • 09 项目-图像处理工具
    • 10 项目-视频播放器
  • C++ 考级
    • 2023年GESP
    • 2024年GESP
    • 密码保护:C++ NOC – 模拟试卷
    • C++ PSTK – 5
  • C++竞赛 CSP
    • 2019-CSP-J1
    • 2019-CSP-J2
    • 2019-CSP-S1
    • 2019-CSP-S2
    • 2020-CSP-J1
    • 2020-CSP-J2
    • 2020-CSP-S1
    • 2020-CSP-S2
    • 2021-CSP-J1
    • 2021-CSP-J2
    • 2021-CSP-S1
    • 2021-CSP-S2
    • 2022-CSP-J1
    • 2022-CSP-J2
    • 2022-CSP-S1
    • 2022-CSP-S2
    • 2023-CSP-J1
    • 2023-CSP-J2
    • 2023-CSP-S1
  • C++竞赛 NOIP
    • NOIP-2007
    • NOIP-2008
    • NOIP-2009
    • NOIP-2010
    • NOIP-2011
    • NOIP-2012
    • NOIP-2013
    • NOIP-2014
    • NOIP-2015
    • NOIP-2016
    • NOIP-2017
    • NOIP-2018
    • NOIP-2020
    • NOIP-2021
  • C++第 1 期
    • 001 初识C++
    • 002 搭建学习环境
    • 003 程序的基本结构
    • 004 变量和基本数据类型1
    • 005 变量和基本数据类型2
    • 006 变量的初始化
    • 007 基本运算符1
    • 008 基本运算符2
    • 008-1 洛谷大挑战 – 1
    • 009 基本运算符3
    • 010 输入输出
    • 011 细说布尔变量
    • 012 关系运算符与判断语句
    • 013 if 的嵌套_和_逻辑运算与
    • 014 else if
    • 015 逻辑运算或
    • 016 逻辑运算非
    • 017 逻辑运算之间的关系1
    • 018 逻辑运算之间的关系2
    • 018-1 洛谷大挑战 – 2
    • 019 循环语句while
    • 020 作用域1
    • 021 作用域2
    • 022 循环语句while嵌套
    • 023 循环语句for
    • 024 循环语句for嵌套
    • 024-1 洛谷大挑战 – 3
    • 025 计算机硬件系统
    • 026 十进制
    • 027 二进制
    • 028 十六进制和八进制
    • 029 内存1
    • 030 内存2
    • 031 数据类型转化1
    • 032 数据类型转化2
    • 032-1 位运算:与(&) 或(|) 非(~)
    • 032-2 位运算:异或(^) 左移 右移
    • 032-3 洛谷大挑战 – 4
  • C++第 2 期
    • 033 字符类型 char
    • 034 字符串 char[]
    • 035 字符串 char[] 输出
    • 036 字符串 char[] 输入
    • 037 数组 – 定义
    • 038 数组 – 遍历
    • 039 数组 – 程序结构
    • 040 数组 – 排序
    • 040-1 洛谷大挑战 – 5
    • 041 变量的地址1
    • 042 变量的地址2
    • 043 地址和指针
    • 044 实践 – 绘画
    • 045 实践 – 字符动画
    • 046 实践 – 移动动画
    • 047 实践 – 按键控制
    • 048 加加语法的差异
    • 048-1 洛谷大挑战 – 6
    • 049 do while
    • 050 三目运算符和switch
    • 051 C语言的输出 – 指定类型
    • 052 C语言的输出 – 左右对齐
    • 053 C语言的输出 – 指定长度
    • 054 转义字符 – 换行和回退
    • 055 转义字符 – 斜杆r
    • 056 转义字符 – 常用总结
    • 056-1 洛谷大挑战 – 7
    • 057 C语言的输入
    • 058 常量
    • 059 函数 – 定义
    • 060 函数 – 声明和实现的分离
    • 061 函数 – 值传递和引用传递
    • 062 函数 – 指针传递(一维数组的处理)
    • 063 函数 – 重载
    • 064 头文件详解
    • 064-1 编辑、编译的概念
    • 064-2 解释,调试(Debug) 的概念
    • 064-3 洛谷大挑战 – 8
  • C++第 3 期
    • 065 二维数组
    • 066 字符串函数1
    • 067 字符串函数2
    • 068 标准库 string – 基本操作
    • 069 标准库 string – 常用操作
    • 070 标准库 string – 高级操作
    • 071 sscanf 和 sprintf
    • 072 枚举和 switch
    • 073 结构体
    • 074 类
    • 075 原码
    • 076 反码和补码
    • 077 内存中的浮点数
    • 078 计算机网络
    • 079 Internet
    • 密码保护:080 Linux 操作系统 – 安装
    • 密码保护:081 Linux 操作系统 – 基本操作
    • 密码保护:082 Linux 操作系统 – noip答题系统
    • 083 总复习:计算机程序的发展历程及NOI相关活动
    • 084 总复习:进制转化
    • 085 总复习:原码 补码 反码的计算
    • 086 总复习:顺序结构
    • 087 总复习:输入输出
    • 088 总复习:控制结构
    • 089 总复习:循环结构
    • 090 总复习:数组
    • 091 总复习:函数
    • 092 总复习:文件 – fopen、freopen
    • 093 总复习:文件 – 文件输入输出流
    • 094 总复习:结构体
    • 095 总复习:指针 – 基础、数组、字符串
    • 096 总复习:指针 – 函数、结构体
    • 096-1 g++编译器的基本使用
    • 096-2 gcc编译器的基本使用
    • 096-3 自顶向下逐步求精的模块化程序设计
    • 096-4 数学库常用函数
  • C++第 4 期
    • 097 算法概念
    • 098 算法描述: 自然语言 流程图 伪代码
    • 099 枚举法
    • 100 模拟法
    • 101 精讲精练 – 枚举法
    • 102 精讲精练 – 模拟法
    • 103 高精度计算 – 加法
    • 104 高精度计算 – 减法
    • 105 高精度计算 – 乘法
    • 106 高精度计算 – 高精度除以单精度
    • 107 高精度计算 – 高精除以高精
    • 108 精讲精练 – 高精度加法和减法
    • 109 精讲精练 – 高精度乘法
    • 110 精讲精练 – 高精度除法
    • 111 排序的基本概念
    • 112 数据排序 – 选择排序
    • 113 数据排序 – 冒泡排序
    • 114 数据排序 – 插入排序
    • 115 数据排序 – 对比和小结
    • 116 精讲精练 – 冒泡排序
    • 117 精讲精练 – 选择排序
    • 118 精讲精练 – 插入排序
    • 118-1 数据排序 – 桶排序
    • 118-2 数据排序 – 快速排序
    • 118-3 数据排序 – 归并排序
    • 118-4 数据排序 – 逆序对
    • 119 递推 – 概述习题一
    • 120 递推 – 概述习题二
    • 121 递推 – Fibonacci 数列
    • 122 递推 – Hanoi 塔问题
    • 123 递推 – 平面分隔
    • 124 递推 – Catalan 数
    • 125 递推 – 第二类 Stirling 数
    • 126 精讲精练 – 递推
    • 127 精讲精练 – 递推
    • 128 精讲精练 – 递推
  • C++第 5 期
    • 129 递归 – 引例
    • 130 递归 – Hanoi 塔问题
    • 131 递归 – 斐波那契数列
    • 132 递归 – 集合划分
    • 133 递归 – 数的计数
    • 134 递归 – 小结
    • 135 精讲精练 – 递归
    • 136 精讲精练 – 递归
    • 137 精讲精练 – 递归
    • 138 贪心 – 概述
    • 139 贪心 – 排队打水
    • 140 贪心 – 均分纸牌
    • 141 贪心 – 删数问题
    • 142 贪心 – 拦截导弹
    • 143 贪心 – 活动选择
    • 144 贪心 – 整数区间
    • 145 贪心 – 小结
    • 146 精讲精练 – 贪心
    • 147 精讲精练 – 贪心
    • 148 精讲精练 – 贪心
    • 149 二分法 – 概述
    • 150 二分法 -两种写法
    • 151 二分法 -经典例题1
    • 152 二分法 -经典例题2
    • 153 精讲精练 – 二分法
    • 154 精讲精练 – 二分法
    • 155 倍增法 – 概述
    • 密码保护:156 倍增法 –
    • 密码保护:157 倍增法 –
    • 密码保护:158 倍增法 –
    • 密码保护:159 精讲精练 – 倍增法
    • 密码保护:160 精讲精练 – 倍增法
    • 160-1 搜索与回溯 – 概述
  • C++第 6 期
    • 161 动态规划 – 动态规划的基本概念和基本模型构成
    • 162 动态规划 – 最优化原理与无后效性原则
    • 163 动态规划 – 多阶段决策过程的最优化问题
    • 164 动态规划 – 简单一维动态规划
    • 165 动态规划 – 简单背包类型动态规划
    • 166 动态规划 – 简单背包类型动态规划
    • 167 动态规划 – 简单背包类型动态规划
    • 168 动态规划 – 简单背包类型动态规划
    • 169 动态规划 – 简单区间类型动态规划
    • 170 动态规划 – 简单区间类型动态规划
    • 171 动态规划 – 简单区间类型动态规划
    • 172 动态规划 – 简单区间类型动态规划
    • 173 动态规划 – 数字金字塔1
    • 174 动态规划 – 数字金字塔2
    • 175 动态规划 – 最长不下降序列
    • 176 动态规划 – 拦截导弹
    • 177 动态规划 – 城市网
    • 178 动态规划 – 挖地雷
    • 179 动态规划 – 友好城市
    • 180 动态规划 – 合唱队形
    • 181 动态规划 – 最长公共子序列
    • 182 动态规划 – 机器分配
    • 183 栈 – 概念
    • 184 栈 -顺序栈操作
    • 185 栈 -链栈基本操作
    • 186 精讲精练 – 括号匹配
    • 187 精讲精练 – 表达式求值
    • 188 精讲精练 – 后缀表达式的转换
    • 189 精讲精练 – 车厢调度问题
    • 190 队列 – 概念
    • 191 队列 -顺序队列
    • 192 队列 -链式队列
  • C++第 7 期
    • 193 精讲精练 – 循环队列
    • 194 精讲精练 – 队列
    • 195 精讲精练 – 队列
    • 196 精讲精练 – 队列
    • 197 链表 – 基本概念
    • 198 单链表
    • 199 双向链表
    • 200 循环链表实现约瑟夫环
    • 201 精讲精练 – 双向链表的操作
    • 202 精讲精练 – 单链表的反转
    • 203 精讲精练 – 判断链表中是否存在环
    • 204 精讲精练 – 环形链表的入口
    • 205 树的定义及概念
    • 206 树和树的存储结构
    • 207 树的父亲表示法
    • 208 树的遍历
    • 209 二叉树基本概念和性质
    • 210 二叉树的存储结构
    • 211 二叉树的建立和删除
    • 212 二叉树的插入与查找
    • 213 树 – 嵌套括号表示法
    • 214 二叉树的遍历 – 前序
    • 215 二叉树的遍历 – 中序
    • 216 二叉树的遍历 – 后序
    • 217 普通树转二叉树
    • 218 树的计数
    • 219 哈夫曼树(赫夫曼树、最优树)
    • 220 精讲精练 – 从中序与后序遍历序列构造二叉树
    • 221 精讲精练 – 对称二叉树
    • 222 精讲精练 – 二叉树的下一个节点
    • 223 精讲精练 – 二叉树的深度
    • 224 精讲精练 – 树的子结构
  • C++第 8 期
    • 225 完全二叉树的定义与基本性质
    • 226 完全二叉树的数组表示法
    • 227 哈夫曼树的定义及构造
    • 228 哈夫曼树的遍历
    • 229 二叉排序树的定义及构造
    • 230 二叉排序树的遍历
    • 231 精讲精练 – 完全二叉树 1
    • 232 精讲精练 – 完全二叉树 2
    • 233 精讲精练 – 哈夫曼树
    • 234 精讲精练 – 二叉排序树
    • 235 图的定义及基本概念
    • 236 图的存储结构
    • 237 图的邻接矩阵存储
    • 密码保护:238 图的邻接表存储
    • 密码保护:239 精讲精练 – 图的存储 1
    • 密码保护:240 精讲精练 – 图的存储 2
    • 密码保护:241 精讲精练 – 图的存储 3
    • 密码保护:242 精讲精练 – 图的存储 4
    • 密码保护:243 图的深度优先遍历
    • 密码保护:244 图的宽度优先遍历
    • 密码保护:245 洪水填充算法
    • 密码保护:246 精讲精练 – 图的遍历 1
    • 密码保护:247 精讲精练 – 图的遍历 2
    • 密码保护:248 精讲精练 – 图的遍历 3
    • 密码保护:249 精讲精练 – 图的遍历 4
    • 密码保护:250 总复习 – 排序算法
    • 密码保护:251 总复习 – 动态规划
    • 密码保护:252 总复习 – 图论算法
    • 密码保护:253 总复习 – 线性表
    • 密码保护:254 总复习 – 简单树
    • 密码保护:255 总复习 – 特殊树
    • 密码保护:256 总复习 – 简单图
  • C++第 9 期
    • 密码保护:257 STL模板的概念及应用
    • 密码保护:258 STL – algorithm库(sort)
    • 密码保护:259 STL – 栈(stack)
    • 密码保护:260 STL – 队列(queue)
    • 密码保护:261 STL – 链表(list)
    • 密码保护:262 STL – 向量(vector)
    • 密码保护:263 STL – 字符串(string)
    • 密码保护:264 STL – 集合(set)
    • 密码保护:265 精讲精练 – STL (sort 栈 队列)
    • 密码保护:266 精讲精练 – STL (链表 向量)
    • 密码保护:267 精讲精练 – STL(字符串 集合)
    • 密码保护:268 哈夫曼编码
    • 密码保护:269 格雷码
    • 密码保护:270 初中代数
    • 密码保护:271 初中平面几何
    • 密码保护:272 整数 因数 倍数和指数的概念
    • 密码保护:273 质数 合数 同余和素数的概念
    • 密码保护:274 唯一分解定理
    • 密码保护:275 欧几里德算法(辗转相除法)
    • 密码保护:276 埃氏筛法求素数
    • 密码保护:277 线性筛法求素数
    • 密码保护:278 加法原理
    • 密码保护:279 乘法原理
    • 密码保护:280 排列及计算公式
    • 密码保护:281 组合及计算公式
    • 密码保护:282 杨辉三角公式
    • 密码保护:283 精讲精练 – 真题 1
    • 密码保护:284 精讲精练 – 真题 2
    • 密码保护:285 精讲精练 – 真题 3
    • 密码保护:286 精讲精练 – 真题 4
    • 密码保护:287 精讲精练 – 真题 5
    • 密码保护:288 精讲精练 – 真题 6

5 创客

  • 创客课程介绍
  • Arduino入门与实践
    • 01-初识创客套装
    • 02-灯光告诉你
    • 03-会呼吸的灯
    • 04-认识光的世界
    • 05-探秘电子之声
    • 06-智能光控灯
    • 07-声控报警器
    • 08-神奇的旋钮
    • 09-调速流水灯
    • 10-声光大综合
    • 11-进入开关世界
    • 12-火焰报警装置
    • 13-高温提醒装置
    • 14-遥控器的秘密
    • 15-地震报警
    • 16-气象监测
    • 17-硬币计数器
    • 18-触摸台灯
    • 19-激光防盗
    • 20-霍尔开关
    • 21-烟雾报警
    • 22-打地鼠游戏
    • 23-继电器
    • 24-倒车雷达
    • 25-智能避障小车
    • 26-自动驾驶
    • 27-智能循迹小车
    • 28-超声波测距仪
    • 29-智能跟随小车
    • 30-旋转编码器
    • 31-LCD显示屏
    • 32-感应雨刮器
  • 创客第 1 期 - 积木搭建
    • 001 入门
    • 002 认识结构体
    • 003 秋千
    • 004 跷跷板
    • 005 打蛋器
    • 006课 奇怪的时钟
    • 007 起重机
    • 008 烤肉架
    • 009 手动风扇
    • 010 履带车
  • 创客第 2 期 - 积木进阶
    • 001 直升机
    • 002 后轮驱动车
    • 003 毛毛虫
    • 004 石油开采机
    • 005 稻草人
    • 006 舂米机
    • 007 乌龟
    • 008 挖掘机
    • 009 旋转杯子
    • 010 缝纫机
    • 011 六足步行机器人
  • 创客第 3 期 - Mind+/Mixly与Arduino (拓展)
    • Arduino第01课 入门
    • Arduino第02课 双色LED实验
    • Arduino第03课 RGB-LED实验
    • Arduino第04课 七彩LED闪烁实验
    • Arduino第05课 继电器实验
    • Arduino第06课 激光传感器实验
    • Arduino第07课 轻触开关按键实验
    • Arduino第08课 倾斜开关传感器实验
    • Arduino第09课 振动开关传感器实验
    • Arduino第10课 红外遥控实验
    • Arduino第11课 蜂鸣器实验
    • Arduino第12课 干簧管传感器实验
    • Arduino第13课 U型光电传感器
    • Arduino第14课 雨滴探测传感器
    • Arduino第15课 PS2操纵杆实验
    • Arduino第16课 电位器传感器实验
    • Arduino第17课 模拟霍尔传感器实验
    • Arduino第18课 模拟温度传感器
    • Arduino第19课 声音传感器实验
    • Arduino第20课 光敏电阻传感器实验
    • Arduino第21课 火焰报警传感器实验
    • Arduino第22课 烟雾传感器实验
    • Arduino第23课 触摸开关传感器实验
    • Arduino第24课 I2C LCD1602显示器
    • Arduino第25课 超声波传感器实验
    • Arduino第26课 循迹传感器实验
    • Arduino第27课 红外避障传感器实验
    • Arduino第28课 语音合成模块
    • Arduino第29课 舵机
    • Arduino第30课 OLED显示屏幕
    • Arduino第31课 考级课程一–走进智能殿堂
    • Arduino第32-33课 考级课程二–炫彩流水灯
    • Arduino第34-35课 考级课程三–智能红绿灯
  • 创客第4期 - C/C++与Arduino (拓展)
    • Arduino C/C++ 第01课 入门
    • Arduino C/C++ 第02课 双色LED灯
    • Arduino C/C++ 第03课 RGB-LED灯
    • Arduino C/C++ 第04课 蜂鸣器播放器
    • ARDUINO C/C++ 第05课 轻触开关按键
    • ARDUINO C/C++ 第06课 旋转编码器
    • ARDUINO C/C++ 第07课 人体红外传感器
    • ARDUINO C/C++ 第08课 4×4薄膜矩阵键盘

6 PPT创作

  • 01 PPT基础操作回顾
  • 02 PPT基础操作SmartArt
  • 03 PPT制作思路—梳理大纲
  • 04 布尔逻辑、缩放定位
  • 05 如何DIY任意图形
  • 06 制作幻灯片母版
  • 07 文字排版设计
  • 08 段落的排版技巧
  • 09 封面设计技巧
  • 10 配色技巧
  • 11 剪纸风格设计
  • 12 孟菲斯风格设计
  • 13 水彩风格设计
  • 14 个性极简风
  • 15 古典中式风
  • 16 新中式古典风
  • 17 思维导图上
  • 18 思维导图下
  • 19 课程回顾
  • 20 动画特效

7 科创课题

  • 科创课题

8 关于我们

  • ① 关于我们
  • ② 学习路线
  • ③ 科创升学
  • ④ 成果展示
  • ⑤ 常见问题
View Categories
  • 大师码
  • Docs
  • 4 C++
  • C++ CSP-J3 算法与数据结构入门
  • CSP-J 038 高精度算法

6 min read

1. 概述 #

高精度数的概念 #

整数和小数有计算精度的限制。比如:

  • unsigned long long 的最大值: 1844 6744 0737 0955 1615 (一千八百多万亿)
  • long double 的范围: 1.18973e+4932 ~ 3.3621e-4932

太大的数,或者小数点太多的数,在计算上有限制。就需要使用特殊的处理方法。这就称为高精度计算。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字。一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算。对于非常庞大的数字无法在计算机中正常存储,于是,将这个数字拆开,拆成一位一位的,或者是四位四位的存储到一个数组中, 用一个数组去表示一个数字,这样这个数字就被称为是高精度数。

数据的接收和存贮 #

  • 当输入的数很长时,可采用字符串方式输入。

这样可以输入位数很长的数,利用字符串函数和操作运算,将每一位数取出,存入数组中。
因为数组存放的元素顺序与我们计算的顺序是相反的,在竖式计算中我们是将其右对齐(个位对个位,十位对十位,以此类推),而读取数字后的两个数组是左对齐的,因此我们要将里面的元素逆置。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
请读入下面的数:
123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789
示例程序:
void init()
{
string s;
cin >> s; // 读入字符串
len = s.length();
for(i=0; i <= len; ++i) //逆置元素
a[i]=s[len-1] - '0'; // 将字符转化成数字
}
请读入下面的数: 123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789 示例程序: void init() { string s; cin >> s; // 读入字符串 len = s.length(); for(i=0; i <= len; ++i) //逆置元素 a[i]=s[len-1] - '0'; // 将字符转化成数字 }
请读入下面的数:
123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789

示例程序:
void init()
{
    string s;
    cin >> s; // 读入字符串
    len = s.length();
    for(i=0; i <= len; ++i) //逆置元素
        a[i]=s[len-1] - '0';   // 将字符转化成数字
}

高精度数位数的确定 #

  • 方法:接收时往往是用字符串,所以它的位数就等于字符串的长度。

进位,错位处理 #

下面例程中的 a b c 均为整形数组。

  • 加法进位:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
c[i] = a[i]+b[i];
if(c[i] >= 10)
{
c[i] %= 10;
++c[i+1];
}
c[i] = a[i]+b[i]; if(c[i] >= 10) { c[i] %= 10; ++c[i+1]; }
c[i] = a[i]+b[i];
if(c[i] >= 10)
{
    c[i] %= 10;
    ++c[i+1];
}
  • 减法借位:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if(a[i] < b[i])
{
--a[i+1];
a[i]+=10;
}
c[i] = a[i]-b[i];
if(a[i] < b[i]) { --a[i+1]; a[i]+=10; } c[i] = a[i]-b[i];
if(a[i] < b[i])
{
    --a[i+1];
    a[i]+=10;
}
c[i] = a[i]-b[i];

2. 高精度加法 #

请输入两个数,计算它们的和。

【算法分析】
竖式方法举例:962+93

【例程】

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include < iostream >
#include < string >
using namespace std;
//高精度加法函数
void add(int a[], int a_len, int b[], int b_len, int* result, int& result_len)
{
int i = 0, x = 0;
result_len = 0;
int max_a_b = a_len > b_len ? a_len : b_len;
while (i< max_a_b)
{
int sub_a = i < a_len ? a[i] : 0; //判断i是否超过数组a的长度,若超过该位为0
int sub_b = i < b_len ? b[i] : 0; //判断i是否超过数组b的长度,若超过该位为0
result[i] = sub_a + sub_b + x;//逐位相加
x = result[i] / 10;
result[i] %= 10;
result_len++;
i++;
}
if (x != 0)
{
result[i] = x;
++result_len;
}
}
int main()
{
string astr, bstr;
cin >> astr;
cin >> bstr;
int lena = astr.size(), lenb = bstr.size();
int a[100], b[100];
for (int i = 0; i< lena; ++i)
a[lena - i - 1] = astr[i] - '0'; // 将数字倒过来,并转化成数字
for (int i = 0; i< lenb; ++i)
b[lenb - i - 1] = bstr[i] - '0';
int c[100] = { 0 }, lenc=0;
add(a, lena, b, lenb, c, lenc); // 计算
for (int i = 0; i < lenc; ++i)
{
cout << c[lenc - i - 1]; // 再将数字倒过来输出
}
cout << endl;
return 0;
}
#include < iostream > #include < string > using namespace std; //高精度加法函数 void add(int a[], int a_len, int b[], int b_len, int* result, int& result_len) { int i = 0, x = 0; result_len = 0; int max_a_b = a_len > b_len ? a_len : b_len; while (i< max_a_b) { int sub_a = i < a_len ? a[i] : 0; //判断i是否超过数组a的长度,若超过该位为0 int sub_b = i < b_len ? b[i] : 0; //判断i是否超过数组b的长度,若超过该位为0 result[i] = sub_a + sub_b + x;//逐位相加 x = result[i] / 10; result[i] %= 10; result_len++; i++; } if (x != 0) { result[i] = x; ++result_len; } } int main() { string astr, bstr; cin >> astr; cin >> bstr; int lena = astr.size(), lenb = bstr.size(); int a[100], b[100]; for (int i = 0; i< lena; ++i) a[lena - i - 1] = astr[i] - '0'; // 将数字倒过来,并转化成数字 for (int i = 0; i< lenb; ++i) b[lenb - i - 1] = bstr[i] - '0'; int c[100] = { 0 }, lenc=0; add(a, lena, b, lenb, c, lenc); // 计算 for (int i = 0; i < lenc; ++i) { cout << c[lenc - i - 1]; // 再将数字倒过来输出 } cout << endl; return 0; }
#include < iostream >
#include < string >
using namespace std;
//高精度加法函数
void add(int a[], int a_len, int b[], int b_len, int* result, int& result_len)
{
    int i = 0, x = 0;
    result_len = 0;
    int max_a_b = a_len > b_len ? a_len : b_len;
    while (i< max_a_b)
    {
        int sub_a = i < a_len ? a[i] : 0; //判断i是否超过数组a的长度,若超过该位为0
        int sub_b = i < b_len ? b[i] : 0; //判断i是否超过数组b的长度,若超过该位为0

        result[i] = sub_a + sub_b + x;//逐位相加
        x = result[i] / 10;
        result[i] %= 10;
        result_len++;
        i++;
    }
    if (x != 0)
    {
        result[i] = x;
        ++result_len;
    }
}

int main()
{
    string astr, bstr;
    cin >> astr;
    cin >> bstr;

    int lena = astr.size(), lenb = bstr.size();
    int a[100], b[100];
    for (int i = 0; i< lena; ++i)
        a[lena - i - 1] = astr[i] - '0'; // 将数字倒过来,并转化成数字

    for (int i = 0; i< lenb; ++i)
        b[lenb - i - 1] = bstr[i] - '0';

    int c[100] = { 0 }, lenc=0;
    add(a, lena, b, lenb, c, lenc); // 计算

    for (int i = 0; i < lenc; ++i)
    {
        cout << c[lenc - i - 1]; // 再将数字倒过来输出
    }
    cout << endl;
    return 0;
}

3. 高精度乘法 #

进位和错位处理:高精度✖️单精度 #

先考虑一个简单的情况:乘数中的一个是普通的 int 类型。有没有简单的处理方法呢?
一个直观的思路是直接将a每一位上的数字乘以b。从数值上来说,这个方法是正确的,但它并不符合十进制表示法,因此需要将它重新整理成正常的样子。
重整的方式,也是从个位开始逐位向上处理进位。但是这里的进位可能非常大,甚至远大于9,因为每一位被乘上之后都可能达到9b的数量级。所以这里的进位不能再简单地进行-10运算,而是要通过除以10的商以及余数计算。详见代码注释,也可以参考下图展示的一个计算高精度数1337乘以单精度数42的过程。

当然,也是出于这个原因,这个方法需要特别关注乘数b的范围。若它和 10^9(或相应整型的取值上界)属于同一数量级,那么需要慎用高精度—单精度乘法。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
void mul_short(int a[], int b, int c[]) {
clear(c);
for (int i = 0; i < LEN - 1; ++i) {
// 直接把 a 的第 i 位数码乘以乘数,加入结果
c[i] += a[i] * b;
if (c[i] >= 10) {
// 处理进位
// c[i] / 10 即除法的商数成为进位的增量值
c[i + 1] += c[i] / 10;
// 而 c[i] % 10 即除法的余数成为在当前位留下的值
c[i] %= 10;
}
}
}
void mul_short(int a[], int b, int c[]) { clear(c); for (int i = 0; i < LEN - 1; ++i) { // 直接把 a 的第 i 位数码乘以乘数,加入结果 c[i] += a[i] * b; if (c[i] >= 10) { // 处理进位 // c[i] / 10 即除法的商数成为进位的增量值 c[i + 1] += c[i] / 10; // 而 c[i] % 10 即除法的余数成为在当前位留下的值 c[i] %= 10; } } }
void mul_short(int a[], int b, int c[]) {
  clear(c);

  for (int i = 0; i < LEN - 1; ++i) {
    // 直接把 a 的第 i 位数码乘以乘数,加入结果
    c[i] += a[i] * b;

    if (c[i] >= 10) {
      // 处理进位
      // c[i] / 10 即除法的商数成为进位的增量值
      c[i + 1] += c[i] / 10;
      // 而 c[i] % 10 即除法的余数成为在当前位留下的值
      c[i] %= 10;
    }
  }
}

进位和错位处理:高精度✖️高精度 #

如果两个乘数都是高精度,那么竖式乘法又可以大显身手。
于是可以将b分解为它的所有数码,其中每个数码都是单精度数,将它们分别与a相乘,再向左移动到各自的位置上相加即得答案。当然,最后也需要用与上例相同的方式处理进位。

注意这个过程与竖式乘法不尽相同,我们的算法在每一步乘的过程中并不进位,而是将所有的结果保留在对应的位置上,到最后再统一处理进位,但这不会影响结果。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
void mul(int a[], int b[], int c[]) {
clear(c);
for (int i = 0; i < LEN - 1; ++i) {
// 这里直接计算结果中的从低到高第 i 位,且一并处理了进位
// 第 i 次循环为 c[i] 加上了所有满足 p + q = i 的 a[p] 与 b[q] 的乘积之和
// 这样做的效果和直接进行上图的运算最后求和是一样的,只是更加简短的一种实现方式
for (int j = 0; j <= i; ++j) c[i] += a[j] * b[i - j];
if (c[i] >= 10) {
c[i + 1] += c[i] / 10;
c[i] %= 10;
}
}
}
void mul(int a[], int b[], int c[]) { clear(c); for (int i = 0; i < LEN - 1; ++i) { // 这里直接计算结果中的从低到高第 i 位,且一并处理了进位 // 第 i 次循环为 c[i] 加上了所有满足 p + q = i 的 a[p] 与 b[q] 的乘积之和 // 这样做的效果和直接进行上图的运算最后求和是一样的,只是更加简短的一种实现方式 for (int j = 0; j <= i; ++j) c[i] += a[j] * b[i - j]; if (c[i] >= 10) { c[i + 1] += c[i] / 10; c[i] %= 10; } } }
void mul(int a[], int b[], int c[]) {
  clear(c);

  for (int i = 0; i < LEN - 1; ++i) {
    // 这里直接计算结果中的从低到高第 i 位,且一并处理了进位
    // 第 i 次循环为 c[i] 加上了所有满足 p + q = i 的 a[p] 与 b[q] 的乘积之和
    // 这样做的效果和直接进行上图的运算最后求和是一样的,只是更加简短的一种实现方式
    for (int j = 0; j <= i; ++j) c[i] += a[j] * b[i - j];

    if (c[i] >= 10) {
      c[i + 1] += c[i] / 10;
      c[i] %= 10;
    }
  }
}

高精度乘法实现 #

请输入两个数,计算它们的积。

【算法分析】
竖式方法举例:

  • 25*836
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
int b[] = {2,5};
int a[] = {8,3,6};
b1 b0
___x_____a2_a1_a0__
c2 c1 c0
d2 d1 d0
___e2_e1_e0________
f5 f4 f3 f2 f1 f0
我们不妨改一下数据的下标,以便于更好的理解下面的代码。
b1 b0
___x_____a2_a1_a0__
c2 c1 c0
d3 d2 d1
___e4_e3_e2________
f5 f4 f3 f2 f1 f0
## 1
fi 的计算过程推导,是代码实现的关键。
1. f的序号和ab有什么关系?为什么是【f序号 = a序号 + b序号】
2. fi的值,是一个累加过程。
## 2
两数乘积的位数,如何确定?
f5 可能没有吗?
int b[] = {2,5}; int a[] = {8,3,6}; b1 b0 ___x_____a2_a1_a0__ c2 c1 c0 d2 d1 d0 ___e2_e1_e0________ f5 f4 f3 f2 f1 f0 我们不妨改一下数据的下标,以便于更好的理解下面的代码。 b1 b0 ___x_____a2_a1_a0__ c2 c1 c0 d3 d2 d1 ___e4_e3_e2________ f5 f4 f3 f2 f1 f0 ## 1 fi 的计算过程推导,是代码实现的关键。 1. f的序号和ab有什么关系?为什么是【f序号 = a序号 + b序号】 2. fi的值,是一个累加过程。 ## 2 两数乘积的位数,如何确定? f5 可能没有吗?
int b[] = {2,5};
int a[] = {8,3,6};

            b1 b0
___x_____a2_a1_a0__
         c2 c1 c0
      d2 d1 d0     
___e2_e1_e0________
f5 f4 f3 f2 f1 f0


我们不妨改一下数据的下标,以便于更好的理解下面的代码。
            b1 b0
___x_____a2_a1_a0__
         c2 c1 c0
      d3 d2 d1     
___e4_e3_e2________
f5 f4 f3 f2 f1 f0

## 1 
fi 的计算过程推导,是代码实现的关键。
1. f的序号和ab有什么关系?为什么是【f序号 = a序号 + b序号】
2. fi的值,是一个累加过程。

## 2 
两数乘积的位数,如何确定?
f5 可能没有吗?

【例程】

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include < iostream >
#include < string >
using namespace std;
void multiply(int a[], int b[], int a_len, int b_len, int* f, int& f_len)
{
int i = 0, x = 0;
f_len = 0;
for (int i = 0; i < a_len; ++i)
{
int x = 0; // x 表示进位
for (int j = 0; j < b_len; ++j)
{
// 乘法核心代码
f[i+j] += a[i] * b[j] + x;
x = f[i+j] / 10;
f[i+j] %= 10;
}
f[i + b_len] = x;
}
// 根据最后一位是否为 0 ,判断计算结果的位数
if (f[a_len + b_len - 1] == 0)
f_len = a_len + b_len - 1;
else
f_len = a_len + b_len;
}
int main()
{
// 从屏幕获得输入
string astr, bstr;
cin >> astr;
cin >> bstr;
int lena = astr.size(), lenb = bstr.size();
int a[100] = { 0 }, b[100] = { 0 }; // 假设数字的位数不超过 100
for (int i = 0; i < lena; ++i)
a[lena - i - 1] = astr[i] - '0'; // 将数字倒过来
for (int i = 0; i < lenb; ++i)
b[lenb - i - 1] = bstr[i] - '0';
// 计算高精度乘法
int f[100] = { 0 }, lenf(0);
multiply(a, b, lena, lenb, f, lenf); // 必须是两个非负数,且 a 大于 b
// 输出结果
for (int i = 0; i < lenf; ++i)
{
cout << f[lenf - i - 1];
}
cout << endl;
return 0;
}
#include < iostream > #include < string > using namespace std; void multiply(int a[], int b[], int a_len, int b_len, int* f, int& f_len) { int i = 0, x = 0; f_len = 0; for (int i = 0; i < a_len; ++i) { int x = 0; // x 表示进位 for (int j = 0; j < b_len; ++j) { // 乘法核心代码 f[i+j] += a[i] * b[j] + x; x = f[i+j] / 10; f[i+j] %= 10; } f[i + b_len] = x; } // 根据最后一位是否为 0 ,判断计算结果的位数 if (f[a_len + b_len - 1] == 0) f_len = a_len + b_len - 1; else f_len = a_len + b_len; } int main() { // 从屏幕获得输入 string astr, bstr; cin >> astr; cin >> bstr; int lena = astr.size(), lenb = bstr.size(); int a[100] = { 0 }, b[100] = { 0 }; // 假设数字的位数不超过 100 for (int i = 0; i < lena; ++i) a[lena - i - 1] = astr[i] - '0'; // 将数字倒过来 for (int i = 0; i < lenb; ++i) b[lenb - i - 1] = bstr[i] - '0'; // 计算高精度乘法 int f[100] = { 0 }, lenf(0); multiply(a, b, lena, lenb, f, lenf); // 必须是两个非负数,且 a 大于 b // 输出结果 for (int i = 0; i < lenf; ++i) { cout << f[lenf - i - 1]; } cout << endl; return 0; }
#include < iostream >
#include < string >
using namespace std;


void multiply(int a[], int b[], int a_len, int b_len, int* f, int& f_len)
{
    int i = 0, x = 0;
    f_len = 0;

    for (int i = 0; i < a_len; ++i)
    {
        int x = 0; // x 表示进位
        for (int j = 0; j < b_len; ++j)
        {
            // 乘法核心代码
            f[i+j] += a[i] * b[j] + x;
            x = f[i+j] / 10;
            f[i+j] %= 10;
        }
        f[i + b_len] = x;
    }

    // 根据最后一位是否为 0 ,判断计算结果的位数
    if (f[a_len + b_len - 1] == 0)
        f_len = a_len + b_len - 1;
    else
        f_len = a_len + b_len;
}

int main()
{
    // 从屏幕获得输入
    string astr, bstr;
    cin >> astr;
    cin >> bstr;

    int lena = astr.size(), lenb = bstr.size();
    int a[100] = { 0 }, b[100] = { 0 }; // 假设数字的位数不超过 100
    for (int i = 0; i < lena; ++i)
        a[lena - i - 1] = astr[i] - '0'; // 将数字倒过来

    for (int i = 0; i < lenb; ++i)
        b[lenb - i - 1] = bstr[i] - '0';


    // 计算高精度乘法
    int f[100] = { 0 }, lenf(0);
    multiply(a, b, lena, lenb, f, lenf); // 必须是两个非负数,且 a 大于 b


    // 输出结果
    for (int i = 0; i < lenf; ++i)
    {
        cout << f[lenf - i - 1];
    }
    cout << endl;
    return 0;
}

4. 高精度除法 #

高精度除以低精度 #

假设 a 是一个高精度整数,b是一个普通的整数。
【算法分析】
在高精度除以单精度时,从高位到低位逐位相除。最需要注意的问题是,后一位继承前一位的余数问题。
设高精度的数位数字为a[i],单精度数为b,第i+1位除b后的余数位r,把r加到i位时,应乘以进制X,即s=X*r+a[i].

  • 注意位移处理即可
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
int b = 5;
int a[] = {8,3,6};
(1)
_1___
5)836
_5___
3
(2)
_16__
5)836
_5___
33
_30__
3
(3)
_167__
5)836
_5___
33
_30__
36
__35_
1
int b = 5; int a[] = {8,3,6}; (1) _1___ 5)836 _5___ 3 (2) _16__ 5)836 _5___ 33 _30__ 3 (3) _167__ 5)836 _5___ 33 _30__ 36 __35_ 1
    int b = 5;
    int a[] = {8,3,6};

(1)
     _1___
    5)836
     _5___
      3

(2)
     _16__
    5)836
     _5___
      33
     _30__
       3

(3)
     _167__
    5)836
     _5___
      33
     _30__
       36
     __35_
        1

【例程】

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include < iostream >
#include < string >
using namespace std;
void assign(int a[], int a_len, int* dst, int& dst_len)
{
for (int i = 0; i < a_len; ++i)
dst[i] = a[i];
dst_len = a_len;
}
void divide(int a[], int a_len, int b, int* result, int& result_len)
{
int c[100] = { 0 }, lenc = 0; // c 用于存放临时的计算结果
if (a[0] == 0)
{
result_len = 1;
assign(c, 1, result, result_len);
return; // 0是被除数,则商为0
}
int i = 0, x = 0;
result_len = 0;
for (int i = 0; i < a_len; ++i)
{
c[i] = (x * 10 + a[i]) / b;
x = (x * 10 + a[i]) % b;
++lenc;
}
// 去除前部可能出现的 0
int c_startID = 0;
for (; c_startID < 100; ++c_startID)
if (c[c_startID] != 0)
break;
for (int i = c_startID; i < lenc; ++i)
{
result[i - c_startID] = c[i];
++result_len;
}
}
int main()
{
// 从屏幕获得输入 被除数a和除数b均以字符串的形式输入
string astr, bstr;
cin >> astr;
cin >> bstr;
//获得字符串a和b的长度也就是,a和b的位数
int lena = astr.size(), lenb = bstr.size();
//设置数组a[100]高精度数字a
int a[100] = { 0 }, b = 0;
for (int i = 0; i < lena; ++i)
a[i] = astr[i] - '0'; // 除法不需要将数字倒过来
for (int i = 0; i < lenb; ++i)
b += (bstr[i] - '0') * pow(10, lenb - i - 1); // 字符串转 10 进制数
//不能除以0
if (b == 0)
return -1;
// 设置数组c[100]存储计算结果,c[100]中存储的也是高精度的数字
int c[100] = { 0 }, lenc(0);
divide(a, lena, b, c, lenc); // a 是被除数,是高精度值。b是低精度值,用 int 即可存储
// 输出
for (int i = 0; i < lenc; ++i)
{
cout << c[i]; // 正向输出
}
cout << endl;
return 0;
}
#include < iostream > #include < string > using namespace std; void assign(int a[], int a_len, int* dst, int& dst_len) { for (int i = 0; i < a_len; ++i) dst[i] = a[i]; dst_len = a_len; } void divide(int a[], int a_len, int b, int* result, int& result_len) { int c[100] = { 0 }, lenc = 0; // c 用于存放临时的计算结果 if (a[0] == 0) { result_len = 1; assign(c, 1, result, result_len); return; // 0是被除数,则商为0 } int i = 0, x = 0; result_len = 0; for (int i = 0; i < a_len; ++i) { c[i] = (x * 10 + a[i]) / b; x = (x * 10 + a[i]) % b; ++lenc; } // 去除前部可能出现的 0 int c_startID = 0; for (; c_startID < 100; ++c_startID) if (c[c_startID] != 0) break; for (int i = c_startID; i < lenc; ++i) { result[i - c_startID] = c[i]; ++result_len; } } int main() { // 从屏幕获得输入 被除数a和除数b均以字符串的形式输入 string astr, bstr; cin >> astr; cin >> bstr; //获得字符串a和b的长度也就是,a和b的位数 int lena = astr.size(), lenb = bstr.size(); //设置数组a[100]高精度数字a int a[100] = { 0 }, b = 0; for (int i = 0; i < lena; ++i) a[i] = astr[i] - '0'; // 除法不需要将数字倒过来 for (int i = 0; i < lenb; ++i) b += (bstr[i] - '0') * pow(10, lenb - i - 1); // 字符串转 10 进制数 //不能除以0 if (b == 0) return -1; // 设置数组c[100]存储计算结果,c[100]中存储的也是高精度的数字 int c[100] = { 0 }, lenc(0); divide(a, lena, b, c, lenc); // a 是被除数,是高精度值。b是低精度值,用 int 即可存储 // 输出 for (int i = 0; i < lenc; ++i) { cout << c[i]; // 正向输出 } cout << endl; return 0; }
#include < iostream >
#include < string >
using namespace std;

void assign(int a[], int a_len, int* dst, int& dst_len)
{
    for (int i = 0; i < a_len; ++i)
        dst[i] = a[i];
    dst_len = a_len;
}

void divide(int a[], int a_len, int b, int* result, int& result_len)
{
    int c[100] = { 0 }, lenc = 0; // c 用于存放临时的计算结果

    if (a[0] == 0)
    {
        result_len = 1;
        assign(c, 1, result, result_len);
        return; // 0是被除数,则商为0
    }

    int i = 0, x = 0;
    result_len = 0;

    for (int i = 0; i < a_len; ++i)
    {
        c[i] = (x * 10 + a[i]) / b;
        x = (x * 10 + a[i]) % b;
        ++lenc;
    }

    // 去除前部可能出现的 0
    int c_startID = 0;
    for (; c_startID < 100; ++c_startID)
        if (c[c_startID] != 0)
            break;

    for (int i = c_startID; i < lenc; ++i)
    {
        result[i - c_startID] = c[i];
        ++result_len;
    }
}

int main()
{
    // 从屏幕获得输入 被除数a和除数b均以字符串的形式输入
    string astr, bstr;
    cin >> astr;
    cin >> bstr;
    //获得字符串a和b的长度也就是,a和b的位数
    int lena = astr.size(), lenb = bstr.size();
   //设置数组a[100]高精度数字a
    int a[100] = { 0 }, b = 0; 
    for (int i = 0; i < lena; ++i)
        a[i] = astr[i] - '0'; // 除法不需要将数字倒过来
    for (int i = 0; i < lenb; ++i)
        b += (bstr[i] - '0') * pow(10, lenb - i - 1); // 字符串转 10 进制数
    //不能除以0
    if (b == 0)
        return -1; 

    // 设置数组c[100]存储计算结果,c[100]中存储的也是高精度的数字
    int c[100] = { 0 }, lenc(0);
    divide(a, lena, b, c, lenc); // a 是被除数,是高精度值。b是低精度值,用 int 即可存储

    // 输出
    for (int i = 0; i < lenc; ++i)
    {
        cout << c[i]; // 正向输出
    }
    cout << endl;
    return 0;
}

高精度除以高精度 #

假设 a 是一个高精度整数,b 也是一个高精度整数。

【算法分析】

  • 方法:使用减法模拟除法

将被除数,不断减去除数,直到余数小于除数。

  • 1. 需要用到高精度减法
  • 2. 需要用到高精度比较大小
  • 3. 需要用到高精度加法

【例程】

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include < iostream >
#include < string >
using namespace std;
int zero[] = { 0 };
int one[] = { 1 };
//赋值过程,将数组a[]中的数据赋值给b[],并将a的长度a_len赋值给b_len
void assign(int a[], int a_len, int* b, int& b_len)
{
for (int i=0; i < a_len; ++i)
b[i] = a[i];
b_len = a_len;
}
//高精度加法计算函数
void add(int a[], int a_len, int b[], int b_len, int* result, int& result_len)
{
int i = 0, x = 0;
result_len = 0;
int max_a_b = a_len > b_len ? a_len : b_len;
while (i< max_a_b)
{
int sub_a = i < a_len ? a[i] : 0;
int sub_b = i < b_len ? b[i] : 0;
result[i] = sub_a + sub_b + x;
x = result[i] / 10;
result[i] %= 10;
result_len++;
i++;
}
if (x != 0)
{
result[i] = x;
++result_len;
}
}
//高精度减法计算函数
void jianfa(int a[], int a_len, int b[], int b_len, int* result, int& result_len)
{
int i = 0, x = 0;
result_len = 0;
int max_a_b = a_len > b_len ? a_len : b_len;
while (i < max_a_b)
{
int sub_a = i < a_len ? a[i] : 0;
int sub_b = i < b_len ? b[i] : 0;
// 减法
if (sub_a < sub_b)
{
--a[i + 1];
sub_a += 10;
}
result[i] = sub_a - sub_b;
result_len++;
i++;
}
if (x != 0)
{
result[i] = x;
++result_len;
}
// 假如结果全都是0,输出一个0
int sum(0);
for (int i = 0; i < result_len; ++i)
{
sum += result[i];
if (sum != 0)
break;
}
if (sum == 0)
result_len = 1;
}
// 如果 a==b 返回 0; 如果 a > b, 返回 1; 如果 a < b, 返回 -1;
int compare_a_b(int a[], int a_len, int b[], int b_len)
{
if (a_len > b_len)
return 1;
else if (a_len < b_len)
return -1;
else
{
for (int i= a_len-1; i>=0; --i) // 加减的结果,是倒过来的,所以这里的比较也要倒着比较
{
if (a[i] > b[i])
return 1;
else if (a[i] < b[i])
return -1;
else
continue;
}
}
return 0; // 相等
}
void divide(int a[], int a_len, int b[], int b_len, int* shang, int& shang_len, int* yushu, int& yushu_len)
{
if (0 == compare_a_b(zero, 1, a, a_len))
{
shang_len = 1;
yushu_len = 1;
return; // 0是被除数,则商为0
}
for (;;)
{
jianfa(a, a_len, b, b_len, a, a_len); // 相当于 a -= b;
add(shang, shang_len, one, 1, shang, shang_len);
assign(a, a_len, yushu, yushu_len);// 将最终减法剩余的结果,赋值给余数
if (-1 == compare_a_b(a, a_len, b, b_len)) //
break; // 当余数a小于除数b的时候,退出循环。
}
}
int main()
{
// 从屏幕获得输入
string astr, bstr;
cin >> astr;
cin >> bstr;
int lena = astr.size(), lenb = bstr.size();
int a[100] = { 0 }, b[100] = { 0 };
for (int i = 0; i< lena; ++i)
a[lena - i - 1] = astr[i] - '0'; // 将数字倒过来
for (int i = 0; i< lenb; ++i)
b[lenb - i - 1] = bstr[i] - '0';
if (0 == compare_a_b(zero, 1, b, lenb))
return -1; // 被除数不能是 0
// 计算除法
int shang[100] = { 0 }, yushu[100] = { 0 }, shang_len(0), yushu_len(0);
divide(a, lena, b, lenb, shang, shang_len, yushu, yushu_len); // a 是被除数,是高精度值。b是低精度值,用 int 即可存储
// 输出
cout << "商:";
for (int i=0; i < shang_len; ++i)
cout << shang[shang_len - i - 1]; // 再将数字倒过来输出
cout << endl;
cout << "余数:";
for (int i = 0; i < yushu_len; ++i)
cout << yushu[yushu_len - i - 1]; // 再将数字倒过来输出
cout << endl;
return 0;
}
#include < iostream > #include < string > using namespace std; int zero[] = { 0 }; int one[] = { 1 }; //赋值过程,将数组a[]中的数据赋值给b[],并将a的长度a_len赋值给b_len void assign(int a[], int a_len, int* b, int& b_len) { for (int i=0; i < a_len; ++i) b[i] = a[i]; b_len = a_len; } //高精度加法计算函数 void add(int a[], int a_len, int b[], int b_len, int* result, int& result_len) { int i = 0, x = 0; result_len = 0; int max_a_b = a_len > b_len ? a_len : b_len; while (i< max_a_b) { int sub_a = i < a_len ? a[i] : 0; int sub_b = i < b_len ? b[i] : 0; result[i] = sub_a + sub_b + x; x = result[i] / 10; result[i] %= 10; result_len++; i++; } if (x != 0) { result[i] = x; ++result_len; } } //高精度减法计算函数 void jianfa(int a[], int a_len, int b[], int b_len, int* result, int& result_len) { int i = 0, x = 0; result_len = 0; int max_a_b = a_len > b_len ? a_len : b_len; while (i < max_a_b) { int sub_a = i < a_len ? a[i] : 0; int sub_b = i < b_len ? b[i] : 0; // 减法 if (sub_a < sub_b) { --a[i + 1]; sub_a += 10; } result[i] = sub_a - sub_b; result_len++; i++; } if (x != 0) { result[i] = x; ++result_len; } // 假如结果全都是0,输出一个0 int sum(0); for (int i = 0; i < result_len; ++i) { sum += result[i]; if (sum != 0) break; } if (sum == 0) result_len = 1; } // 如果 a==b 返回 0; 如果 a > b, 返回 1; 如果 a < b, 返回 -1; int compare_a_b(int a[], int a_len, int b[], int b_len) { if (a_len > b_len) return 1; else if (a_len < b_len) return -1; else { for (int i= a_len-1; i>=0; --i) // 加减的结果,是倒过来的,所以这里的比较也要倒着比较 { if (a[i] > b[i]) return 1; else if (a[i] < b[i]) return -1; else continue; } } return 0; // 相等 } void divide(int a[], int a_len, int b[], int b_len, int* shang, int& shang_len, int* yushu, int& yushu_len) { if (0 == compare_a_b(zero, 1, a, a_len)) { shang_len = 1; yushu_len = 1; return; // 0是被除数,则商为0 } for (;;) { jianfa(a, a_len, b, b_len, a, a_len); // 相当于 a -= b; add(shang, shang_len, one, 1, shang, shang_len); assign(a, a_len, yushu, yushu_len);// 将最终减法剩余的结果,赋值给余数 if (-1 == compare_a_b(a, a_len, b, b_len)) // break; // 当余数a小于除数b的时候,退出循环。 } } int main() { // 从屏幕获得输入 string astr, bstr; cin >> astr; cin >> bstr; int lena = astr.size(), lenb = bstr.size(); int a[100] = { 0 }, b[100] = { 0 }; for (int i = 0; i< lena; ++i) a[lena - i - 1] = astr[i] - '0'; // 将数字倒过来 for (int i = 0; i< lenb; ++i) b[lenb - i - 1] = bstr[i] - '0'; if (0 == compare_a_b(zero, 1, b, lenb)) return -1; // 被除数不能是 0 // 计算除法 int shang[100] = { 0 }, yushu[100] = { 0 }, shang_len(0), yushu_len(0); divide(a, lena, b, lenb, shang, shang_len, yushu, yushu_len); // a 是被除数,是高精度值。b是低精度值,用 int 即可存储 // 输出 cout << "商:"; for (int i=0; i < shang_len; ++i) cout << shang[shang_len - i - 1]; // 再将数字倒过来输出 cout << endl; cout << "余数:"; for (int i = 0; i < yushu_len; ++i) cout << yushu[yushu_len - i - 1]; // 再将数字倒过来输出 cout << endl; return 0; }
#include < iostream >
#include < string >
using namespace std;

int zero[] = { 0 };
int one[] = { 1 };
//赋值过程,将数组a[]中的数据赋值给b[],并将a的长度a_len赋值给b_len
void assign(int a[], int a_len, int* b, int& b_len)
{
    for (int i=0; i < a_len; ++i)
        b[i] = a[i];
    b_len = a_len;
}
//高精度加法计算函数
void add(int a[], int a_len, int b[], int b_len, int* result, int& result_len)
{
    int i = 0, x = 0;
    result_len = 0;
    int max_a_b = a_len > b_len ? a_len : b_len;
    while (i< max_a_b)
    {
        int sub_a = i < a_len ? a[i] : 0;
        int sub_b = i < b_len ? b[i] : 0;
        result[i] = sub_a + sub_b + x;
        x = result[i] / 10;
        result[i] %= 10;
        result_len++;
        i++;
    }
    if (x != 0)
    {
        result[i] = x;
        ++result_len;
    }
}
//高精度减法计算函数
void jianfa(int a[], int a_len, int b[], int b_len, int* result, int& result_len)
{
    int i = 0, x = 0;
    result_len = 0;
    int max_a_b = a_len > b_len ? a_len : b_len;
    while (i < max_a_b)
    {
        int sub_a = i < a_len ? a[i] : 0;
        int sub_b = i < b_len ? b[i] : 0;
        // 减法
        if (sub_a < sub_b)
        {
            --a[i + 1];
            sub_a += 10;
        }
        result[i] = sub_a - sub_b;
        result_len++;
        i++;
    }
    if (x != 0)
    {
        result[i] = x;
        ++result_len;
    }

    // 假如结果全都是0,输出一个0
    int sum(0);
    for (int i = 0; i < result_len; ++i)
    {
        sum += result[i];
        if (sum != 0)
            break;
    }

    if (sum == 0)
        result_len = 1;

}

// 如果 a==b 返回 0; 如果 a > b, 返回 1; 如果 a < b, 返回 -1;
int compare_a_b(int a[], int a_len, int b[], int b_len)
{
    if (a_len > b_len)
        return 1;
    else if (a_len < b_len)
        return -1;
    else
    {
        for (int i= a_len-1; i>=0; --i) // 加减的结果,是倒过来的,所以这里的比较也要倒着比较
        {
            if (a[i] > b[i])
                return 1;
            else if (a[i] < b[i])
                return -1;
            else
                continue;
        }
    }

    return 0; // 相等
}

void divide(int a[], int a_len, int b[], int b_len, int* shang, int& shang_len, int* yushu, int& yushu_len)
{
    if (0 == compare_a_b(zero, 1, a, a_len))
    {
        shang_len = 1;
        yushu_len = 1;
        return; // 0是被除数,则商为0
    }

    for (;;)
    {
        jianfa(a, a_len, b, b_len, a, a_len); // 相当于 a -= b;

        add(shang, shang_len, one, 1, shang, shang_len);
        assign(a, a_len, yushu, yushu_len);// 将最终减法剩余的结果,赋值给余数

        if (-1 == compare_a_b(a, a_len, b, b_len))  // 
            break; // 当余数a小于除数b的时候,退出循环。
    }
}

int main()
{
    // 从屏幕获得输入
    string astr, bstr;
    cin >> astr;
    cin >> bstr;
    int lena = astr.size(), lenb = bstr.size();
    int a[100] = { 0 }, b[100] = { 0 };

    for (int i = 0; i< lena; ++i)
        a[lena - i - 1] = astr[i] - '0'; // 将数字倒过来

    for (int i = 0; i< lenb; ++i)
        b[lenb - i - 1] = bstr[i] - '0';

    if (0 == compare_a_b(zero, 1, b, lenb))
        return -1; // 被除数不能是 0


    // 计算除法
    int shang[100] = { 0 }, yushu[100] = { 0 }, shang_len(0), yushu_len(0);
    divide(a, lena, b, lenb, shang, shang_len, yushu, yushu_len); // a 是被除数,是高精度值。b是低精度值,用 int 即可存储


    // 输出
    cout << "商:";
    for (int i=0; i < shang_len; ++i)
        cout << shang[shang_len - i - 1]; // 再将数字倒过来输出
    cout << endl;

    cout << "余数:";
    for (int i = 0; i < yushu_len; ++i)
        cout << yushu[yushu_len - i - 1]; // 再将数字倒过来输出
    cout << endl;
    
    return 0;
}
您的感觉是什么
分享这篇文章 :
  • Facebook
  • X
  • LinkedIn
  • Pinterest
目录
  • 1. 概述
    • 高精度数的概念
    • 数据的接收和存贮
    • 高精度数位数的确定
    • 进位,错位处理
  • 2. 高精度加法
  • 3. 高精度乘法
    • 进位和错位处理:高精度✖️单精度
    • 进位和错位处理:高精度✖️高精度
    • 高精度乘法实现
  • 4. 高精度除法
    • 高精度除以低精度
    • 高精度除以高精度

Copyright © 2020-2023 上海大师码文化有限公司 All rights reserved.
沪ICP备15020985号-5 | 沪公网安备31012002006140 | 管理登录

Copyright © 2020 上海大师码文化有限公司 All rights reserved.
沪ICP备15020985号-5 管理登录

Copyright © 2020-2023 上海大师码文化有限公司 All rights reserved.
沪ICP备15020985号-5 | 沪公网安备31012002006140 | 管理登录

Copyright © 2020 上海大师码文化有限公司 All rights reserved.
沪ICP备15020985号-5 管理登录