当前位置: 首页 > news >正文

《程序员面试金典(第6版)面试题 16.09. 运算

题目描述

请实现整数数字的乘法、减法和除法运算,运算结果均为整数数字,程序中只允许使用加法运算符和逻辑运算符,允许程序中出现正负常数,不允许使用位运算。

你的实现应该支持如下操作:

  • Operations() 构造函数
  • minus(a, b) 减法,返回a - b
  • multiply(a, b) 乘法,返回a * b
  • divide(a, b) 除法,返回a / b

示例:

Operations operations = new Operations();
operations.minus(1, 2); //返回-1
operations.multiply(3, 4); //返回12
operations.divide(5, -2); //返回-2

提示:

  • 你可以假设函数输入一定是有效的,例如不会出现除法分母为0的情况
  • 单个用例的函数调用次数不会超过1000次

解题思路与代码

  • 这道题属实是一道中等难度的题。需要你有一定的思考量,才可以做出来。

  • 题目的要求是,不允许我们使用位运算符,除了 + 法以外的算术运算符,去实现两个数之间的减法,乘法,除法函数。

  • 也就是说,我们可以使用 + 法运算符,关系运算符(==, <= , >=, < , >)还有逻辑运算符 ( ! , && , ||)去实现这些函数。

  • 这道题建议大家不要抖机灵,使用各种没有意义的库函数来简便运算。还有这道题也不要去使用vector这种数据结构。因为,vector的模板类在实现时涉及到位运算符和减法运算符的

接下来,其实我们就要思考一个问题。乘法,除法的本质是什么?

  • 那其实是不是就是加法(乘法的本质是加法)与减法(除法的本质是减法)呢?
  • 那也就是说,要实现除法函数,首先得实现减法函数。

那我们,在来思考一个问题,减法的本质是什么?

  • 那是不是加上一个相反数呢?
  • 所以要实现减法函数,首先我们还需要去实现一个取反函数。

其实这道题还有一个隐藏的条件,那就是提示:单个用例的函数调用次数不会超过1000次

  • 也就是说,这道题,出题人不想你太容易去解决这个问题。问你如何优化流程,也就是缩短时间复杂度。
  • 假如说我们要用累加去实现取反过程,你想想时间复杂度是不是O(n),那有没有一种办法可以优化累加的时间复杂度呢?
  • 当然有。我们可以通过事先创建两个数组,分别去存储正负2的多少次方的值是多少。到时候,我们可以用循环的方式,去累加预定值,这样是不是就将时间复杂度O(n)缩短到O(logn)了呢?

OK,这道题讲到这里,大家应该心里很有谱了才对。做这道题,首先,我们要创建两个内置数组,去存储可能出现的2的次方值。然后先实现取反函数。再实现减法函数,再实现乘法函数,最后实现除法函数。

实现的过程中,需要大家注意溢出问题。因为虽然题目给的值的范围不会超过int的最大最小范围。但是两个数相减,相乘,相除的过程中,如果处理不好,是会发生溢出问题的。

具体的实现请看代码:

