《编程思维与实践》1070.复数幂

《编程思维与实践》1070.复数幂

题目

在这里插入图片描述

思路

思路比较简单,就是细节比较繁琐:

( a + b i ) ( c + d i ) = ( a c − b d ) + ( a d + b c ) i (a+bi)(c+di)=(ac-bd)+(ad+bc)i (a+bi)(c+di)=(acbd)+(ad+bc)i , 利用该公式分实部和虚部进行计算结果即可.

由于涉及加减和正负号,所以在大整数结构体中加入符号参数sign,

为了方便起见这里对加法和减法操作进行了一定的补充,

①针对加法,令sign一开始为0,a+b有以下四种可能,需要先进行判定:

1. a>0且b>0,则sign赋值为1;

2. a>0且b<0,则调用减法函数进行a-|b|,且将sign赋值为1;

3. a<0且b>0,则调用减法函数进行b-|a|,且将sign赋值为1;

4. a<0且b<0,则sign赋值为-1.

②针对减法,令sign一开始为0,a-b有以下四种可能,需要先进行判定:

1. a>0且b>0,则sign赋值为1;

2. a>0且b<0,则调用加法函数进行a+|b|,且将sign赋值为1;

3. a<0且b>0,则调用加法函数进行|a|+|b|,且将sign赋值为-1;

4. a<0且b<0,则调用减法函数进行|b|-|a|,且将sign赋值为-1.

在读取复数的实部和虚部时需要逆向遍历,因为大数据处理为了方便起见从个位开始存,

先判断是否存在虚部,之后判断是否存在实部,特别地,如果存在虚部但存的数位数为0时需要补一个1.

在输出复数的实部和虚部时同样也要判断是否存在实部和虚部,

特别地,如果实部前不输出加号或者只有虚部时前不输出加号;

同时,如果虚部存的数位数为1且值为1时直接输出i.

注意的点:

1. 0在之前题目的处理中均视为位数为1(因为要保留整数0),为了本题处理的方便,这里视为位数为0;

2. 注意到 ( 100 0 1000 ) 2 = 1 0 6000 (1000^{1000})^2=10^{6000} (10001000)2=106000 所以数组最大需要开6001;

3. 如果幂次为0则直接输出1;

4. 由于每次进行复数乘法时,实部和虚部的计算都需要用到上一步的实部和虚部,所以需要一个temp去存计算后的结果.

代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define N 6001

typedef struct{int cnt,v[N],sign;}BIGINT;

BIGINT carry(BIGINT S,int bin);   //进位 bin表示进制 binary
BIGINT add(BIGINT S, BIGINT T,int sign);     //两个大整数相加
BIGINT mul(BIGINT S, BIGINT T);    //两个大整数相乘
BIGINT sub(BIGINT S, BIGINT T,int sign);     //两个大整数相减 两个大整数均非负
void ReadBig(char *s,BIGINT* A,BIGINT* B);   //读取实部虚部
void output(BIGINT R,BIGINT I); //输出复数

int main()
{
	char s[1000];
	int n;
	scanf("%s%d",s,&n);
	if(n==0)
	{
		printf("1");
	}
	else
	{
		BIGINT A={0,{0},1},B={0,{0},1};
		ReadBig(s,&A,&B); 
		BIGINT R=A,I=B;  //R实部 I虚部 
		for(int i=1;i<n;i++)
		{
			BIGINT temp=sub(mul(R,A),mul(I,B),0);
			I=add(mul(R,B),mul(I,A),0);
			R=temp; 
		}
		output(R,I);
	}
    return 0;
}

BIGINT carry(BIGINT S,int bin)   //进位 bin表示进制 binary
{
	int flag=0;
	for(int i=0;i<S.cnt;i++)
	{
		int temp=S.v[i]+flag;
		S.v[i]=temp%bin;
		flag=temp/bin;
	}
	if(flag)
	{
		S.v[S.cnt++]=flag;
	}
	return S;
}

