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

news2025/1/20 5:49:27

《编程思维与实践》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.coloradmin.cn/o/522998.html

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

相关文章

MySQL的事务

1、事务的概念 事务是一种机制、一个操作序列&#xff0c;包含了一组数据库操作命令&#xff0c;并且把所有的命令作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这一组数据库命令要么都执行&#xff0c;要么都不执行。 事务是一个不可分割的工作逻辑单元&#xff…

【python数据分析】Pandas数据载入

&#x1f64b;‍ 哈喽大家好&#xff0c;本次是python数据分析、挖掘与可视化专栏第五期 ⭐本期内容&#xff1a;Pandas数据载入 &#x1f3c6;系列专栏&#xff1a;Python数据分析、挖掘与可视化 &#x1f44d;“总有一段时光悄悄过去然后永远怀念.” 文章目录 前言一、数据载…

fusion app 网页远程控制app

拥有此网页&#xff0c;即可。远程控制软件里面的公告更新以及其他内容。 网页并无联系方式&#xff0c;请自己摸索。 从此即可摆脱&#xff0c; QQ收藏&#xff0c;微云&#xff0c;讯飞语记的束缚&#xff01; 使用本程序网站放再多的内容都不会乱码&#xff01; FA2和1都可…

代码随想录算法训练营第四天|24. 两两交换链表中的节点 、19.删除链表的倒数第N个节点 、面试题 02.07. 链表相交 、142.环形链表II

两两交换链表中的节点 题目链接&#xff1a;力扣 解题思路&#xff1a;虚拟头节点&#xff0c;然后进行模拟即可。 我拿到这道题的时候&#xff0c;其实交换的思路是有的&#xff0c;但是首先没有设虚拟节点&#xff0c;这使得我的解答很乱&#xff0c;有很多if条件判断。其次…

Eclipse中如何使用:Maven、Git、GitHub、码云

第1章 在Eclipse 中使用 Maven 1.1 安装 Maven 核心程序 1)下载地址&#xff1a;http://maven.apache.org/ 2)检查 JAVA_HOME 环境变量。Maven 是使用 Java 开发的&#xff0c;所以必须知道当前系统环境中 JDK 的安装目录。 即&#xff1a;安装jdk目录中bin目录的上一级目录…

基于ESP32的单通道LoRaWAN网关设计资料介绍-操作模式

资料下载链接》》 介绍 这是在由ESP8266/ESP32 mcu和sx1276无线电组成的平台上实现LoRa网关功能的第6代软件。与旧版本的网关不同&#xff0c;此版本将在单一频率上收听所有可用的扩频因子 (SF)。网关使用 Web 功能&#xff08;通过 Intranet&#xff09;启用网关的监控和配置…

桂院导航小程序 云开发项目 二次开发教程

Gitee代码仓库&#xff1a;桂院导航小程序 GitHub代码仓库&#xff1a;GLU-Guide​​​​​​​ 演示视频 桂院校园导航小程序 演示视频 先 假装 大伙都成功安装了云开发项目&#xff0c;并能在 微信开发者工具 和 手机 上正确运行。 接着就是 将项目 改成自己的学校。 代码…

Redis性能测试怎么做?看看字节8年测试工程师写的测试总结

最近测试服务端的时候,接触到了redis&#xff0c;之前也看过,但不系统,借着这次实践,记录一下 01、简介 Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。 它通常被称为数据结构…

【Linux】第一个驱动程序,hello world!开启驱动之旅

目录 前言&#xff1a; 一、背景 二、驱动程序编写流程 1.APP打开的文件在内核中如何表示&#xff1f; 2.编写驱动程序的流程 三、hello驱动程序实战 hello_drive.c hello_drive_test.c 最终测试&#xff1a; a.首先编译内核&#xff08;如果没有编译过&#xff09…

Makefile 与 docker 进行多服务 一次性构建

本机多服务一次性构建背景 本机开发多个服务,每个服务还会互相调用正常情况,开发者需要在本地启动多个服务,并且手动调用想着不使用gitlab ci/cd, 在本机快速通过 makefiledocker-compose 编排多个服务可执行源码在:https://github.com/webws/go-moda/tree/main/example/traci…

