#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string r;
int n,dianwei;
const int R_LEN=;
short result[R_LEN],jieguo[R_LEN],chengshu[];
while(cin>>r>>n)
{
int len=;
for(int i=;i<R_LEN;++i) jieguo[i]=result[i]=;//初始化为0
for(int i=;i<;++i) chengshu[i]=;
dianwei = ;
size_t pos = r.find(".");//找到小数点的位置
if(pos != string::npos)
dianwei=(-pos)*n; //结果中的小数点的位数 for(int i=,j=;i>=;--i) //得到倒序数字数组
{
if(r[i]!='.')
{
jieguo[j]=result[j]=chengshu[j]=r[i]-'';//提取数位
++j;
}
} //整数相乘步骤
while(n>=)//指数大于等于2的时候计算,否则就是直接去除多余0输出了
{
--n;
for(int i=;i<R_LEN;++i)//对结果数组一初始化
result[i]=; for(int i=;i<;++i)//乘数数位循环
{
int c;
for(int j=;j<R_LEN;++j)//被乘数数位循环
{
c=chengshu[i]*jieguo[j];
result[i+j]+=c; for(int t=i+j;result[t]>;++t)//处理进位 即当result[t]<=9 该数组不进位时停止
{
result[t+]+=result[t]/;
result[t]=result[t]%;
}
}
}
for(int i=;i<R_LEN;++i)
jieguo[i]=result[i];//结果转存 这里的jieguo数组作用是存上一次的结果,用来和乘数向乘,因为result[]=jieguo[]*chengshu[]
} //找边界步骤
int firstindex=-;
for(int i=R_LEN-;i>=dianwei;--i)//从右往左查找小数点前第一个不为0的数 处理前导0 记录边界
{
if(result[i]>)
{
firstindex=i;//记录 小数点前第一个不为0的数的下标 方便输出
break;
}
}
int lastindex=-;
for(int i=;i<dianwei;++i)//从左往右查找小数点前第一个不为0的数 处理后导0 记录边界
{
if(result[i]>) //记录 小数点前第一个不为0的数的下标 方便输出
{
lastindex=i;
break;
}
} //输出步骤
if(firstindex!=-)//输出小数点前的部分
{
while(firstindex>=dianwei)
{
cout<<result[firstindex];
--firstindex;
}
}
if(lastindex!=-)//如果有小数部分,先输出小数点,再输出小数部分
{
cout<<'.';
--dianwei;
while(dianwei>=lastindex)
{
cout<<result[dianwei];
--dianwei;
}
}
cout<<endl;
}
}

我自己重写的一遍

#include<iostream>
#include<cstdio>
#include<string>
#include<string.h>
#include<cstring>
using namespace std;
#define maxn 160
int main()
{
string r;
int n;
while (cin >> r >> n)
{
int a[], result[maxn], temp[maxn];
//先找到小数的位置
int weishu=,pos=-;
for (int i = ; i < ; i++)
if (r[i] == '.')
pos = i;
if(pos!=-)
weishu = (-pos )*n;//为result的下标 前面有weishu个数字
//初始化
for (int i = ; i < maxn; i++)
result[i]=temp[i]=;
for (int i = ; i < ; i++)
a[i]=; int j = ;
for (int i = ; i >=; i--)
{
if (r[i] != '.')
{
result[j]=temp[j]= a[j] = r[i]-'';
j++;
}
}
//整数相乘
while(n>=)
{
--n;
for(int i=;i<maxn;i++)//对结果数组一初始化
result[i]=;
for (int i = ; i < ; i++)
{
for (int j = ; j < maxn; j++)
{
result[i + j] += temp[j] * a[i];
//处理进位问题
for (int t = i + j; result[t] > ; ++t) //这里改变了上面的i
{
result[t + ] += result[t] / ;
result[t] = result[t] % ;
}
}
}
for (int h = ; h < maxn; h++)
temp[h] = result[h]; }
//找界限
//找前导
int firstloc = -;
//int x = 0;
for (int i = maxn-; i >= weishu; i--)//这里加了个等号 ***这里的等号一定要存在 因为可能不存在小数点,位数为0时也需要求出前导
if (result[i] >)
{
firstloc = i;
//x = 1;//说明小数点前面有数字
break;
}
int endloc = -;
for(int i=;i<weishu;i++)
if (result[i] >)
{
endloc = i;
break;
}
//输出
if(firstloc!=-)//输出小数点前的部分
{
while(firstloc>=weishu)
{
cout<<result[firstloc];
--firstloc;
}
}
if(endloc!=-)//如果有小数部分,先输出小数点,再输出小数部分
{
cout<<'.';
--weishu;
while(weishu>=endloc)
{
cout<<result[weishu];
--weishu;
}
}
cout<<endl;
}
}

