大数据运算
来源:互联网 发布:java帮助文档下载 编辑:程序博客网 时间:2024/05/30 23:04
1、大数的数据类型设计 可以用一个string和一个long long类型来表示一个大数类型,long long类型表示没有超出范围,string表示超出范围的大数。在初始化的时候我们可以将string和long long都进行初始化,在运算的时候再判断是用long long运算还是用string进行运算。typedef long long INIT64;class BigData{ friend ostream& operator<<(ostream& os,const BigData& b);public: BigData(INIT64 value=0); BigData(string strData); BigData operator+(BigData b); BigData operator-(BigData b); BigData operator*(BigData b); BigData operator/(BigData b);private: bool isINIT64overflow(const string& strData); string Add(string strLeft, string strRight); string Sub(string strLeft, string strRight); string Mul(string strLeft, string strRight); string Div(string strLeft, string strRight); char SubLoop(char* &pLeft, size_t& dataLen, const char *pRight, const size_t RSize); bool isLgtR(const char* pLeft, const size_t dataLen, const char *pRight, const size_t RSize);private: INIT64 _value; string _strData;};1.1、用一个整数初始化大数对象,其中sprintf的作用就相当于itoa.BigData::BigData(INIT64 value) :_value(value){ char buf[128] = { 0 }; sprintf(buf,"%lld",_value); _strData =buf;}1.2、用一个字符串初始化一个大数对象,考虑到输入的字符串可能有各种异常情况,比如前面一空白字符或0开头,出现字母等等,我们将常见的异常情况过滤掉(可以参考atoi是怎么进行过滤的)。BigData::BigData(string strData) :_value(0) , _strData("+0"){ char* pData = (char*)strData.c_str(); while (isspace(*pData)) //过滤空白 pData++; if ('\0' == *pData) return; char symbol = *pData; if (('+' == *pData) || ('-' == *pData)) //过滤符号 pData++; else if (isdigit(*pData)) symbol = '+'; else return; while('0' == *pData) //过滤前面的0 pData++; if ('\0' == *pData) return; _strData.resize(strlen(pData)+1); _strData[0] = symbol; int count = 1; while (*pData>='0' && *pData<='9') { _value = _value * 10 + *pData - '0'; _strData[count++] = *pData; pData++; } if (*pData) _strData.resize(count); if (symbol == '-') _value = 0 - _value;}1.3、判断一个大数是不是超出范围,因为整数的最大数据类型是long long类型,我们必须用string中的值进行判断,判断大数是不是超出范围。bool BigData::isINIT64overflow(const string& strData){ const string max_value= "+9223372036854775807"; const string min_value= "-9223372036854775808"; if (strData.size() < max_value.size()) return false; else if (strData.size() == max_value.size()) { if (('+'==strData[0]&&strData<=max_value)\ ||('-'==strData[0]&&strData>=min_value)) return false; } return true;}ostream& operator<<(ostream& os, const BigData& b){ const char *str = b._strData.c_str(); if ('+' == *str) cout << str + 1; else cout << str; return os;}2、加法的实现BigData BigData::operator+(BigData b){ if (!isINIT64overflow(_strData) && !isINIT64overflow(b._strData)) //如果都没溢出 { if (_strData[0] != b._strData[0]) //异号直接相加,不会溢出 return _value + b._value; else if ('+' == _strData[0] && '+' == b._strData[0]) { INIT64 max_value = 9223372036854775807; if (max_value - _value >= b._value) //两个正数相加不会溢出 { return _value + b._value; } } else if ('-' == _strData[0] && '-' == b._strData[0]) { INIT64 min_value =0-9223372036854775808; if (min_value - _value <= b._value) //两个负数相加不会溢出 { return _value + b._value; } } } if (_strData[0] == b._strData[0]) //同号相加 return BigData(Add(_strData, b._strData)); else //异号相加可以转换成减法 { //异号相加转换成正号相减 string Left = _strData; string Right = b._strData; Left[0] = '+'; Right[0] = '+'; if ('-' == _strData[0]) swap(Left,Right); return BigData(Sub(Left,Right)); }}string BigData::Add(string strLeft,string strRight){ size_t LSize = strLeft.size(); size_t RSize = strRight.size(); if (LSize < RSize) //为了方便,我们保证+号左边的数的位数不小于加号右边的数 { swap(strLeft,strRight); swap(LSize,RSize); } string strTemp; strTemp.resize(LSize+1); //两个数相加,结果的位数最长是两个运算数中位数最长的运算数加+1 strTemp[0] = strLeft[0]; char step = 0; //记录进位 for (size_t index = 1; index < LSize;index++) { char ret = strLeft[LSize - index]-'0'; ret += step; if (RSize>index) { ret=ret+strRight[RSize-index] - '0'; } step = ret / 10; //保存进位情况 strTemp[LSize + 1 - index] = ret%10+'0'; } strTemp[1] = step+'0'; //向最高位进位,取决于step的值 return strTemp;}3、减法的实现参考加法4、乘法的实现BigData BigData::operator * (BigData b){ if ("+0" == _strData || "+0" == b._strData) return BigData(0); if (!isINIT64overflow(_strData) && !isINIT64overflow(b._strData)) { INIT64 max_value = 9223372036854775807; INIT64 min_value = 0 - 9223372036854775808; if (_strData[0] == b._strData[0]) { if (('+' == _strData[0] && max_value / _value >= b._value) || \ ('-' == _strData[0] && max_value / _value <= b._value)) return _value*b._value; } else { if (('+' == _strData[0] && min_value / _value <= b._value) || \ ('-' == _strData[0] && min_value / _value >= b._value)) return BigData(_value*b._value); } } //判断运算数中有没有为正负1的特殊情况 if ("+1"==_strData) return BigData(b._strData); if ("+1" == b._strData) return BigData(_strData); if ("-1" == _strData) { string ret = b._strData; if ('+' == b._strData[0]) ret[0] = '-'; else ret[0] = '+'; return BigData(ret); } if ("-1" == b._strData) { string ret =_strData; if ('+' ==_strData[0]) ret[0] = '-'; else ret[0] = '+'; return BigData(ret); } return BigData(Mul(_strData, b._strData));}string BigData::Mul(string strLeft, string strRight){ size_t LSize = strLeft.size(); size_t RSize = strRight.size(); //乘法相乘的时候,保证*号左边的数的长度小于等于*号右边的数 if(LSize > RSize) { swap(LSize,RSize); swap(strLeft,strRight); } char symbol = '+'; if (strLeft[0] != strRight[0]) //异号相乘为负 symbol='-'; string strTemp; strTemp.resize(LSize+RSize-1,'0'); //两数相乘,结果的位数最长是两个运算数位数之和 strTemp[0] = symbol; //因为两个数相乘,即乘数的每一位都要和被乘数相运算,所以必须用两个循环 for (size_t i = 1; i < LSize;i++) { if ('0' == strLeft[LSize - i]) continue; char step=0; //记录进位 for (size_t j=1;j<RSize;j++) { char ret = strLeft[LSize-i]-'0'; ret*=(strRight[RSize-j]-'0'); ret += step+strTemp[LSize + RSize - j - i] - '0'; strTemp[LSize + RSize - j - i]= ret%10+'0'; step = ret / 10; } strTemp[LSize- i] += step; } return strTemp;}
5、除法的实现
除法的实现有些复杂,原理如下图所示:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
阅读全文
0 0
- 大数据的运算
- java大数据运算
- 大数据阶层运算
- 大数据运算
- 大数据运算
- 大数据运算
- 大数据阶乘运算-java高精度运算
- java 大数据次方运算
- 大数据的运算加减乘除
- 《C++大数据运算(+、-、*、/)》
- 算法实践之5 :大数据运算
- POJ1001幂次方的运算,大数据
- BigInteger用法-Java大数据存储、运算
- 大数据的存储及运算
- 小项目:大数据的基本运算
- MaxCompute大数据运算挑战与实践
- spark离线大数据运算程序编译
- 大数据运算系统(1)--- MapReduce
- 鼠标单击时jq特效
- 安装过程
- 设计模式之----简单工厂模式
- 高软实验三报告
- Python3之uuid模块
- 大数据运算
- 汇编学习之新手上路1+2+3+……+100
- Java——单例设计模式中懒汉式并发访问的安全问题
- Java中nextInt()后紧跟nextLine()方法造成的一些问题
- 分组密码加密的几种模式
- 读写锁与自旋锁
- 【广告算法工程师入门 19】机制设计-GFP和GSP下的策略行为与均衡分析
- java内部类的作用
- js获取项目路径