大数据运算

来源:互联网 发布:网页淘宝自动跳转app 编辑:程序博客网 时间:2024/05/08 20:13

大数据处理 

在平常的编程中 我们会遇到很多的,这些数据的值 超出了     整型int的最大范围  ;甚至超过了long long的数据范围;
遇到这种情况,我们的数据处理就会变的十分的麻烦。因为我们不可以使用整型变量来表示这些值当然也就不可使用四则运算来,就算这些值的加减乘除的算术。
当遇到这种情况的时候,我么就需要来使用字符串来表示一个数 ;
当然,也要使用字符串来进行相应的四则运算了;;;;
下面是我实现的大数据计算函数 ;   (希望大家来看看,帮我检查错误)
下面是一下函数原型:
//BigData.h  文件#pragma once#include<string.h>#include<string>typedef long long  INT64;//表示出两个极端值#define MAXINT64 (INT64)0x7fffffffffffffff #define MININT64 (INT64)0x8000000000000000 class BigData{public://三种的构造函数 BigData():_value(0),_str(string()),_IsOverFlow(false){_str.resize(3);_str[0] = '+';_str[1] ='0';_str[2] = 0;}BigData(const  char *  str);BigData(const INT64 value);//判断一个数有没有越界bool IsOverFlow(const  char  * str);//重载实现的  +  -  *  /  %BigData operator+(const  BigData& data);BigData operator-(const  BigData& data);BigData operator*(const  BigData& data);BigData operator/(const  BigData& data);BigData operator%(const  BigData& data);//重载的比较函数bool operator>(const  BigData& data);bool operator<(const  BigData& data);bool operator==(const  BigData& data);bool operator!=(const  BigData& data);protected:INT64_value;//当前的数 没有溢出,,,表示string  _str;//字符串表示bool_IsOverFlow;//表示的是当前的数有有没越界};//str1   长度  大于 str2//str1  与  str2不戴符号//实现两个字符串的  四则运算,,,,一般情况下,,str1 长度要大于str2string   StrAddStr(char *str1,char *str2);string   StrSubStr(char *str1,char *str2);string   StrMulStr(char *str1,char *str2);string   StrDivStr(char *str1,char *str2);string   StrRemStr(char *str1,char *str2);//测试用例void TestBigData();
函数代码的实现:
#include<iostream>using namespace std;#include"BigData.h"#include<assert.h>//定义极端值的两个字符串  全局const char  * MAXCHAR64= "+9223372036854775807";const char  * MINCHAR64= "-9223372036854775807";//构造函数 //字符串构造要考虑的情况// 字符串 "1234568"  "    2325"//  "000000123" "000123 34"// "+1234"  "-132"// "+   780" "+as"BigData::BigData(const  char *  s):_IsOverFlow(false),_str(string()),_value(0){//传进来的数 是 一个null字符串if(s == NULL){//数据给上 0 _str.resize(3,'0');_str[0] = '+';_str[1] = '0';_str[2]  =0 ;return  ;}char  *  str = (char*)s;//清楚 空格  还有   0 while(*str == '0'||*str == ' '){++str;}//symbol表示的是 符号 char  symbol  = '+';//当前的数是正数if(*str  == '+'){str++;}//表示的是当前的数是负数else if(*str == '-'){symbol = '-';++str;}while(*str == '0'||*str == ' '){++str;}//表示没有数if(*str == 0){_str.resize(3,'0');_str[0] = '+';_str[1] = '0';_str[2]  =0 ;return  ;}if(*str  >= '0'&&*str <= '9'){}else{_str.resize(3,'0');_str[0] = '+';_str[1] = '0';_str[2]  =0 ;return  ;}//将数据读到_str中 int size = strlen(str); //size +2  表示字符串 + '\0' +符号 _str.resize(size+2,'0');//赋值\0 _str[0] =symbol ;//给定符号 int idex = 1; INT64 value =  0; while(*str) { if(*str >= '0'&&*str <= '9') { _str[idex] = *str;idex++;str++; } else { break; } } _str[idex] = 0; //判断传进来的这个字符串,有没有越界 _IsOverFlow = IsOverFlow(_str.c_str()); //要是没有越界的话   _value 附上值 if(_IsOverFlow == false) { char  *  tmp =  (char*)_str.c_str(); int num = 1;  if(*tmp == '-') num =-1; ++tmp; while(*tmp) { _value = _value * 10 +*tmp -'0'; tmp++; } } if(_str[0] == '-') _value = -_value;}//构造函数 使用的是 数字 //传进来的数字肯定不会越界BigData::BigData(const INT64 value):_str(string()),_value(value),_IsOverFlow(false){//将数字转换成字符串int base = 10;int idex = 1;INT64 num = abs(value);//得到数字的长度   idex// 9   <  10  1// 10  >= 10  2// 100 >= 100 3while(num >= base){idex++;base *= 10;}base /= 10;_str.resize(idex+2,'0');if(value > 0)_str[0] = '+';else_str[0] = '-';int tmp= 1;while(tmp <= idex){INT64 data = num/base;_str[tmp++] = data+'0';num = num%base;base /=10;}_str[idex+1] = 0;}//是否越界bool BigData::IsOverFlow(const  char  *str){int size1= strlen(str);int size2= strlen(MAXCHAR64);//要是没超过最长的值if(size1 < size2)return false;if(size1 == size2){if(strcmp(str,MAXCHAR64) <= 0 && strcmp(str,MINCHAR64)>=0)return  false;}return  true;}//重载bool BigData::operator>(const  BigData& data){char  *  str1  = (char *) _str.c_str();char  *  str2  = (char *)data._str.c_str();//两个的长度 int size1 =  strlen(str1);int size2 =  strlen(str2);//一个是正一个是负if(str1[0] == '+'&&str2[0] == '-')return true;//两个数都是正数if(str1[0] == '+'&&str2[0] == '+'){if(size1 > size2)return true;if(size1 == size2)return (strcmp(str1,str2) > 0)?true:false;}//两个数都是负数if(str1[0] == '-'&&str2[0] == '-'){if(size1 < size2)return true;if(size1 == size2)return (strcmp(str1,str2) < 0)?true:false;}return false;}bool BigData::operator<(const  BigData& data){if(operator>(data) == true)return false;if(operator==(data) == true)return  false;return  true;}bool BigData::operator==(const  BigData& data){char  *  str1  = (char *) _str.c_str();char  *  str2  = (char *)data._str.c_str();if(str1[0] != str2[0])return false;return  (strcmp(str1,str2) ==  0)?true:false;}bool BigData::operator!=(const  BigData& data){return  (operator==(data) == true)?false:true;}//假设传进来的size1>size2string   StrSubStr(char *str1,char *str2){int size1 =strlen(str1);int size2 =strlen(str2);if(strcmp(str1,str2) == 0)return string();string  tmp;tmp.resize(size1+1,'0');char * ret  = (char*)tmp.c_str();char*  end = ret + size1;*end = 0;end--;char  *end1 = str1+size1-1;char  *end2 = str2+size2-1;char  borrow  = 0;//表示的是借位while(end1 >= str1&& end2>=str2){int data  = *end1 -  *end2  - borrow;if(data >= 0 ){*end  =data+'0';borrow = 0;}else{*end = data+10+'0';borrow = 1;}end1--;end2--;end--;}while(end1 >= str1){int data  = *end1 - borrow -'0';if(data >= 0 ){*end  =data+'0';borrow = 0;}else{*end = data+10+'0';borrow = 1;}end1--;end--;}if(borrow == 1)assert(false);end++;string  str(end);return str;}string   StrAddStr(char *str1,char *str2){int size1 =strlen(str1);int size2 =strlen(str2);string  tmp;tmp.resize(size1+2,'0');char * ret  = (char*)tmp.c_str();char*  end = ret + size1+1;*end = 0;end--;char  *end1 = str1+size1-1;char  *end2 = str2+size2-1;char  carry  = 0;//表示的是借位while(end1 >= str1&& end2 >=str2){int data = (*end1 -'0')+(*end2 -'0')+carry;if(data >= 10){*end  = data-10 +'0';carry = 1;}else{*end = data+'0';carry  = 0 ;}end--;end1--;end2--;}while(end1 >=str1){int data = *end1 + carry -'0';if(data >= 10){*end  = data-10 +'0';carry = 1;}else{*end = data+'0';carry  = 0 ;}end --;end1--;}if(carry == 1)*end = '1';elseend++;string  str(end);return str;}string   StrMulStr(char *str1,char *str2){int size1  =strlen(str1);int size2  =strlen(str2);string str;str.resize(size1+size2+2,'0');//end表示的是 新建  字符串的尾char *end= (char*)str.c_str() + size1+size2+1;*(end--) = 0;char *end1 = str1 + size1-1;char *end2 = str2 + size2-1;int idex = 0;//表示的是 +上几个 0while(end2 >= str2){char  *tmp  = end1;int  carry = 0 ;string ch ;ch.resize(size1+2+idex,'0');*((char * )ch.c_str()+size1+1+idex) = 0;//补上\0char * it = (char * )ch.c_str() + size1;while(1){int data = (*tmp - '0')*(*end2 -'0')+carry;carry = data/10;*it = data%10 +'0';if(tmp == str1){if(carry != 0){*(--it) = carry+'0';break;}else{break;}}else{--it;}tmp--;}//得到每次成一位的得到的char  * res =(char*)str.c_str(); string  tmp1 =  StrAddStr(res,it);memcpy(end-strlen(tmp1.c_str())+1,tmp1.c_str(),strlen(tmp1.c_str()));end2--;++idex;}return str; }string   StrDivStr(char *str1,char *str2){int size1 = strlen(str1);int size2 = strlen(str2);if(size1 <size2){return string("0");}if(strcmp(str1,str2) == 0){return string("1");}string  ret;//用来保存每次的结果string  str(str1,str1+size2);//保存的是每次被除数 int idex = size2;//表示的是当前的被除数到了第几位//str2表示的是除数//str1表示的是被除数//str表示的是每次的被除数//ret表示每次除后得到的结果while(idex <= size1){if(strcmp(str.c_str(),str2)== 0){ret.push_back('1');str.clear();if(idex == size1){break;}str.push_back(str1[idex]);++idex;}else if((strlen(str.c_str()) == strlen(str2)&&strcmp(str.c_str(),str2) > 0)||(strlen(str.c_str()) > strlen(str2))){char  tmp[]  = "1";string remainder;//表示每次除下来的  余数while(1){   string  x= StrMulStr(str2,tmp);char  * dest = (char*)(x.c_str());while(*dest == '0'){++dest;}if((strlen(dest)==strlen(str1)&&strcmp(dest,str1) > 0)||strlen(dest) >strlen(str1)){tmp[0]--;remainder = StrSubStr((char*)str.c_str(),(char*)StrMulStr(str2,tmp).c_str());break;}else if((strlen(dest)==strlen(str1)&&strcmp(dest,str1)==0)){break;}else{tmp[0]++;}}ret.push_back(tmp[0]);str = string(remainder.begin(),remainder.end());if(idex == size1){break;}str.push_back(str1[idex]);++idex;}else{ret.push_back('0');if(idex == size1){break;}str.push_back(str1[idex]);++idex;}}return ret;}string   StrRemStr(char *str1,char *str2){int size1 = strlen(str1);int size2 = strlen(str2);if(size1 <size2){return string(str1);}if(strcmp(str1,str2) == 0){return string();}else{string  Div = StrDivStr(str1,str2);string  Mul = StrMulStr(str2,(char*)Div.c_str());return  StrSubStr(str1,(char*)Mul.c_str());}}BigData BigData::operator+(const BigData& data){//要是有一个数 0 if(_IsOverFlow == false&&_value == 0){return data;}if(data._IsOverFlow == false&&data._value == 0){return *this;}//两个数都没有越界if(_IsOverFlow == false&&data._IsOverFlow == false){//两个数  正负号相反if((_str[0] == '+'&&data._str[0] == '-')||(_str[0] == '-'&&data._str[0] == '+'))return BigData(_value + data._value);//两个数都是正数 ,,,加起来的和是 也没有越界if((_str[0] == '+'&&data._str[0] == '+')&& MAXINT64 -  _value >= data._value)return BigData(_value + data._value);//两个数都是负数,加起来的和没有越界if((_str[0] == '-'&&data._str[0] == '-')&&MININT64 - _value <= data._value)return BigData(_value + data._value);}//剩下的肯定都是越界的处理 //字符串的相加 //要是两个数 不同号char  *  str1  = (char *) _str.c_str();char  *  str2  = (char *)data._str.c_str();//保证str1 的长度 大于是str2if(strlen(str1) <strlen(str2)){swap(str1,str2);}else if(strlen(str1) == strlen(str2)){if(strcmp(str1+1,str2+1) < 0)swap(str1,str2);}//两个数异号   结果符号 为大的数的 符号  也就是是str1if((str1[0] == '+'&&str2[0] == '-')||(str1[0] == '-'&&str2[0]=='+')){string  ret = StrSubStr(str1+1,str2+1);char  *str= (char *)ret.c_str();char  *tmp = new char[2+strlen(str)];tmp[0]= str1[0];memcpy(&tmp[1],str,strlen(str)+1);BigData value(tmp);delete[] tmp;return value;}//两个数同号else{string  ret = StrAddStr(str1+1,str2+1);char  *str= (char *)ret.c_str();char  *tmp = new char[2+strlen(str)];tmp[0]= str1[0];memcpy(&tmp[1],str,strlen(str)+1);BigData value(tmp);delete[] tmp;return value;}}BigData BigData::operator-(const  BigData& data){//要是有一个数 0 if(_IsOverFlow == false&&_value == 0){return BigData(-data._value);}if(data._IsOverFlow == false&&data._value == 0){return *this;}//两个数都没有越界 if(_IsOverFlow == false&&data._IsOverFlow == false){//减了之后也没有越界//两个数同号if((_str[0] == '+'&&data._str[0] == '+')||(_str[0] == '-'&&data._str[0] == '-')){return BigData(_value - data._value);}// +  - if((_str[0] == '+'&&data._str[0] == '-')&&MAXINT64 + data._value >= _value){return BigData(_value - data._value);}//- +if((_str[0] == '-'&&data._str[0] == '+')&&MININT64 + data._value <= _value){return BigData(_value - data._value);}}//表示的是两个数 本身越界,,,或者是减了之后越界int symbol = 0;char  *  str1  = (char *) _str.c_str();char  *  str2  = (char *)data._str.c_str();if(strlen(str1) <strlen(str2)){swap(str1,str2);symbol = 1;}//两个要是相等else if(strlen(str1) == strlen(str2)){if(strcmp(str1+1,str2+1) < 0){swap(str1,str2);symbol = 1;}}//两个同号if((str1[0] == '+'&&str2[0] == '+')||(str1[0] == '-'&&str2[0]=='-')){string  ret = StrSubStr(str1+1,str2+1);char  *str= (char *)ret.c_str();char  *tmp = new char[2+strlen(str)];if(symbol == 1){tmp[0]= '-';}else{tmp[0] = '+';}memcpy(&tmp[1],str,strlen(str)+1);BigData value(tmp);delete[] tmp;return value;}//两个不同号 else{string  ret = StrAddStr(str1+1,str2+1);char  *str= (char *)ret.c_str();char  *tmp = new char[2+strlen(str)];if(symbol ==1){tmp[0] = str2[0];}else{tmp[0]= str1[0];}memcpy(&tmp[1],str,strlen(str)+1);BigData value(tmp);delete[] tmp;return value;}}BigData BigData::operator*(const  BigData& data){//有一个数 0if(_IsOverFlow ==false&&_value == 0)return BigData();if(data._IsOverFlow == false&&data._value == 0)return BigData();char  *  str1 = (char *)_str.c_str();char  *  str2 = (char *)data._str.c_str();//当两个数没有越界的话,,,且相乘之后也没有yuejieif(_IsOverFlow == false&&data._IsOverFlow == false){if((strlen(str1)+strlen(str2))  < strlen(MAXCHAR64))return BigData(_value *data._value);}//保证str1长度大于是str2if(strlen(str1) < strlen(str2)){swap(str1,str2);}//当两个数是同号,结果肯定是+if((str1[0] == '+'&&str2[0] == '+')||(str1[0]=='-'&&str2[0] =='-')){string  ret = StrSubStr(str1+1,str2+1);return BigData(ret.c_str());}//两个数是 异号的,,,结果是 -else{string  ret = StrAddStr(str1+1,str2+1);char  *str= (char *)ret.c_str();char  *tmp = new char[2+strlen(str)];tmp[0] = '-';memcpy(&tmp[1],str,strlen(str)+1);BigData value(tmp);delete[] tmp;return value;}}BigData BigData::operator/(const  BigData& data){if(data._IsOverFlow == false &&data._value == 0){throw invalid_argument("除数不能为 0\n");}if(_IsOverFlow == false&&_value == 0)return  BigData();if(_IsOverFlow == false&&data._IsOverFlow == false)return BigData(_value/data._value);char  *str1 = (char * )_str.c_str();char  *str2 = (char * )data._str.c_str();if((str1[0] == '+'&&str2[0] == '+')||(str1[0] == '-'&&str2[0] == '-')){return BigData(StrDivStr(str1,str2).c_str());}else{string  ret = StrDivStr(str1+1,str2+1);char  *str= (char *)ret.c_str();char  *tmp = new char[2+strlen(str)];tmp[0] = '-';memcpy(&tmp[1],str,strlen(str)+1);BigData value(tmp);delete[] tmp;return value;}}BigData BigData::operator%(const  BigData& data){if(data._IsOverFlow == false &&data._value == 0){throw invalid_argument("除数不能为 0\n");}if(_IsOverFlow == false&&_value == 0)return  BigData();if(_IsOverFlow == false&&data._IsOverFlow == false)return BigData(_value%data._value);char  *str1 = (char * )_str.c_str();char  *str2 = (char * )data._str.c_str();if(str1[0] == '+'){return BigData(StrRemStr(str1,str2).c_str());}else{string  ret = StrRemStr(str1+1,str2+1);char  *str= (char *)ret.c_str();char  *tmp = new char[2+strlen(str)];tmp[0] = '-';memcpy(&tmp[1],str,strlen(str)+1);BigData value(tmp);delete[] tmp;return value;}}void TestBigData(){BigData data("+1234");BigData data1;BigData data2("-456");BigData  data3(1);data1 = data%data2;string  str = StrRemStr("1234","456");}


0 0