总结(心得)

1.数组一定不能越界

例如:

#define maxn=100;

for(int i=0;i<=100;i++)

这是绝对错误的,不能越界

2.要考虑清楚情况

要分好条件,不能漏情况

3.for语句里面要注意

for(i=maxn;;i--)

for(i=0;;i++)

3.memset的使用

// memset(result, 0, maxn);  这是错误的表达
memset(result, 0, sizeof(int)*maxn);

这是最初写的一份(有很多错误)

#include<iostream>
#include<cstdio>
#include<string>
#include<string.h>
#include<cstring>
using namespace std;
#define maxn 160
int main()
{
string r;
int n;
while (cin >> r >> n)
{
int a[], result[maxn], temp[maxn];
//先找到小数点的位置
int pos = -;
for (int i = ; i < ; i++)
if (r[i] == '.')
pos = i;
int weishu = (-pos )*n;//为result的下标 前面有weishu个数字
//初始化
memset(a, , sizeof(a));
memset(result, , maxn);
memset(temp, , maxn);
int j = ;
for (int i = sizeof(r)-; i >=; i++)
{
if (r[i] != '.')
temp[j]= a[j++] = r[i]-'';
}
//整数相乘
while(n--)
{
for (int i = ; i < ; i++)
{
for (int j = ; j < maxn; j++)
{
result[i + j] += temp[j] * a[i];
//处理进位问题
for (int t = i + j; result[i + j] > ; i++)
{
result[t + ] += result[t] / ;
result[i + j] = result[i + j] % ;
}
}
for (int h = ; h < maxn; h++)
temp[h] = result[h];
}
}
//找界限
//找前导
int firstloc = ;
//int x = 0;
for (int i = maxn; i > pos; i--)
if (result[i] >&& result[i] <=)
{
firstloc = i;
//x = 1;//说明小数点前面有数字
break;
}
int endloc = ;
for(int i=;i<pos;i++)
if (result[i] > && result[i] <= )
{
endloc = i;
break;
}
//输出
for (int i = firstloc; i > pos; i--)
cout << result[i];
cout << "." << endl;
for (int i = endloc; i < pos; i++)
cout << result[i];
}
}

错误在上面的标记已经改正

