nowcoder NC10 大数乘法

news2024/11/15 15:54:22

题目链接: icon-default.png?t=N7T8https://www.nowcoder.com/practice/c4c488d4d40d4c4e9824c3650f7d5571?tpId=196&tqId=37177&rp=1&ru=/exam/company&qru=/exam/company&sourceUrl=%2Fexam%2Fcompany&difficulty=undefined&judgeStatus=undefined&tags=&title=

 

题目描述:

以字符串的形式读入两个数字,编写一个函数计算它们的乘积,以字符串形式返回。

数据范围: 读入的数字大小满足 0 \leqslant n \leqslant {10}^{1000}

要求:空间复杂度 O(m),时间复杂度 O(m^{2})(假设m是n的长度)

示例1:

输入:"11","99"

返回值:"1089"

说明:11*99=1089

示例2:

输入:"1","0"

返回值:"0"

答案:

import java.util.*;


public class Solution {

    public String solve (String s, String t) {
        // write code here
        if (s.charAt(0) == '0' || t.charAt(0) == '0'){
            return "0";
        }
        String ret = "0";
        String[] tmp = new String[t.length()]; 
        for (int i = t.length() - 1; i >= 0; i--){
            tmp[i] = "";
            int j = t.length() - 1;
            while(j - i > 0){
                tmp[i] += '0';
                j--;
            }
            tmp[i] += alongMultiply(s, t.charAt(i));
        }
        for (int i = t.length() - 1; i >= 0; i--){
            ret = Add(tmp[i], ret);
        }

        StringBuffer stringBuffer = new StringBuffer();
        for (int i = ret.length() - 1; i >= 0; i--){
            stringBuffer.append(ret.charAt(i));
        }
        ret = stringBuffer.toString();
        return ret;
    }

    public String Add(String a, String b){
        String str = "";
        int aLen = a.length() - 1;
        int ai = 0;
        int bLen = b.length() - 1;
        int bi = 0;
        int ten = 0;

        while(aLen >= ai && bLen >= bi){
            int tmp = (a.charAt(ai++) - '0') + (b.charAt(bi++) - '0');
            tmp += ten;
            ten = tmp / 10;
            str += tmp % 10;
        }
        while(aLen >= ai){
            int tmp = a.charAt(ai++) - '0';
            tmp += ten;
            ten = tmp / 10;
            str += tmp % 10;
        }
        while(bLen >= bi){
            int tmp = b.charAt(bi++) - '0';
            tmp += ten;
            ten = tmp / 10;
            str += tmp % 10;
        }
        if (ten != 0){
            str += ten;
        }
        return str;
    }

    public String alongMultiply(String s, char t){
        String ret = "";
        if (s.charAt(0) == '0' || t == '0'){
            return "0";
        }
        int tt = t - '0';
        int ten = 0;
        for (int i = s.length() - 1; i >= 0; i--){
            int tmp = s.charAt(i) - '0';
            tmp *= tt;
            tmp += ten;
            ten = tmp / 10;
            ret += tmp % 10;
        }
        if (ten != 0){
            ret += ten;
        }

        return ret;
    }
}

详解: 

 从题目中我们可以得到以下几点信息:

  1. 输入值和返回值都是字符串类型;
  2. 输入值和返回值不可以直接转换成整数(因为数字过大);
  3. 对时间复杂度几乎没有要求;
  4. 不会出现负数乘法。

 当我们清楚了题目要求之后就该考虑该如何解题了。

 首先我们应该考虑的是乘法是如何进行计算的

我们以 11 * 99 为例:

 

我们可以分析得到无论是几位数的乘法都是按照以下步骤进行的:

  1. 将第一个数字分别乘以第二个数的每一位;
  2. 如果第一个数乘的是第二个数的个位就给结果乘一,十位就乘十 以此类推;
  3. 最后一步就是将各各结果相加。

到这一步之后如果你想在题目给的那一个方法里面实现这些内容就会大大提高你写代码的难度,此时其实我推荐将其用三个方法来实现。

  • 第一个为主函数,主要用来实现代码的整体思路;
  • 第二个为相乘的方法,其主要功能是实现一个 n 位数与一位数相乘;
  • 第三个为相加的方法,其主要功能是实现两个 n 位数的相加。

根据乘法的定义可以知道:0 与任何数相乘都是 0 所以我们的第一段代码就可以为:

    public String solve (String s, String t) {
        // write code here
        if (s.charAt(0) == '0' || t.charAt(0) == '0'){
            return "0";
        }
    }

接下来就是对每一位进行相乘但是我们并不知道是 几位数与几位数进行相乘 所以我们此时应该根据 t 的长度来定义一个字符串数组 tmp 用来存储 t 中的每一位与 s 相乘的结果。

再定义一个名为 alongMultiply() 的方法 此方法就用来实现n 位数与一位数相乘并将其值以字符串的形式进行返回。(此方法可以先不急着实现)。

再定义一个名为 的字符串类型的变量,将其初始化为“0” 用来存储最终的返回值。

因为会有进位而导致最后结果的位数充满不确定性所以我们可以采用倒序的存储方式 