BIGINT add(BIGINT S, BIGINT T,int sign)     //两个大整数相加
{
	if(sign==0)
	{
		if(S.sign==-1&&T.sign==-1)
		{
			sign=-1;
		}
		else if(S.sign==1&&T.sign==-1)
		{
			return sub(S,T,1);
		} 
		else if(S.sign==-1&&T.sign==1)
		{
			return sub(T,S,1);
		}
		else
		{
			sign=1;
		}
	}
	int max=S.cnt>T.cnt?S.cnt:T.cnt;
	BIGINT R={max,{0},sign};
	for(int i=0;i<max;i++)
	{
		R.v[i]=S.v[i]+T.v[i];   //依次进行普通乘法
	}
	R=carry(R,10);
	for(int i=R.cnt-1;i>=0&&R.v[i]==0;i--)  //去前置0(本题0的位数记为0) 
    {
        R.cnt--;
    }
	return R;
}

BIGINT mul(BIGINT S, BIGINT T)     //两个大整数相乘
{
    BIGINT R={S.cnt+T.cnt,{0},S.sign*T.sign};  //位数最多为两者相加
    for(int i=0;i<T.cnt;i++)
    {
        for (int j=0;j<S.cnt;j++)
        {
            R.v[i+j]+=S.v[j]*T.v[i];   //依此进行普通乘法
        }
    }
    R=carry(R,10);
    if(R.v[S.cnt+T.cnt-1]==0) 
	{
		R.cnt--; //最高位0不统计在一个大整数的位数中
	}
    return R;
}

BIGINT sub(BIGINT S, BIGINT T,int sign)     //两个大整数相减 两个大整数均非负
{
	if(sign==0)
	{
		if(S.sign==-1&&T.sign==1)
		{
			return add(S,T,-1);
		}
		else if(S.sign==-1&&T.sign==-1)
		{
			return sub(T,S,1);
		}
		else if(S.sign==1&&T.sign==-1)
		{
			return add(S,T,1);
		}
		else
		{
			sign=1;
		}
	}
	if(S.cnt<T.cnt)
	{
	    return sub(T,S,-1);
	}
    else if(S.cnt==T.cnt&&sign!=-1)  
    {
        for(int i=T.cnt-1;i>=0;i--)   //注意是从最高位开始比 
        {
            if(T.v[i]<S.v[i])
            {
                break;
            }
            else if(T.v[i]>S.v[i])
            {
                return sub(T,S,-1);
            }
        }
    }
	BIGINT R={S.cnt,{0},sign};
	int flag=0;  //借位
	for(int i=0;i<R.cnt;i++)
	{
		if(S.v[i]-flag-T.v[i]>=0)
        {
            R.v[i]=S.v[i]-T.v[i]-flag;
            flag=0;
        }
        else
        {
            R.v[i]=S.v[i]-T.v[i]-flag+10;
            flag=1;
        }
	}
	for(int i=R.cnt-1;i>=0&&R.v[i]==0;i--) //去前置0(本题0的位数记为0) 
    {
        R.cnt--;
    }
	return R;
}

void ReadBig(char *s,BIGINT* A,BIGINT* B)  
{
	if(strchr(s,'i')!=NULL) //有虚部
	{
		int i;
		for(i=strlen(s)-2;i>=0&&isdigit(s[i]);i--)  //逆着遍历 
		{
			B->v[B->cnt++]=s[i]-'0';
		}
		if(B->cnt==0)  //补个1
		{
			B->v[B->cnt++]=1;
		}
		if(i>0)   //有实部 
		{
			B->sign=s[i]=='+'?1:-1;
			i--;
			while(i>=0&&isdigit(s[i]))
			{
				A->v[A->cnt++]=s[i--]-'0';  
			}
			if(i==0)
			{
				A->sign=-1;
			}
		}   
		else if(i==0)    //无实部且虚部前有符号 
		{
			B->sign=-1;
		}
	}
	else  //无虚部
	{
		int i;
		for(i=strlen(s)-1;i>=0&&isdigit(s[i]);i--)
		{
			A->v[A->cnt++]=s[i]-'0';
		}
		if(i==0)
		{
			A->sign=-1;
		}
	}
}