class Operations {int posN[31]; // 放正数2的n次方int negN[31]; // 放负数2的n次方//取相反数函数int oppN(int num){if(!num) return 0;int res = 0;if(num > 0){ // 从2^30次方开始检查for(int i = 30; i >= 0; i += (-1)){if(num + negN[i] < 0) continue;num += negN[i];res += negN[i];}}else{ // 从 - 2^30次方开始检查for(int i = 30; i >= 0; i += (-1)){if(num + posN[i] > 0) continue;num += posN[i];res += posN[i];}}return res;}
public:Operations() {int p = 1;int n = -1;posN[0] = p;negN[0] = n;// 初始化次方数组for(int i = 1; i < 31; ++i){p += p;posN[i] = p;n += n;negN[i] = n;}}int minus(int a, int b) {return a + oppN(b);}int multiply(int a, int b) {if(!a || !b) return 0;if(a == 1) return b;if(b == 1) return a;if(b < 0) return oppN(multiply(a,oppN(b))); // 统一b的正负int res = a;int count = 1;while(count < posN[30] && count + count <= b ){res += res;count += count;}res += multiply(a,minus(b,count));return res;}int divide(int a, int b) {if(!a) return 0;int res = 1;if(a > 0){if(b == INT_MIN) return 0;if(b < 0) return oppN(divide(a,oppN(b))); // 统一a,b的正负if(a < b) return 0;int count = b;while(count < posN[30] && a >= count + count){res += res;count += count;}res += divide(minus(a,count),b);}else{if(b == 1) return a;if(b > 0) return oppN(divide(a,oppN(b)));if(a > b) return 0;int count = b;while(count >= negN[30] && a <= count + count){res += res;count += count;}res += divide(minus(a,count),b);}return res;}    
};

在这里插入图片描述

复杂度分析

下面是这个代码中各个函数的时间复杂度和空间复杂度分析:

  • oppN(int num):时间复杂度为 O(log(num)),因为它在最坏情况下需要遍历数组 posN 或 negN 中的所有元素(共 31 个),这与输入数字的二进制表示长度成正比。空间复杂度为 O(1),因为它使用了固定数量的额外存储空间。

  • Operations() 构造函数:时间复杂度为 O(1),因为它只需要遍历 31 个元素并执行一定数量的操作。空间复杂度为 O(1),因为它只使用了固定大小的 posN 和 negN 数组。

  • minus(int a, int b):时间复杂度为 O(log(b)),因为它调用了 oppN 函数。空间复杂度为 O(1),因为它没有使用额外的存储空间。

  • multiply(int a, int b):时间复杂度为 O(log(a) * log(b)),因为它使用递归实现,每次递归调用都会减小 b 的值,递归深度为 O(log(b)),而每次递归调用都会调用 minus 函数,时间复杂度为 O(log(a))。空间复杂度为 O(log(b)),因为递归深度与空间复杂度成正比。

  • divide(int a, int b):时间复杂度为 O(log(a) * log(b)),因为它也是使用递归实现,每次递归调用都会减小 a 的值,递归深度为 O(log(a)),而每次递归调用都会调用 minus 函数,时间复杂度为 O(log(b))。空间复杂度为 O(log(a)),因为递归深度与空间复杂度成正比。

总的来说,这个实现的时间复杂度主要取决于输入数字的二进制表示长度,而空间复杂度主要取决于递归深度。

总结

  • 这道题的意义在于考察编程能力、逻辑思维和对基本运算的理解。

  • 它要求我们在限制条件下(仅使用加法运算符和逻辑运算符)实现整数数字的减法、乘法和除法运算。这种问题有助于锻炼思考能力,强化对计算机基本原理的理解,以及提高解决问题的灵活性。

  • 同时,这种问题也有助于理解计算机是如何处理基本的算术运算的,以及为什么某些优化方法(例如位运算)是有效的。通过解决这种问题,你可以加深对计算机科学和编程原理的理解。

