大数乘法C++实现

最近面试中老被问两个大数放一块相乘要怎么弄。以前没考虑过这些问题,周末花点时间把面试时说的思路实现出来,大意是把一个数字,比如1234567890按位分成几段后分别存在一个字符串里,然后按照做乘法的方法,分别取单个两个字符串去做运算,把值保存在字符串里。不知道这算不算要求的实现大数乘法。代码如下。

.h文件

#pragma once

#include <string>
#include <tchar.h>
typedef std::basic_string<TCHAR> NumberString;

class BigNumberHelp
{
public:
BigNumberHelp(void);
~BigNumberHelp(void);

public:
NumberString Multiply(const NumberString& str1, const NumberString& str2);

private:
void SplitStringToAray(const NumberString& str, unsigned int* &Buff, unsigned int& nSize);
void TryIncreaseBit(unsigned int* Buff, unsigned int nBuffSize, unsigned int nPos, unsigned int nNumber);//给容器某位加数,并进位

private:
unsigned int m_nBitSize; //每个数组中存放几位数字
unsigned int m_nBitMax; //每个数组中存放数字最大值+1
};

.cpp

#include "StdAfx.h"
#include "BigNumberHelp.h"
#include <math.h>

BigNumberHelp::BigNumberHelp(void)
{
TCHAR szBuff[100] = {0};
_ultot_s(UINT_MAX, szBuff, 100, 10); 

m_nBitSize = _tcslen(szBuff) / 2 -1;
m_nBitMax = pow(10.0, (double)m_nBitSize);

//m_nBitSize = 2 ;
//m_nBitMax = pow(10.0, (double)m_nBitSize);
}

BigNumberHelp::~BigNumberHelp(void)
{
}


NumberString BigNumberHelp::Multiply(const NumberString& strA, const NumberString& strB)
{
unsigned int* pBuffA = NULL;
unsigned int nBuffSizeA = 0;
unsigned int* pBuffB = NULL;
unsigned int nBuffSizeB = 0;

SplitStringToAray(strA, pBuffA, nBuffSizeA);
SplitStringToAray(strB, pBuffB, nBuffSizeB);


unsigned int nRetSize =nBuffSizeA + nBuffSizeB + 1;
unsigned int* pResult = new unsigned int[nRetSize];
memset(pResult, 0, nRetSize*sizeof(unsigned int));

for (unsigned int n = 0; n < nBuffSizeB; n++)
{
for (unsigned int k = 0; k < nBuffSizeA; k++)
{
unsigned int nRet = pBuffA[k] * pBuffB[n];
TryIncreaseBit(pResult, nRetSize, n+k, nRet);
}
} 

NumberString strRet;
TCHAR* szRet = new TCHAR[m_nBitSize+1];
memset(szRet, 0, (m_nBitSize+1)*sizeof(TCHAR));

TCHAR szFormat[10] = {0};
_sntprintf_s(szFormat, 10, 10, _T("%%0%dd"), m_nBitSize);

for (int i = nRetSize-1; i >= 0; --i)
{
_sntprintf_s(szRet, m_nBitSize+1, m_nBitSize, szFormat, pResult[i]);
strRet += szRet;
}

delete[] szRet;

NumberString::size_type nTrimPos = strRet.find_first_not_of(_T("0"));
if (nTrimPos != NumberString::npos)
{
strRet.erase(0, nTrimPos);
}

return strRet;
}

void BigNumberHelp::SplitStringToAray(const NumberString& str, unsigned int* &pBuff, unsigned int& nBuffSize)
{
if (str.empty())
return;

unsigned int nSize = str.size();
nBuffSize = ((nSize%m_nBitSize) != 0)?(nSize / m_nBitSize + 1):(nSize/m_nBitSize);
pBuff = new unsigned int[nBuffSize];
memset(pBuff, 0, nBuffSize*sizeof(unsigned int));

unsigned int nIndex = 0;

unsigned int nPos = nSize;
while (nPos >= m_nBitSize)
{
nPos -= m_nBitSize;
NumberString strTemp = str.substr(nPos, m_nBitSize);
unsigned int nTemp = _ttoi(strTemp.c_str());
pBuff[nIndex] = nTemp;
nIndex++;
}

if (nPos > 0)
{
NumberString strLast = str.substr(0, nPos);
unsigned int nLast = _ttoi(strLast.c_str());
pBuff[nIndex] = nLast;
}
}

void BigNumberHelp::TryIncreaseBit(unsigned int* Buff, unsigned int nBuffSize, unsigned int nPos, unsigned int nNumber)
{ 
if (nPos == nBuffSize) 
return;


int nRet = Buff[nPos] + nNumber;
int nBuffAdd = 0;
if (nRet >= m_nBitMax)
{
int nNewNum = nRet / m_nBitMax;
nBuffAdd = nRet - nNewNum*m_nBitMax; 
TryIncreaseBit(Buff, nBuffSize, nPos+1, nNewNum);
}
else
{
nBuffAdd = nRet;
}

Buff[nPos] = nBuffAdd;
}

测试:

 BigNumberHelp help;
 NumberString strA = _T("123456789987654321");
 NumberString strB = _T("1234567891");
 NumberString strRet = help.Multiply(strA, strB);







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值