Rust 数据结构与算法:4栈:用栈实现进制转换

news2025/1/13 11:33:39
2、进展转换

将十进制数转换为二进制表示形式的最简单方法是“除二法”,可用栈来跟踪二进制结果。

在这里插入图片描述

除二法

下面实现一个将十进制数转换为二进制或十六进制的算法,代码如下:

#[derive(Debug)]
struct Stack<T> {
    size: usize,  // 栈大小
    data: Vec<T>, // 栈数据
}

impl<T> Stack<T> {
    // 初始化空栈
    fn new() -> Self {
        Self {
            size: 0,
            data: Vec::new(), // 以 Vec 为低层
        }
    }

    fn is_empty(&self) -> bool {
        0 == self.size
    }

    fn len(&self) -> usize {
        self.size
    }

    // 清空栈
    fn clear(&mut self) {
        self.size = 0;
        self.data.clear();
    }

    // 将数据保存在 Vec 的末尾
    fn push(&mut self, val: T) {
        self.data.push(val);
        self.size += 1;
    }

    // 将栈顶减 1 后,弹出数据
    fn pop(&mut self) -> Option<T> {
        if 0 == self.size {
            return None;
        };
        self.size -= 1;
        self.data.pop()
    }

    // 返回栈顶数据引用和可变引用
    fn peek(&self) -> Option<&T> {
        if 0 == self.size {
            return None;
        }
        self.data.get(self.size - 1)
    }

    fn peek_mut(&mut self) -> Option<&mut T> {
        if 0 == self.size {
            return None;
        }
        self.data.get_mut(self.size - 1)
    }

    // 以下是为栈实现的迭代功能
    // into_iter: 栈改变,成为迭代器
    // iter: 栈不变,得到不可变迭代器
    // iter_mut:栈不变,得到可变迭代器

    fn into_iter(self) -> IntoIter<T> {
        // into_iter()方法获取了一个迭代器,然后进行迭代
        IntoIter(self)
    }

    fn iter(&self) -> Iter<T> {
        let mut iterator = Iter { stack: Vec::new() };
        for item in self.data.iter() {
            iterator.stack.push(item);
        }
        iterator
    }

    fn iter_mut(&mut self) -> IterMut<T> {
        let mut iterator = IterMut { stack: Vec::new() };
        for item in self.data.iter_mut() {
            iterator.stack.push(item);
        }
        iterator
    }
}
// 实现三种迭代功能
struct IntoIter<T>(Stack<T>);
// Iterator 是 Rust 的迭代器 迭代器(iterator)负责遍历序列中的每一项和决定序列何时结束的逻辑。当使用迭代器时,我们无需重新实现这些逻辑。
impl<T: Clone> Iterator for IntoIter<T> {
    // into_iter()方法获取了一个迭代器,然后进行迭代。
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        // 迭代器之所以成为迭代器,是因为实现了Iterator trait。要实现该特征,最主要的就是实现其中的 next 方法,该方法控制如何从集合中取值,最终返回值的类型是关联类型 Item。
        if !self.0.is_empty() {
            self.0.size -= 1;
            self.0.data.pop()
        } else {
            None
        }
    }
}
// 'a 生命周期标识 用于帮助编译器检查引用的有效性,避免悬垂引用和使用已被释放的内存。
// 从所有权的角度来理解,就是它可以避免因为Copy或者clone的造成的不必要开销
struct Iter<'a, T: 'a> {
    stack: Vec<&'a T>, // 'a 被用在了传参类型 T 上
}
impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T; // 生命周期标识只作用于引用上,且放在&符号之后 如这里的 &'a T
    fn next(&mut self) -> Option<Self::Item> {
        self.stack.pop()
    }
}

struct IterMut<'a, T: 'a> {
    stack: Vec<&'a mut T>,
}
impl<'a, T> Iterator for IterMut<'a, T> {
    type Item = &'a mut T;
    fn next(&mut self) -> Option<Self::Item> {
        self.stack.pop()
    }
}
fn main() {
    let num1 = 10;
    let num2 = 43;
    let bin_str = base_converter(num1, 2);
    let hex_str = base_converter(num2, 16);

    println!("{num1}(十进制) = {bin_str}(二进制), {num2}(十进制) = {hex_str}(十六进制)");
}

