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 这是一道高精度的运算,如果你之前有写过那种高精度的乘法的题目的话,做这个也还是比较简单的.. 思路:我是首先把小数点的位置确定下来,然后其 ...
随机推荐
- 一个典型的PHP分页实例代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- easyui layout 折叠之后显示标题
方法一:重载扩展panel收缩事件 (function($){ var buttonDir = {north:'down',south:'up',east:'left',west:'right'}; ...
- AdapterPattern(23种设计模式之一)
设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大 ...
- 算法Sedgewick第四版-第1章基础-002一些工具类算法(Euclid’s algorithm)
1. //Euclid’s algorithm public static int gcd(int p, int q) { if (q == 0) return p; int r = p % q; r ...
- Luogu 2312 [NOIP2014] 解方程
感觉好无聊. 秦九昭算法:一般地,一元n次多项式的求值需要经过(n+1)*n/2次乘法和n次加法,而秦九韶算法只需要n次乘法和n次加法.在人工计算时,一次大大简化了运算过程.(百度百科) 具体来说怎么 ...
- 格式化字符串攻击原理及示例.RP
格式化字符串攻击原理及示例 一.类printf函数簇实现原理 类printf函数的最大的特点就是,在函数定义的时候无法知道函数实参的数目和类型. 对于这种情况,可以使用省略号指定参数表. 带有省略号的 ...
- C语言关键字:auto、static、register、const、volatile 、extern 总结 <转>
auto 这个这个关键字用于声明变量的生存期为自动,即将不在任何类.结构.枚举.联合和函数中定义的变量视为全局变量,而在函数中定义的变量视为局部变量.这个关键字不怎么多写,因为所有的变量默认就是aut ...
- 解决java.lang.IllegalStateException: BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext问题
使用ClassPathXmlApplicationContext加载项目时, ClassPathXmlApplicationContext context = new ClassPathXmlAppl ...
- [raspberry pi3] zram设置
linux 3.15之后添加了个和mac一样的功能,内存压缩zram, 之前还有个zswap, zram通常是以模块的方式被放在系统里面的,以便在可以根据需求的不同,定制化加载. raspberry ...
- 别了,DjVu!
作者:马健邮箱:stronghorse_mj@hotmail.com发布:2010.05.21 目录一.DjVu技术二.掌握DjVu技术的人三.玩DjVu的人四.小结跋:我与DjVu 谨以此文纪念与D ...