已经不是小时候了,不能因为自己的小情绪就不干这不干那,不能因为不想而逃避,要自己为自己的未来打算,如果最后被社会淘汰了,就不能养活自己了。
平方差高精度
A、B可达 正负10^100,用任何数据类型都接不下它,可数据类型可看下。
c/c++中int,long,long long的取值范围_c++ long long 取值范围-CSDN博客
所以很明显,这题要用大数的方法。
存储大数
先用字符串录入,再进行转换
运算大数
主要是进位问题和最高位的位数问题。
出错总结
1. 在把字符转换成数字时,没有 - '0'
2. 读入数字时,是高位在前,所以在字符串里,先读入的是高位,高位数字存储在低位。
3. 两数相乘,用两层for循环,逐个相乘,至于是后结果的最高位数,是两个数长度之和。
4. 函数名后没有带[下标],也不会报错,呜呜。
5. 我将平方后的数组容量从150 升高到了300,多通过了两个。
代码:
#include <iostream>
#include<stdio.h>
#include<string>
#include<algorithm>
using namespace std;
int num1[150]; //个位在下标为1的地方
int num2[150];
//int flag1 = 0; //是否为负数
//int flag2 = 0;
int numlen1;
int numlen2;
int squ_num1[150]; //平方后的数字
int squ_num2[150];
int sub[150]; //平方减之后的数字
int squ_numlen1;
int squ_numlen2;
int sub_num;
void shift(string s1,string s2,int len1,int len2)
{
//判断符号,并将数字数组的第一位 1 代表正 -1代表负
if(s1[0] == '-') //如果是负号
{
//flag1 = 1;
num1[0] = -1;
numlen1 = len1;
for(int i = len1 - 1 ; i >= 0; i--)//把数字粘过去
{
num1[len1-i] = s1[i]-'0';
}
}else{
num1[0] = 1;
numlen1 = len1+1;
for(int i = len1 - 1 ; i >= 0 ; i--)//把数字粘过去
{
num1[len1-i] = s1[i] - '0';
}
}
if(s2[0] == '-') //如果是负号
{
//flag2 = 1;
num2[0] = -1;
numlen2 = len2;
for(int i = len2 - 1 ; i >= 0 ; i--)//把数字粘过去
{
num2[len2-i] = s2[i]-'0';
}
}else{
num2[0] = 1;
numlen2 = len2+1;
for(int i = len2 - 1 ; i >= 0; i--)//把数字粘过去
{
num2[len2-i] = s2[i]-'0';
}
}
return ;
}
//大数的平方
int square(int numlen,int num[150],int (&squ_num)[150])
{
/*int cin = 0;
squ_num[0] = 1; //平方后为正数,0也算吧
int squ_numlen = numlen;
for(int i = 1 ; i < numlen ; i++)
{
int x = num[i]*num[i];
squ_num[i] = (x+cin)%10;
cin = (x+cin)/10; //保证每个cin 都是该次的cin
}
if(cin != 0)
{
squ_num[numlen] = cin;
squ_numlen++;
}*/
int cin = 0;
squ_num[0] = 1;
int squ_numlen = 2*numlen-2;
for(int i = 1 ; i < numlen; i++)
{
for(int j = 1 ; j < numlen ; j++)
{
int x = num[i] * num[j] + cin;
squ_num[j+i-1] = x % 10;
cin = x / 10; //两个一位数相乘,最多两位
}
}
if(cin != 0)
{
squ_num[2*numlen-2] = cin;
squ_numlen = 2*numlen-1;
}
return squ_numlen;
}
//大数相减
void subtract(int squ_num11[150],int squ_num21[150])
{
int cin = 0 ;
sub[0] = 1; //设为正数
int end = min(squ_numlen1,squ_numlen2);
int fend = max(squ_numlen1,squ_numlen2);
for(int i = 1 ; i < end ;i++)
{
if((squ_num11[i] - cin) >= squ_num21[i])
{
sub[i] = squ_num11[i] - squ_num21[i] -cin;
cin = 0;
}else if((squ_num11[i] - cin) < squ_num21[i]) {
sub[i] = squ_num11[i]+10-squ_num21[i]-cin;
cin = 1;
}
}
/*if(cin == 1)
{
sub[end] = squ_num11[end]-1;
}*/
for(int i = end ; i < fend ; i++)
{
if(squ_num11[i] - cin < 0)
{
sub[i] = squ_num11[i] + 10 - cin;
cin = 1;
}else if(squ_num11[i] - cin >= 0)
{
sub[i] = squ_num11[i] - cin;
cin = 0;
}
}
sub_num = fend-1;
return ;
}
//大数比较大小 1更大返回1 2更大返回0
int cmp()
{
if(squ_numlen1 > squ_numlen2)
{
return 1;
}else if(squ_numlen1 < squ_numlen2){
return 0;
}else {
for(int i = squ_numlen1 ; i > 0 ; i--)
{
if(squ_num1[i] > squ_num2[i])
{
return 1;
break;
}else if(squ_num1[i] < squ_num2[i]){
return 0;
break;
}
}
}
return -1;
}
int main()
{
// 请在此输入您的代码
//1.存储大数:以字符串的方式输入,再将每个字符转成数字放入数组。
string s1;
string s2;
cin >> s1;
cin >> s2;
//将字符转成数字放入数组,注意判断正负数
int len1 = s1.length();
int len2 = s2.length();
shift(s1,s2,len1,len2);
//进行加法和减法
//一共四种情况(AB是绝对值),-A`+B` A`-B` A`+B` -A`-B`
//(A + B)*(A - B ) (包括负号)
//或者直接 A^2 ,两数相乘最多两位,注意进位
squ_numlen1 = square(numlen1,num1,squ_num1);
squ_numlen2 = square(numlen2,num2,squ_num2);
if(cmp() == 1)
{
subtract(squ_num1,squ_num2);
sub[0] = 1;
}else if(cmp() == 0)
{
subtract(squ_num2,squ_num1);
sub[0] = -1;
}else
{
sub[1]=0;
sub[0] = 1;
sub_num = 1;
}
//把sub打印出来
if(sub[0] == -1)
{
cout << '-';
}
int flag = 1; //用来标志这个0是否是无效0
//
cout << sub_num << endl;
for(int j = 0 ; j < squ_numlen1 ; j++){cout << squ_num1[j] << ' ';}
cout << endl;
for(int j = 0 ; j < squ_numlen2 ; j++){cout << squ_num2[j] << ' ';}
for(int i = sub_num ; i > 0 ; i--)
{
if(i!=1 && flag && sub[i] == 0){}
else {
flag = 0;
cout << sub[i] ;
}
}
return 0;
}