即:12345 存储为 54321

因为加法也会有进位所以我们可以在主方法的最后统一进行反转。

 public String solve (String s, String t) {
        // write code here
        if (s.charAt(0) == '0' || t.charAt(0) == '0'){
            return "0";
        }
        String ret = "0";

        //新加的代码
        String[] tmp = new String[t.length()]; 
        for (int i = t.length() - 1; i >= 0; i--){
            tmp[i] = "";
            int j = t.length() - 1;
            while(j - i > 0){ //相当于十位乘十 , 百位乘一百……
                tmp[i] += '0';
                j--;
            }
            tmp[i] += alongMultiply(s, t.charAt(i));
        }
}

紧接着我们再将 tmp数组 中的所有值进行相加存储在 ret 中。

for (int i = t.length() - 1; i >= 0; i--){
            ret = Add(tmp[i], ret);
}

到这里我们的整体布局已经完成了,接下来就该实现 alongMultiply() 方法了:

public String alongMultiply(String s, char t){
        String ret = ""; //用来存储最后的返回值
        if (s.charAt(0) == '0' || t == '0'){
            return "0";
        }
        int tt = t - '0';
        int ten = 0; //用来存储每次的进位
        for (int i = s.length() - 1; i >= 0; i--){
            int tmp = s.charAt(i) - '0';
            tmp *= tt;
            tmp += ten;
            ten = tmp / 10;
            ret += tmp % 10;
        }
        if (ten != 0){
            ret += ten;
        }

        return ret;
    }

 Add() 方法的实现:

public String Add(String a, String b){
        String str = ""; //存储最终的返回值
        int aLen = a.length() - 1;
        int ai = 0;
        int bLen = b.length() - 1;
        int bi = 0;
        int ten = 0; //用来存储每次的进位

        while(aLen >= ai && bLen >= bi){
            int tmp = (a.charAt(ai++) - '0') + (b.charAt(bi++) - '0');
            tmp += ten;
            ten = tmp / 10;
            str += tmp % 10;
        }
        while(aLen >= ai){
            int tmp = a.charAt(ai++) - '0';
            tmp += ten;
            ten = tmp / 10;
            str += tmp % 10;
        }
        while(bLen >= bi){
            int tmp = b.charAt(bi++) - '0';
            tmp += ten;
            ten = tmp / 10;
            str += tmp % 10;
        }
        if (ten != 0){
            str += ten;
        }
        return str;
    }

接下来我们只要再将最终的值进行反转本题就算做完了:

        StringBuffer stringBuffer = new StringBuffer();
        for (int i = ret.length() - 1; i >= 0; i--){
            stringBuffer.append(ret.charAt(i));
        }
        ret = stringBuffer.toString();

 当然你也可以用(我用上面的方法主要是因为它比较快):

        tmp[0] = ret;
        ret = "";
        for (int i = tmp[0].length() - 1; i >= 0; i--){
            ret += tmp[0].charAt(i);
        }

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

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

相关文章

解决VSCode下载速度特别慢的问题

一、下载VSCode 1.打开VSCode官网 https://code.visualstudio.com 2.download下载 3.下载特别慢 二、解决VSCode下载速度特别慢 1.单击右下角全部显示 我是用chrome浏览器,点击右下角的全部显示按钮,可以跳转到下载内容页面。 如果你是用其他浏览器…

OpenCV(二十八):连通域分割

目录 1.介绍连通域分割 2.像素领域介绍 3.两遍法分割连通域 4.连通域分割函数 1.介绍连通域分割 连通域分割是一种图像处理技术,用于将图像中的相邻像素组成的区域划分为不同的连通域。这些像素具有相似的特性,如相近的灰度值或颜色。连通域分割可以…

(十一)人工智能应用--深度学习原理与实战--实现泰坦尼克号生存者预测案例Titanic Survival