使用Segment Anything(SAM)模型进行自动标注

1.下载项目 项目1&#xff1a;https://github.com/zhouayi/SAM-Tool 项目2&#xff1a;https://github.com/facebookresearch/segment-anything git clone https://github.com/zhouayi/SAM-Tool.gitgit clone https://github.com/facebookresearch/segment-anything.git cd …

Nginx之正向代理与反向代理

1.什么是代理 打工人张三最近换了新工作&#xff0c;原来的住房离公司的路程太远&#xff0c;于是乎想要重新找一个离工作地不那么远的住房&#xff0c;由于工作繁忙&#xff0c;没有时间看房。 房东王五名下有2套住房&#xff0c;一套自己住&#xff0c;另一套想租出去&…

shell脚本----sed命令

文章目录 一、sed的工作流程二、sed的操作三、Sed命令使用3.1打印内容3.2删除行3.3替换3.4插入3.5分组调用 一、sed的工作流程 sed概述 sed编辑器时一种流编辑器&#xff0c;流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。 sed编辑器可以根据命令来处理…

(转载)从0开始学matlab(第3天)—多维数组

正如我们所看到的&#xff0c;MATLAB 的数组可能是一维或多维的。一维的数组可以形象地看作一系列的数垂直地罗列起来&#xff0c;用一个下标就可以调用数组中的元素&#xff08;如图 a&#xff09;。这样的数组适用于一个变量的函数&#xff0c;例如在规定的时间间隔后一系列…

C语言实战 - 贪吃蛇(图像界面)

由于本人精力有限&#xff0c;暂时先把素材和代码放上&#xff0c;等以后有空再补教程。 目录 效果预览 准备工作 EasyX图形库 音频素材 代码编写 Transfer.h文件 game.cpp文件 main.c文件 效果预览 先来看一下最终成品效果 贪吃蛇图形界面 准备工作 EasyX图形库 这…

Stable Diffusion云端部署只需三步, 不吃电脑配置, 模型快速部署

牙叔教程 简单易懂 我是小白, 小白跟我一步一步做就可以了, 鼠标点两下就OK了, 学点新东西, 好吗? 不想学的就走吧, 离我远点. Stable Diffusion是什么 Stable diffusion是一个基于Latent Diffusion Models&#xff08;潜在扩散模型&#xff0c;LDMs&#xff09;的文图生成…

瑞吉外卖 - 后台系统登陆功能(3)

某马瑞吉外卖单体架构项目完整开发文档&#xff0c;基于 Spring Boot 2.7.11 JDK 11。预计 5 月 20 日前更新完成&#xff0c;有需要的胖友记得一键三连&#xff0c;关注主页 “瑞吉外卖” 专栏获取最新文章。 相关资料&#xff1a;https://pan.baidu.com/s/1rO1Vytcp67mcw-PD…

Baumer工业相机堡盟工业相机IO介绍与配置

Baumer工业相机堡盟工业相机IO介绍与配置 Baumer工业相机Baumer工业相机IO的作用Baumer工业相机IO的作用Baumer工业相机IO上点连 Baumer工业相机 Baumer工业相机堡盟相机是一种高性能、高质量的工业相机&#xff0c;可用于各种应用场景&#xff0c;如物体检测、计数和识别、运…

Android基础复习:Service组件详解

Android基础复习&#xff1a;Service组件详解 概况 Service组件是一种可在后台执行长时间运行操作而不提供界面的应用组件。服务可由其他应用组件启动&#xff0c;而且即使用户切换到其他应用&#xff0c;服务仍将在后台继续运行。此外&#xff0c;组件可通过绑定到服务与之进…

【动手学深度学习】现代卷积神经网络汇总

文章目录 1 LeNet2 AlexNet3 VGG4 NiN5 GoogLeNet6 ResNet7 DenseNet 本文为作者阅读学习李沐老师《动手学深度学习》一书的阶段性读书总结&#xff0c;原书地址为&#xff1a;Dive into Deep Learning。 1 LeNet 网络结构 实现代码 net nn.Sequential(nn.Conv2d(1, 6, kern…