// 支持将 10进制数 转为 2 进制或 16 进制
fn base_converter(mut dec_num:u32,base:u32) -> String {
    // digits 对应各种余数的字符形式,尤其是 10-15
    let digits = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];
    let mut rem_stack = Stack::new();

    // 余数入栈
    while dec_num > 0 {
        let rem = dec_num % base;
        rem_stack.push(rem);
        dec_num /= base;
    }

    // 余数出栈并取对应字符以拼接成字符串
    let mut base_str = "".to_string();
    while !rem_stack.is_empty() {
        let rem = rem_stack.pop().unwrap() as usize;
        base_str += &digits[rem].to_string();
    }
    base_str
}

运行结果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1450750.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SG7050EEN晶体振荡器SPXO规格书

频率范围:25mhz ~ 500mhz供电电压:2.5 V型。/ 3.3 V类型功能:输出使能(OE)外形尺寸:7.0 5.0 1.5 mm输出:LV-PECL低相位抖动:50fs型。(f0 156.25 MHz)工作温度:-40℃~ 105℃ 规范

二叉树相关OJ题

创作不易&#xff0c;感谢三连&#xff01;&#xff01; 一、选择题 1、某二叉树共有 399 个结点&#xff0c;其中有 199 个度为 2 的结点&#xff0c;则该二叉树中的叶子结点数为&#xff08; &#xff09; A.不存在这样的二叉树 B.200 C.198 D.199解析&#xff1a;选B&…

致创新者:聚焦目标,而非问题

传统的企业创新管理方式常常导致组织内部策略不协调、流程低效、创新失败率高等问题。而创新运营作为企业管理创新的新模式&#xff0c;通过整合文化、实践、人员和工具&#xff0c;提高组织创新能力。已经采用创新运营的公司报告了一系列积极的结果&#xff0c;如市场推出速度…

最长连续手牌 - 华为OD统一考试

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 有这么一款单人卡牌游戏&#xff0c;牌面由颜色和数字组成&#xff0c;颜色为红、黄、蓝、绿中的一种&#xff0c;数字为 0−9 中的一个。游戏开始时玩家从手牌中…

力扣hot3--并查集+哈希

第一想法是排个序然后遍历一遍&#xff0c;but时间复杂度就超啦 并查集居然与哈希结合了&#xff08;&#xff09; 已经好久没用过并查集了&#xff0c;&#xff0c;&#xff0c;我们用哈希表f_node中来记录原结点的父节点&#xff0c;其中key是原结点&#xff0c;value是父节点…

OpenHarmony—UIAbility组件生命周期

概述 当用户打开、切换和返回到对应应用时&#xff0c;应用中的UIAbility实例会在其生命周期的不同状态之间转换。UIAbility类提供了一系列回调&#xff0c;通过这些回调可以知道当前UIAbility实例的某个状态发生改变&#xff0c;会经过UIAbility实例的创建和销毁&#xff0c;…

代码随想录算法训练营第二十七天|贪心算法理论基础,455.分发饼干,376. 摆动序列,53. 最大子序和

系列文章目录 代码随想录算法训练营第一天|数组理论基础&#xff0c;704. 二分查找&#xff0c;27. 移除元素 代码随想录算法训练营第二天|977.有序数组的平方 &#xff0c;209.长度最小的子数组 &#xff0c;59.螺旋矩阵II 代码随想录算法训练营第三天|链表理论基础&#xff…

抖音私信自动回复工具使用教程!

该工具基于网页版抖音&#xff0c;可以用于抖音个人号等任何权限的账号&#xff01; 获取软件 联系我的v 信&#xff1a;llike620 基本使用 了解GPT的&#xff0c;可以配置FastGPT这种训练知识库的AI进行回复 不了解的&#xff0c;可以配置关键词回复 点击抖音私信按钮&a…

Linux设置jar包开机自启动

