poj 1001 字符串乘法以及处理精度问题
#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 字符串乘法以及处理精度问题的更多相关文章
- [POJ 1001] Exponentiation C++解题报告 JAVA解题报告
Exponentiation Time Limit: 500MS Memory Limit: 10000K Total Submissions: 126980 Accepted: 30 ...
- POJ 1001 Exponentiation(大数运算)
POJ 1001 Exponentiation 时限:500 ms 内存限制:10000 K 提交材料共计: 179923 接受: 43369 描述:求得数R( 0.0 < R < ...
- 1001 字符串“水”题(二进制,map,哈希)
1001: 字符串“水”题 时间限制: 1 Sec 内存限制: 128 MB提交: 210 解决: 39[提交][状态][讨论版] 题目描述 给出一个长度为 n 的字符串(1<=n<= ...
- POJ 1001 解题报告 高精度大整数乘法模版
题目是POJ1001 Exponentiation 虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于 ...
- [POJ] #1001# Exponentiation : 大数乘法
一. 题目 Exponentiation Time Limit: 500MS Memory Limit: 10000K Total Submissions: 156373 Accepted: ...
- POJ 1001 Exponentiation 无限大数的指数乘法 题解
POJ做的非常好,本题就是要求一个无限位大的指数乘法结果. 要求基础:无限大数位相乘 额外要求:处理特殊情况的能力 -- 关键是考这个能力了. 所以本题的用例特别重要,再聪明的人也会疏忽某些用例的. ...
- 【POJ 1001】Exponentiation (高精度乘法+快速幂)
BUPT2017 wintertraining(15) #6A 题意 求\(R^n\) ( 0.0 < R < 99.999 )(0 < n <= 25) 题解 将R用字符串读 ...
- poj 1001 java大精度
import java.io.* ; import java.math.* ; import java.util.* ; import java.text.* ; public class Main ...
- poj 1001
http://poj.org/problem?id=1001 这是一道高精度的运算,如果你之前有写过那种高精度的乘法的题目的话,做这个也还是比较简单的.. 思路:我是首先把小数点的位置确定下来,然后其 ...
随机推荐
- ngx-bootstrap使用01 安装ngx-bootstrap和bootstrap及其使用、外部样式引入
1 版本说明 2 新建一个angular项目 ng new 项目名 --stayle=scss 代码解释:创建一个样式文件格式为SCSS的angular项目 技巧01:由于我angular-cli的版 ...
- jetty启动常用命令
1. 启动Jetty Server:运行命令:Java -jar start.jar 指定项目名称启动: java -jar start.jar -Dname=zoush 保持jetty后台 ...
- ENCODE:DNA 分子元件的百科全书
ENCODE(DNA分子元件的百科全书)是由国家人类基因研究所(NHGRI)资助的一个国际研究联盟, 该联盟的目标是:建立一份综合的人类基因组功能元件的清单,这些基本元件包括那些直接作用蛋白质和RNA ...
- 同一个id出现多条数据的问题
这是disial出现的一个bug,花了近两天时间才解决,原因,要在dto的类前加上注解,让它延迟加载. -----后期补充.结合代码.
- IDEA工作中常用快捷键
ctrl+shift+t: Ubuntu中在一个工具栏中打开两个终端 shift+shift: 搜索任何类 ctrl+N: 搜索任何类 ctrl+right: forward----自定义 ctrl+ ...
- C++二进制文件读写
简单二进制文件读写,多文件 /*Demo9.1.cpp*/ #include <iostream> #include <fstream> #include <string ...
- 数据结构_coprime_sequence(互质序列)
coprime_sequence(互质序列) 问题描述 顾名思义,互质序列是满足序列元素的 gcd 为 1 的序列.比如[1,2,3],[4,7,8],都是互质序列. [3,6,9]不是互质序列.现在 ...
- SpringMVC 配置式开发-BeanNameUrlHandlerMapping(七)
第一种处理器映射器BeanNameUrlHandlerMapping.class(注册器映射器 bean节点的class属性中用到的,这种方式dean id属性必须要以“/”开头) 第二种处理器映射 ...
- postgre教程
http://www.yiibai.com/html/postgresql/2013/080890.html
- Fragment之间通过add切换时的显示与隐藏
新手,不知道用什么方法实现 ,通过动态的方法显示了Fragment A,在这个里面点击列表项时add方法动态加载Fragment B,但是两者都会一起显示,重叠在一起了,如果用replace方法 ...