#include<iostream>
#include<cstdio>
#include<string>
#include<string.h>
#include<cstring>
using namespace std;
#define maxn 160
int main()
{
string r;
int n;
while (cin >> r >> n)
{
int a[], result[maxn], temp[maxn];
//先找到小数点的位置 //***这里错误 未考虑到如果没有小数点的话 weishu时为多少
/*int pos = -1;
for (int i = 0; i < 6; i++)
if (r[i] == '.')
pos = i;
int weishu = (5-pos )*n;//为result的下标 前面有weishu个数字*/
int pos = -;
for (int i = ; i < ; i++)
if (r[i] == '.')
pos = i;
int weishu=;
if(pos!=-)
weishu = (-pos )*n;
//初始化
memset(a, , sizeof(a));
/*
memset(result, 0, maxn); //***这里错误
memset(temp, 0,maxn);
*/
memset(result, , sizeof(int)*maxn);
memset(temp, , sizeof(int)*maxn);
//给这些数组赋值 //*****这里错误 未加上result[j]=result[j]=.... 加上时因为在整数相乘那一步 当n<2时是不参加那些步骤的 所有result[]是需要赋值的
/*int j = 0;
for (int i = sizeof(r); i >=0; i++) //注意:这里数组越界了,另外当i取到最大值,i自然是i--
{
if (r[i] != '.')
temp[j]= a[j++] = r[i]-'0'; //另外这里j++放进表达式,可能会产生temp[j]与a[j++]里面的j值不同
}*/
int j = ;
for (int i = ; i >=; i--)
{
if (r[i] != '.')
{
result[j]=temp[j]= a[j] = r[i]-'';
j++;
}
}
//整数相乘
/*while(n--)
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < maxn; j++)
{
result[i + j] += temp[j] * a[i];
//处理进位问题
for (int t = i + j; result[i + j] > 9; i++) //******错误result[i + j]中的i+j可是一个定值在该循环语句中 未起预想中的作用
{
result[t + 1] += result[t] / 10;
result[i + j] = result[i + j] % 10; //******错误result[i + j]中的i+j可是一个定值
}
}
for (int h = 0; h < maxn; h++)
temp[h] = result[h];
}
}
*/
while(n>=)
{
n--;
for(int i=;i<maxn;i++)
result[i]=;
for (int i = ; i < ; i++)
{
for (int j = ; j < maxn; j++)
{
result[i + j] += temp[j] * a[i];
//处理进位问题
for (int t = i + j; result[t] > ; t++)
{
result[t + ] += result[t] / ;
result[t] = result[t] % ;
}
}
}
for (int h = ; h < maxn; h++)
temp[h] = result[h];
}
//找界限
//找前导
/*int firstloc = 0; //***错误 未考虑到前导不存在的情况
for (int i = maxn; i > pos; i--)//****错误 未考虑到不存在小数点 则前导可以取为0的情况 可以改成i>=pos
if (result[i] >0&& result[i] <=9)
{
firstloc = i;
//x = 1;//说明小数点前面有数字
break;
}*/
int firstloc = -;
for (int i = maxn-; i >=weishu; i--)
if (result[i] >)
{
firstloc = i;
//x = 1;//说明小数点前面有数字
break;
}
int endloc = -;
for(int i=;i<weishu;i++)
if (result[i] >)
{
endloc = i;
break;
}
//输出
/*for (int i = firstloc; i > pos; i--) //***错误 不是pos 应该是weishu
cout << result[i];
cout << "." << endl;
for (int i = endloc; i < pos; i++)
cout << result[i];*/
/*for (int i = firstloc; i >weishu; i--) //***错误 不是pos 应该是weishu
cout << result[i];
cout << "." << endl;
for (int i = endloc; i < weishu; i++)
cout << result[i];*/
if(firstloc!=-)//输出小数点前的部分
{
while(firstloc>=weishu)
{
cout<<result[firstloc];
--firstloc;
}
}
if(endloc!=-)//如果有小数部分,先输出小数点,再输出小数部分
{
cout<<'.';
--weishu;
while(weishu>=endloc)
{
cout<<result[weishu];
--weishu;
}
}
cout<<endl;
}
}