泰坦尼克号生存者预测(Titanic Survival)是谷歌Kaggle人工智能大赛中的经典亲例。本任务要求根据给定的1300余位乘客的特征(姓名、性别、年龄、舱位等】及幸存情况(0-死亡,1-幸存】建立神经网络模型,能够较巿准确地预测测试集中乘客的幸存情况。 主要流程为: 数据的导人及预…

Json“牵手”当当网商品详情数据方法,当当商品详情API接口,当当API申请指南

当当网是知名的综合性网上购物商城,由国内著名出版机构科文公司、美国老虎基金、美国IDG集团、卢森堡剑桥集团、亚洲创业投资基金(原名软银中国创业基金)共同投资成立1。 当当网从1999年11月正式开通,已从早期的网上卖书拓展到网…

python批量下载csdn文章

声明:该爬虫只可用于提高自己学习、工作效率,请勿用于非法用途,否则后果自负 功能概述: 根据待爬文章url(文章id)批量保存文章到本地;支持将文中图片下载到本地指定文件夹;多线程爬取; 1.爬取…

I.MX RT1176笔记(9)-- 程序异常追踪(CmBacktrace 和 segger rtt)

前言 在使用 ARM Cortex-M 系列 MCU时候,有时候会遇到各种异常(Hard Fault, Memory Management Fault, Bus Fault, Usage Fault, Debug Fault),这时候我们根据经验查询PC指针,LR寄存器,堆栈数据定位地址然…

深入理解联邦学习——纵向联邦学习

分类目录:《深入理解联邦学习》总目录 假设进行联邦学习的数据提供方为 A A A和 B B B,第三方为 C C C,则纵向联邦学习步骤如下: 在系统级做加密样本对齐,在企业感知层面不会暴露非交叉用户对齐样本进行模型加密训练&…

day2_C++

day2_C 代码题思维导图 代码题 #include using namespace std;#define MAX 50struct StuData {private:int scoreArr[MAX];int num;public:void setNum(int num);void input();void sort();void show();int getnum();};void StuData::setNum(int num){this->num num; }vo…

c语言实训心得3篇集合

c语言实训心得体会一: 在这个星期里,我们专业的学生在专业老师的带领下进行了c语言程序实践学习。在这之前,我们已经对c语言这门课程学习了一个学期,对其有了一定的了解,但是也仅仅是停留在了解的范围,对里…

[杂谈]-快速了解直接内存访问 (DMA)

快速了解直接内存访问 (DMA) 文章目录 快速了解直接内存访问 (DMA)1、使用 DMA 需要什么?2、DMA介绍3、DMA 中的数据传输如何进行?4、DMA接口5、DMAC 控制器寄存器6、DMA 控制器编程模式6.1 突发模式(Burst Mode)6.2 循环窃取模式…

h5微传单制作教程:快速轻松制作

在当今社交媒体充斥的时代,微传单作为一种新型的宣传推广方式,成为了企业和个人在传播信息时的重要工具。h5微传单相比传统的纸质传单更加灵活多样,并且能够通过手机、平板等设备随时随地进行浏览和分享,具有很高的传播效果。下面…

20个经典巧妙电路合集

1、防反接保护(二极管) 在实际电子设计中,防反接保护电路非常重要,不要觉得自己肯定不会接错,实际上无论多么小心,还是会犯错误...... 最简单的就是利用二极管了,利用二极管的单向导电性&#…

荔枝集团:如何提升项目管理效能,让需求交付快进50%

导语: 随着市场竞争日益激烈,企业面临的压力越来越大,需要不断优化自身的效率和质量,以更好地应对市场变化和竞争压力。因此,效能改进已成为企业实现长期发展的关键要素。 研发浓度作为一种能够准确反映研发效率的指…

ubuntu上ffmpeg使用framebuffer显示video

这个主题是想验证使用fbdev(Linux framebuffer device),将video直接显示到Linux framebuffer上,在FFmpeg中对应的FFOutputFormat 就是ff_fbdev_muxer。 const FFOutputFormat ff_fbdev_muxer {.p.name "fbdev",.p.long_…

大数据技术之Hadoop:HDFS存储原理篇(五)

目录 一、原理介绍 1.1 Block块 1.2 副本机制 二、fsck命令 2.1 设置默认副本数量 2.2 临时设置文件副本大小 2.3 fsck命令检查文件的副本数 2.4 block块大小的配置 三、NameNode元数据 3.1 NameNode作用 3.2 edits文件 3.3 FSImage文件 3.4 元素据合并控制参数 …

你知道聊天机器人在医疗保健行业发挥了什么作用吗?

在医疗保健行业,时间限制、数据泄露、误诊、治疗延误和人为错误等各种挑战构成了重大问题。然而,人工智能(AI)的快速发展已成为解决这些问题的解决方案。一个特别值得注意的应用是医疗保健中的聊天机器人,它提供了一系…

Linux---应用层获取usb设备描述信息通过endpoint地址数据通讯

文章目录 🌈应用层获取USB设备信息总体思路🌈应用层代码实例🌈实例测试🌈应用层通过endpoint进行数据读写 🌈应用层获取USB设备信息总体思路 应用层可以打开USB设备的节点,读取包括USB设备的配置&#xff…

核心实验12合集_vlan高级配置:基于子网划分vlan超级vlan相同vlan 端口隔离 _ENSP

项目场景一: 核心实验12合集-1_vlan高级配置_ENSP 基于子网划分vlan 1 当检测ip在192.168.10.0/24时候,PC接入交换机时,将其划为vlan10, 且可以和vlan 10 的服务器通信。 2 当检测ip在192.168.20.0/24时候,…

配电室数字电力智慧平台

配电室数字电力智慧平台依托电易云-智慧电力物联网,采用先进的人工智能、物联网、大数据技术,对配电室进行全面监控和管理,实现电力运行的自动化和智能化,有效降低运维成本,提高电力运行安全和可靠性。 该平台可以实时…

CTFHUB ICS(2)

1.modbus 还是通过strings输出文件 发现这次只找到了flag的字符666c61677b就是flag的16进制 通过strings和grep配合输出为10个数量的数据 strings 6.pcap | grep -E "^.{10}$" grep 搜索文本的工具 -E 使用扩展正则表达式 ^ 表示行的开始 . 匹配任意单…