步骤 1、新建jar包自启文件 sudo vi /etc/init.d/jarSysInit.sh 按i键进入编辑模式输入以下内容&#xff1a; export JAVA_HOME/home/jdk/jdk-11.0.22 export CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/jre/lib/rt.jar export PATH$PATH:$JAVA_…

H5大气的互联网建站服务公司静态HTML网站模板源码

H5大气的互联网建站服务公司静态HTML网站模板源码 源码介绍&#xff1a;一款大气的互联网建站服务公司/工作室静态HTML网站模板&#xff0c;带有多个单页&#xff0c;可自行二开作为工作室或公司官网。 下载地址&#xff1a; https://www.changyouzuhao.cn/13456.html

人力资源智能化管理项目(day08:云存储)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/humanResourceIntelligentManagementProject 存储桶列表 &#xff1a;登录 - 腾讯云 API密钥管理&#xff1a;登录 - 腾讯云 上传图片-创建腾讯云存储桶 存储桶名称&#xff1a;intelligentmanagement-1306913843 地…

【Qt】环境安装与初识

目录 一、Qt背景介绍 二、搭建Qt开发环境 三、新建工程 四、Qt中的命名规范 五、Qt Creator中的快捷键 六、QWidget基础项目文件详解 6.1 .pro文件解析 6.2 widget.h文件解析 6.3 widget.cpp文件解析 6.4 widget.ui文件解析 6.5 main.cpp文件解析 七、对象树 八、…

Rust中不可变变量与const有何区别?

Rust作者认为变量默认应该是immutable&#xff0c;即声明后不能被改变的变量。这一点是让跨语言学习者觉得很别扭&#xff0c;不过这一点小的改变带来了诸多好处&#xff0c;本节我们来学习Rust的变量。 什么是变量&#xff1f; 如果你初次学习编程语言&#xff0c;变量会是一…

AlmaLinux更换鼠标样式为Windows样式

文章目录 前言先看看条件与依赖第一步&#xff1a;测试最终效果第二步&#xff1a;使用CursorXP修改鼠标样式CurosrXP安装CursorXP使用 第三步&#xff1a;Linux端环境搭建与命令执行UbuntuFedora其他系统均失败 第四步&#xff1a;应用主题 前言 只不过是突发奇想&#xff0c…

相机图像质量研究(17)常见问题总结:CMOS期间对成像的影响--靶面尺寸

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

如何使用python在三天内制作出一个赛车游戏

制作一个赛车游戏是一个复杂的过程&#xff0c;涉及多个方面&#xff0c;如游戏设计、图形渲染、物理引擎、用户输入处理等。在三天内完成这个任务可能非常具有挑战性&#xff0c;特别是如果你是初学者。但如果你有基本的Python编程知识和一些游戏开发经验&#xff0c;以下是一…

假期day12

任务调度算法&#xff1a; 1.抢占式调度&#xff1a;高优先级的任务优先执行&#xff0c;并且可以打断低优先级的任务执行。 2.时间片轮转&#xff1a;相同优先级的任务&#xff0c;拥有相同的时间片&#xff08;1ms&#xff09;&#xff0c;当时间片被耗尽&#xff0c;就退出…

Github项目推荐-Tiny-Rdm

项目地址 GitHub - tiny-craft/tiny-rdm: A Modern Redis GUI Client 项目简述 一个开源的Redis管理工具&#xff0c;有漂亮的界面和丰富的功能。使用的编程语言如下 项目截图

C语言第二十五弹---字符函数和字符串函数(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 目录 1、字符分类函数 2、字符转换函数 3、strlen的使用和模拟实现 4、strcpy 的模拟实现 5、strcat 的模拟实现 6、strcmp 的模拟实现 7、strncpy 函数的使用 总结…

【Pygame手册02/20】pygame模块display控制窗口和屏幕

目录 一、说明二、pygame.display接口函数2.1 函数表格2.2 pygame.display的功能 三、详细的函数调用3.1 pygame.display.init()3.2 pygame.display.quit()3.3 pygame.display.get_init()3.4 pygame.display.set_mode()3.5 pygame.display.get_surface()3.6 pygame.display.fl…