poj 1001 字符串乘法以及处理精度问题的更多相关文章

  1. [POJ 1001] Exponentiation C++解题报告 JAVA解题报告

        Exponentiation Time Limit: 500MS   Memory Limit: 10000K Total Submissions: 126980   Accepted: 30 ...

  2. POJ 1001 Exponentiation(大数运算)

    POJ 1001 Exponentiation 时限:500 ms   内存限制:10000 K 提交材料共计: 179923   接受: 43369 描述:求得数R( 0.0 < R < ...

  3. 1001 字符串“水”题(二进制,map,哈希)

    1001: 字符串“水”题 时间限制: 1 Sec  内存限制: 128 MB提交: 210  解决: 39[提交][状态][讨论版] 题目描述 给出一个长度为 n 的字符串(1<=n<= ...

  4. POJ 1001 解题报告 高精度大整数乘法模版

    题目是POJ1001 Exponentiation  虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于 ...

  5. [POJ] #1001# Exponentiation : 大数乘法

    一. 题目 Exponentiation Time Limit: 500MS   Memory Limit: 10000K Total Submissions: 156373   Accepted: ...

  6. POJ 1001 Exponentiation 无限大数的指数乘法 题解

    POJ做的非常好,本题就是要求一个无限位大的指数乘法结果. 要求基础:无限大数位相乘 额外要求:处理特殊情况的能力 -- 关键是考这个能力了. 所以本题的用例特别重要,再聪明的人也会疏忽某些用例的. ...

  7. 【POJ 1001】Exponentiation (高精度乘法+快速幂)

    BUPT2017 wintertraining(15) #6A 题意 求\(R^n\) ( 0.0 < R < 99.999 )(0 < n <= 25) 题解 将R用字符串读 ...

  8. poj 1001 java大精度

    import java.io.* ; import java.math.* ; import java.util.* ; import java.text.* ; public class Main ...

  9. poj 1001

    http://poj.org/problem?id=1001 这是一道高精度的运算,如果你之前有写过那种高精度的乘法的题目的话,做这个也还是比较简单的.. 思路:我是首先把小数点的位置确定下来,然后其 ...

随机推荐

  1. 高性能MySQL笔记-第5章Indexing for High Performance-005聚集索引

    一.聚集索引介绍 1.什么是聚集索引? InnoDB’s clustered indexes actually store a B-Tree index and the rows together i ...

  2. ARC100C Linear Approximation

    传送门 分析 这道题真的好水呀QwQ,想必大家都知道对于式子|x-2|+|x-3|x取什么值可以使式子结果最小,这道题也是这个原理,只需要将要额外减的1.2.3……提前减掉就行了. 代码 #inclu ...

  3. python3-list列表增删改查合并排序

    # Auther: Aaron Fan names = ["aaron", "alex", "james", "meihengfa ...

  4. Android调试之Logcat

    转贴  http://www.cnblogs.com/adison/p/4264284.html 在Android开发过程中,总免不了要调试,无论是Debug,还是Android自带的Logcat,抑 ...

  5. Entity Framework Tutorial Basics(19):Change Tracking

    Change Tracking in Entity Framework: Here, you will learn how entity framework tracks changes on ent ...

  6. Bulma 源码结构

    源码基于 Bulma 0.4.0 版本. 一.入口文件 bulma.sass bulma.sass 是 Bulma 使用 SASS 编译的入口文件. sass bulma.sass css/bulma ...

  7. IntelliJ+AntBuild+Tomcat实现Maven站点的热部署

    这段时间要研究WebGL技术,做一下三维建模项目,涉及到较多的前端编码.eclipse编译器那令人着急的编码提示功能,以及丑恶的界面对项目的开展造成了一定的阻碍.为解决这个问题,转向IntelliJ ...

  8. enum枚举型

    在实际编程中,有些数据的取值往往是有限的,只能是非常少量的整数,并且最好为每个值都取一个名字,以方便在后续代码中使用,比如一个星期只有七天,一年只有十二个月,一个班每周有六门课程等. 以每周七天为例, ...

  9. Java泛型读书笔记 (三)

    泛型对于老代码的支持 Java的泛型设计成类型擦除的目的,很大一部分是为了兼容老老代码.如下的一段代码: void setLabelTable(Dictionary table) table的类型是非 ...

  10. requireJS入门基础

    参考  require.js详解 1.引用requireJS的html文件 <!DOCTYPE html> <head> <title>requireJS</ ...