void output(BIGINT R,BIGINT I)
{
	if(R.cnt!=0) //输出实部 
	{
		if(R.sign==-1)
		{
			printf("-");
		}
		for(int i=R.cnt-1;i>=0;i--)
		{
			printf("%d",R.v[i]);
		}
	}
	if(I.cnt!=0)   //虚部不为0 
	{
		if(R.cnt!=0)  //存在实部的话需要输出正负号 
		{
			if(I.sign==-1)
			{
				printf("-");
			}
			else if(I.sign==1)
			{
				printf("+");
			}
		}
		else if(I.sign==-1)  //不存在实部的话正号不需要输出 
		{
			printf("-");
		}
		if(!(I.cnt==1&&I.v[0]==1))  // 1i直接输出i 
		{
			for(int i=I.cnt-1;i>=0;i--)
			{
				printf("%d",I.v[i]);
			}
		}
		printf("i");
	}
} 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

致力于中小企业JavaEE企业级快速开发平台、后台框架平台

一、开源项目简介 J2eeFAST 是一个 Java EE 企业级快速开发平台&#xff0c; 致力于打造中小企业最好用的开源免费的后台框架平台 。系统基于&#xff08;Spring Boot、Spring MVC、Apache Shiro、MyBatis-Plus、Freemarker、Bootstrap、AdminLTE&#xff09;经典技术开发&…

亲测好用|甲方、专家和领导,用三维模型汇报方案如何投其所好?

身为设计方的你&#xff0c;有没有这样的经历&#xff1a; ➤ 一个非常优秀的方案未能被甲方采纳&#xff0c;反而甲方选择了一个不如自己的方案&#xff0c;造成了很大的遗憾&#xff1b; ➤ 在讲述自己的设计方案的时候&#xff0c;经常越说越散&#xff0c;甚至到了最后自…

应用在虚机和容器场景下如何优雅上下线

在生产场景中部署的服务提供者常因业务升级或其他场景需要下线和上线的部署操作&#xff0c;本文总结了应用在上下线过程中会遇到的典型问题&#xff0c;并思考在虚机和容器场景该如何处理这些问题&#xff0c;规避该过程中可能出现的服务消费者的请求失败&#xff0c;实现应用…

springboot文件上传

1.新建文件上传页面 在static目录中新建upload-test.html&#xff0c;上传页面代码如下所示&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>springboot文件上传测试</title> <…

mysql数据库的库操作 --2

目录 库操作 2.1&#xff1a;数据库的查看与创建与使用 2.2&#xff1a;字符集和效验规则 2.3&#xff1a;修改和删除数据库 2.4&#xff1a;数据库的备份和恢复 2.5&#xff1a;查看连接情况 库操作 2.1&#xff1a;数据库的查看与创建与使用 2.1.1&#xff1a;数据库…

Redis 持久化

文章目录 1. Redis 持久化2. RDB2.1 自动触发2.2 手动触发2.3 RDB 优点2.4 RDB 缺点2.5 RDB 文件修复2.6 总结 3. AOF3.1 AOF持久化工作流程3.2 AOF 缓冲区三种写回策略3.3 AOF 优点3.4 AOF 缺点3.5 AOF 重写机制3.6 AOF 重写原理3.7 总结 4. 混合持久化5. 纯缓存模式 1. Redis…

系统移植——linux内核移植——分析内核编译过程

uImage镜像文件 1.进入linux内核源码目录 ubuntuubuntu:~$ cd FSMP1A/linux-stm32mp-5.10.61-stm32mp-r2-r0/linux-5.10.61/ 打开Makefile文件 vi Makefile 搜索include 因为 $(SRCARCH)->arm 所以上述指令为 arch/arm/Makefile 2.进入linux内核源码目录下,arch/arm目录下…

计网笔记 数据链路层 (1-2) 封装成帧、差错控制、流量控制与可靠传输、停止等待协议、后退N帧协议(GBN)、选择重传协议(SR)

文章目录 前言在这里插入图片描述 零、数据链路层基本概念一、功能0、数据链路层功能概述1、封装成帧和透明传输1.1封装成帧1.2 透明传输1.3组帧方法 2、数据链路层的差错控制2.0差错从何而来2.1位错&#xff08;比特错&#xff0c;1变成0&#xff0c;0变成1&#xff09;2.2帧错…

复习一周,面了京东和百度,不小心都拿了Offer...

我个人情况是5年软件测试经验&#xff0c;在家复习了一周&#xff0c;面了京东和百度&#xff0c;都顺利拿下offer&#xff0c;下面是我的面试经历分享&#xff0c;希望能带来一些不一样的启发和帮助。 两家公司最常问的就是下面这些问题&#xff1a; 请介绍一下你之前做过哪些…