  • 最后的最后,如果你觉得我的这篇文章写的不错的话,请给我一个赞与收藏,关注我,我会继续给大家带来更多更优质的干货内容

相关文章:

《程序员面试金典(第6版)面试题 16.09. 运算

题目描述 请实现整数数字的乘法、减法和除法运算&#xff0c;运算结果均为整数数字&#xff0c;程序中只允许使用加法运算符和逻辑运算符&#xff0c;允许程序中出现正负常数&#xff0c;不允许使用位运算。 你的实现应该支持如下操作&#xff1a; Operations() 构造函数minus…...

asp.net基于web的校园美食派送配送系统

1&#xff0e;系统登录&#xff1a;系统登录是用户访问系统的路口&#xff0c;设计了系统登录界面&#xff0c;包括用户名、密码和验证码&#xff0c;然后对登录进来的用户判断身份信息&#xff0c;判断是管理员用户还是普通用户。 2&#xff0e;系统用户管理&#xff1a;不管是…...

【JAVA】#详细介绍!!! 文件操作之File对象(1)!

本文内容不涉及文件内容操作&#xff0c;主要是对指定文件元信息的获取&#xff0c;以及通过java代码如何创建一个文件或者删除文件 目录 文件操作的File对象 File对象的基本操作方法 得到文件&#xff08;夹&#xff09;对象的信息元 1.getParent 2. getName 3.getPath 4…...

Vue基本的内置指令

前言 除了常见的v-bind,v-for,v-if,v-on.v-model等&#xff0c;本次学习一些vue提供的其他内置指令 1 v-text 给标签插入文本&#xff0c;类似于插值语法 它会把全部的字符串当成文本去解析,不会当成标签的,哪怕写的是标签结构 效果和插值语法是一样的 插值语法比v-text更加…...

华为孟晚舟当值首秀:2030年AI算力将增长500倍!

作者 | 范智林 来源 | 华商观察 微信号&#xff1a;HuashangGC 孟晚舟当值首次亮相。 4月19日&#xff0c;华为副董事长、轮值董事长、CFO孟晚舟在华为第20届全球分析师大会上进行演讲&#xff0c;这是她当值华为轮值董事长以来的首次公开亮相。 按照华为内部规定&#xff0c…...

关于python异常的总结

Python异常是在程序执行时发生的错误&#xff0c;可能会导致程序终止运行。 在Python中&#xff0c;异常处理是一种机制&#xff0c;它允许开发人员在程序发生异常时捕获、处理和报告这些异常&#xff0c;以便程序可以继续运行或在出现异常时进行优雅的退出。 在Python中&…...

基于Java+SpringBoot+vue学生学习平台详细设计实现

基于JavaSpringBootvue学生学习平台详细设计实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式 文章目…...

【云原生网关】Kong 使用详解

目录 一、前言 二、Kong介绍 三、Kong核心组件 3.1 kong组件介绍 3.1.1 Kong Server 3.1.2 Apache Cassandra/PostgreSQL 3.1.3 Kong dashboard 3.2 传统网关与Kong工作模式对比 四、Kong网关特征与架构 4.1 kong网关特征 4.1.1 可扩展性 4.1.2 模块化 4.1.3 在任…...

浅谈之Java多线程

Java多线程是Java语言中一个非常重要的特性&#xff0c;它允许程序同时执行多个任务。通过多线程&#xff0c;程序可以同时处理多项任务&#xff0c;从而缩短程序的执行时间。另外&#xff0c;多线程也有助于利用多核处理器&#xff0c;更好地发挥计算机硬件的性能。 那我们在…...

【Vue3学习笔记1】一个清单应用帮你入门Vue.js

Vue 目前已经是国内最流⾏的前端框架之⼀&#xff0c;Vue 3 带来的诸多优化更是让前端圈迎来了新的潮流&#xff0c;比如&#xff1a; 基于 Proxy 的全新响应式实现&#xff1b; Composition API <script setup> 组织代码的更优方式&#xff1b; 更有料的 TypeScript 支…...

go破冰之旅·8·go函数基本实践及各种玩法

一次5-10分钟即可搞定&#xff0c;以干货效率的学习方式带你更直观的玩转各种玩法&#xff01; 行文不易&#xff0c;一字一句纯手打创造&#xff0c;倾注了不少精力&#xff0c;感谢支持。 目录 什么是函数&#xff1f;有哪些元素&#xff1f; 函数参数、返回值 小程序&…...

Qt - 从零到壹的 打地鼠 游戏

❤️‍&#x1f525;欢迎收看西北风的blog&#xff0c;好男人就是我&#xff0c;我就是西北风。✨ Gitee 地址 W_A_Mole NTC_jason/cc语言 - 码云 - 开源中国 (gitee.com) 目录 &#x1f7e5;一&#xff1a;创建一个主窗体 &#x1f7e3;二.&#xff1a;添加主窗口背景图片…...

代码自动发布系统

之前是jenkins发现gitlab代码更新了就自动获取直接部署到服务器 现在是jenkins自动获取Code之后打包成镜像上传到仓库然后通知docker去拉取更新的镜像 分析 旧∶ 代码发布环境提前准备&#xff0c;以主机为颗粒度静态 新: 代码发布环境多套&#xff0c;以容器为颗粒度编译 …...

qemu-基础篇(一)——安装

文章目录 env安装查看版本查看支持的开发板查看支持的CPU的型号 env ubuntu 安装 sudo apt-get install qemu sudo apt-get install qemu-system-arm sudo apt-get install qemu-system查看版本 qemu-img -V qemu-system-arm --version qemu-system-aarch64 --version返回结…...

从根本上理解Synchronized的加锁过程

作为一个Java开发&#xff0c;对于Synchronized这个关键字并不会陌生&#xff0c;无论是并发编程&#xff0c;还是与面试官对线&#xff0c;Synchronized可以说是必不可少。 在JDK1.6之前&#xff0c;都认为Synchronized是一个非常笨重的锁&#xff0c;就是在之前的《谈谈Java…...

CANOE入门到精通——CANOE系列教程记录1 第一个仿真工程

本系列以初学者角度记录学习CANOE&#xff0c;以《CANoe开发从入门到精通》参考学习&#xff0c;CANoe16 demo版就可以进行学习 概念 CANoe是一种用于开发、测试和分析汽车电子系统的软件工具。它通过在不同层次上模拟汽车电子系统中的不同部件&#xff0c;如ECU、总线和传感…...

JavaEE——单例模式

文章目录 一、介绍什么是单例模式二、饿汉模式三、懒汉模式四、讨论两种模式的线程安全问题 一、介绍什么是单例模式 在介绍单例模式之前&#xff0c;我们得先明确一个名词设计模式。 所谓设计模式其实不难理解&#xff0c;就是在计算机这个圈子中&#xff0c;呢些大佬们为了…...

关于数据倾斜

1、数据倾斜表现 1.1 hadoop中的数据倾斜表现 有一个多几个Reduce卡住&#xff0c;卡在99.99%&#xff0c;一直不能结束。各种container报错OOM异常的Reducer读写的数据量极大&#xff0c;至少远远超过其它正常的Reducer伴随着数据倾斜&#xff0c;会出现任务被kill等各种诡异…...

Shell第一次作业

要求&#xff1a; 1、判断当前磁盘剩余空间是否有20G&#xff0c;如果小于20G&#xff0c;则将报警邮件发送给管理员&#xff0c;每天检查一次磁盘剩余空间。 ​2、判断web服务是否运行&#xff08;1、查看进程的方式判断该程序是否运行&#xff0c;2、通过查看端口的方式判断…...

实例解读nn.AdaptiveAvgPool2d((1, 1))

nn.AdaptiveAvgPool2d((1, 1))在PyTorch中创建一个AdaptiveAvgPool2d类的实例。该类在输入张量上执行2D自适应平均池化。 自适应平均池化是一种池化操作&#xff0c;它计算每个输入子区域的平均值并产生一个指定大小的输出张量。子区域的大小是根据输入张量的大小和输出张量的…...

物联网设备超低功耗设计实战:从硬件协同到软件优化的全链路解析

1. 项目概述&#xff1a;为什么我们需要一个“超低功耗”的无线平台&#xff1f;在物联网设备开发领域&#xff0c;功耗一直是一个绕不开的核心痛点。我经历过太多项目&#xff0c;前期功能验证一切顺利&#xff0c;一到功耗测试就“翻车”。客户拿着样机问&#xff1a;“你们这…...

【香橙派5】基于RKNN-Lite在RK3588上部署Yolov5的实战指南

1. 香橙派5与RK3588平台简介 香橙派5作为一款高性能的单板计算机&#xff0c;搭载了瑞芯微RK3588芯片&#xff0c;这颗芯片内置了强大的NPU&#xff08;神经网络处理单元&#xff09;&#xff0c;算力高达6TOPS。这意味着它能够高效处理复杂的AI推理任务&#xff0c;比如实时目…...

柔性LED灯丝DIY:从电路原理到创意饰品制作全攻略

1. 项目概述&#xff1a;当生日遇上柔性LED灯丝给孩子的生日派对准备一份独一无二的、会发光的惊喜&#xff0c;是很多家长和手工爱好者的心愿。这次&#xff0c;我们不买现成的塑料灯牌&#xff0c;而是亲手做一个能戴在头上或挂在脖子上的“生日数字灯冠”。这个项目的核心&a…...

3大突破性功能:如何用QtScrcpy彻底改变你的Android投屏体验

3大突破性功能&#xff1a;如何用QtScrcpy彻底改变你的Android投屏体验 【免费下载链接】QtScrcpy Android real-time display control software 项目地址: https://gitcode.com/GitHub_Trending/qt/QtScrcpy 你是否曾经为了在电脑上操作手机而烦恼&#xff1f;无论是游…...

MemPrivacy:面向端云智能体的隐私保护个性化记忆管理框架

之前文章介绍过&#xff1a;89.2%攻击成功率&#xff01;腾讯、字节研究发现 OpenClaw Agent 存在可利用结构性漏洞 今天介绍一个 MemPrivacy 项目&#xff0c;来自 MemTensor、荣耀和同济大学的联合团队。 他们的研究让云端智能体能正常"记住你"&#xff0c;但永远看…...

AI原生产品管理:多智能体协作如何重塑产品开发工作流

1. 项目概述&#xff1a;当AI成为你的产品经理最近在GitHub上看到一个挺有意思的项目&#xff0c;叫NathanJCW/ai-native-pm-cortex。光看名字&#xff0c;你大概能猜到它想做什么——“AI原生的产品经理大脑”。这可不是一个简单的聊天机器人插件&#xff0c;它试图构建一个完…...

人性最残忍的真相是:你越不把自己当回事,别人就越不把你当回事

那个总给别人买贵东西的人,最后都怎么样了? 目录 那个总给别人买贵东西的人,最后都怎么样了? 我们为什么会忍不住过度付出? 真正的爱,从来都不是单方面的牺牲 爱自己,是所有健康关系的前提 昨天刷到一句话,瞬间戳中了我:“永远不要拿自己辛苦钱,去给别人买自己都舍不…...

量子控制中的动态校正门与SCQC几何方法

1. 量子控制中的噪声挑战与动态校正门在超导量子处理器上实现高保真度的量子门操作&#xff0c;最大的障碍来自环境噪声。这些噪声主要分为两类&#xff1a;失谐噪声&#xff08;δz&#xff09;和幅度噪声&#xff08;ϵ&#xff09;。失谐噪声源于量子比特频率的漂移&#xf…...

Go语言SDK开发实战:为AI编程助手Cursor构建高效API客户端

1. 项目概述&#xff1a;一个为AI编程助手Cursor定制的Go语言SDK如果你和我一样&#xff0c;日常重度依赖Cursor这类AI编程助手来提升开发效率&#xff0c;同时又是个Go语言的忠实拥趸&#xff0c;那你肯定遇到过这样的场景&#xff1a;想用Go写个脚本&#xff0c;自动化处理一…...

碳排放混合时间窗集装箱运输调度【附算法】

✨ 长期致力于集装箱运输VRP、混合时间窗、碳排放、多目标优化、NSGA-Ⅱ、蚁群算法研究工作&#xff0c;擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流&#xff0c;点击《获取方式》 &#xff08;1&#xff09;经济性与紧急性双目…...