String类

目录 一.认识 String 类 二.常用方法 1.字符串构造&#xff08;定义&#xff09; 2.字符串指为空和null 3.String对象的比较 &#xff08;1&#xff09;equals和的区别 &#xff08;2&#xff09;compareTo比较 4.字符串查找 5.字符串转化 &#xff08;1&#xff09;…

前几天面了个32岁的测试员,年薪50w问题基本都能回答上,应该刷了不少八股文···

互联网行业竞争是一年比一年严峻&#xff0c;作为测试工程师的我们唯有不停地学习&#xff0c;不断的提升自己才能保证自己的核心竞争力从而拿到更好的薪水&#xff0c;进入心仪的企业&#xff08;阿里、字节、美团、腾讯等大厂.....&#xff09; 所以&#xff0c;大家就迎来了…

centerpoint论文和代码解读

目录 一、序论 二、论文结构 三、代码 论文地址&#xff1a; https://arxiv.org/pdf/2006.11275.pdf 代码地址&#xff1a;tianweiy/CenterPoint (github.com) 一、序论 centorpoint是一种anchor-free的方法&#xff0c;直接预测物体的中心点&#xff0c;然后直接回归其wh…

【C++】unordered_map与unordered_set(系列关联式容器)

文章目录 1.unordered系列关联式容器2. unordered_map3.unordered_set 1.unordered系列关联式容器 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;如map和set&#xff0c;它们在查询时效率可达logN&#xff0c;即最差情况下需要比较红黑树的高度…

将 Segment Anything 扩展到医学图像领域

文章目录 前言技术交流SAM 拆解分析从医学角度理解 SAM 的效用MedSAM实验总结 前言 SAM 是一种在自然图像分割方面取得成功的模型&#xff0c;但在医学图像分割方面表现不佳。MedSAM 首次尝试将 SAM 的成功扩展到医学图像&#xff0c;并成为用于分割各种医学图像的通用工具。为…

一文读懂 DNS 解析

导读 文章为“一文读懂域名与网站系列”第二篇&#xff0c;上篇文章主要介绍了域名的注册、建站和管理&#xff0c;通过本文你可以了解以下几个问题&#xff1a; 域名的结构、常用解析记录的类型 DNS 解析的过程 DNS 解析拓展知识 众所周知&#xff0c;互联网中的地址其实是…

Invicti v23.5 for Windows 发布 - 企业应用安全测试

Invicti v23.5 for Windows - 企业应用安全测试 Invicti Standard 11 May 2023 v23.5.0.40516 请访问原文链接&#xff1a;https://sysin.org/blog/invicti/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Invicti 是一种自动…

ESP32在linux下烧录,提示权限有问题,解决方法

执行idf.py -p /dev/ttyACM0 flash下载时&#xff0c;提示这个错误 serial.serialutil.SerialException: [Errno 13] could not open port /dev/ttyACM0: [Errno 13] Permission denied: /dev/ttyACM0 解决方法&#xff1a; 1检查串行端口 /dev/ttyUSB0 是否已被其他程序占用…

系统分析师之项目管理(十七)

一、范围管理 范围管理&#xff1a;确定项目的边界&#xff0c;即哪些工作是项目应该做的&#xff0c;哪些工作不应该包括在项目中。 二、时间管理 时间管理&#xff1a;也叫进度管理&#xff0c;就是用科学的方法&#xff0c;确定目标进度&#xff0c;编制进度计划和资源供应计…

SpringBoot整合Swagger

Swagger的作用&#xff1a;生成前后的接口文档&#xff1a; 了解Swagger的概念及作用 掌握在项目中集成Swagger自动生成API文档 一、SpringBoot集成Swagger 1.依赖&#xff1a; <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 --><depe…

【A、B、C、D、E类IP地址划分依据,你都会吗?】

IP 地址的格式&#xff1a;IP 地址 网络地址 主机地址 如果 IP 进行了子网划分&#xff1a; 则IP地址网络地址子网地址主机地址 网络地址是互联网上的节点在网络中具有的逻辑地址。MAC 地址&#xff0c;处于数据链 路层&#xff0c;IP 地址处于网络层&#xff0c;端口号处…