大数相乘

class NodeData
{
public:
    NodeData* next;
    char num;
    NodeData() {num = '0'; next = NULL;}
};

NodeData* SetUpLinkList()
{
    NodeData* head = new NodeData;
    bool is_add = true;
    char data = 0;
    NodeData* p = head;
    while(1) {
        cin >> data;
        if ('a' == data ) break;
        NodeData* cur = new NodeData;
        cur->num = data;
        cur->next = NULL;
        p->next = cur;
        p = cur;
    }

    NodeData* tmp = head;
    head = head->next;
    delete tmp;

    return head;
}

NodeData* ReverseLink(NodeData*a)
{
    NodeData* res = NULL;
    if (NULL == a) return NULL;

    NodeData* head = a;
    NodeData* p = a;
    NodeData* q = a->next;

    while (NULL != q) {
        NodeData* r = q->next;
        q->next = p;
        p = q;
        q = r;
    }

    head->next = NULL;
    res = p;

    return res;
}

int digital_atoi(char chr)
{
    return chr - '0';
}

char digital_itoa(int i)
{
    return i + '0';
}

NodeData* Multiply(NodeData* a, NodeData* b)
{
    NodeData* total = NULL;
    if (NULL == a ||
        NULL == b) return NULL;

    NodeData* fir = ReverseLink(a);
    NodeData* sec = ReverseLink(b);
    int count = 0;
    while (NULL != sec) {
        int m = digital_atoi(sec->num);
        int flow = 0;//进位
        NodeData* head = new NodeData;
        NodeData* p = head;
        NodeData* left = fir;

        while (NULL != left) {
            int n = digital_atoi(left->num);
            int subtotal = m * n;
            
            int y = (subtotal + flow) % 10;
            flow = (subtotal + flow) / 10;

            NodeData* node = new NodeData;
            node->num = digital_itoa(y);
            p->next = node;
            p = node;
            
            left = left->next;
        }

        if (0 != flow) {
            NodeData* node = new NodeData;
            node->num = digital_itoa(flow);
            p->next = node;
            p = node;
        }

        //根据乘法竖式,得到某一位与被乘数相乘的结果,并且将此结果的低位用0补齐
        NodeData* subtotal_head = new NodeData;
        p = subtotal_head;
        for (int i = 0; i < count; i++)
        {
            NodeData* node = new NodeData;
            node->num = '0';
            node->next = NULL;
            p->next = node;
            p = node;
        }
        p->next = head->next;
        delete head;
        NodeData* del_node = subtotal_head;
        subtotal_head = subtotal_head->next;
        delete del_node;

        //算完了某一位的乘法后,将其结果与当前的total相加
        NodeData* sum_head = new NodeData;
        sum_head->next = NULL;
        NodeData* tmp = sum_head;
        flow = 0;
        bool bflag_added = false;
        while (NULL != total &&
               NULL != subtotal_head) {
                   bflag_added = true;
                   int n = digital_atoi(total->num);
                   int m = digital_atoi(subtotal_head->num);
                   int sum = m + n;
                   int y = (sum + flow) % 10;
                   flow = (sum + flow) / 10;
                   
                   NodeData* node = new NodeData;
                   node->num = digital_itoa(y);
                   node->next = NULL;
                   tmp->next = node;
                   tmp = node;

                   total = total->next;
                   subtotal_head = subtotal_head->next;
        }

        if (NULL != sum_head->next) {
            del_node = sum_head;
            sum_head = sum_head->next;
            delete del_node;
        }

        //上面加完后,可能有进位,有可能部分没加完
        if (bflag_added) {
            NodeData* continue_node = NULL;
            if (NULL != subtotal_head) {
                continue_node = subtotal_head;
            } else if (NULL != total) {
                continue_node = total;
            } else {
                //Do nothing
            }

            while (NULL != continue_node)
            {
                int n = digital_atoi(continue_node->num);
                int sum = n + flow;
                int y = sum % 10;
                flow = sum / 10;
                NodeData* node = new NodeData;
                node->num = digital_itoa(y);
                tmp->next = node;
                tmp = node;

                continue_node = continue_node->next;
            }

            if (0 != flow) {
                NodeData* node = new NodeData;
                node->num = digital_itoa(flow);
                node->next = NULL;
                tmp->next = node;
            }

            //删除临时结点
            while (NULL != subtotal_head) {
                del_node = subtotal_head;
                subtotal_head = subtotal_head->next;
                delete del_node;
            }

            while (NULL != total) {
                del_node = total;
                total = total->next;
                delete del_node;
            }
        } else {
            sum_head = subtotal_head;
        }
            
        total = sum_head;
        count++;

        sec = sec->next;
    }

    total = ReverseLink(total);

    return total;
}

int _tmain(int argc, _TCHAR* argv[])
{
    NodeData*left = SetUpLinkList();
    NodeData*right = SetUpLinkList();

    NodeData* res = Multiply(left, right);
    while (NULL != res) {
        cout << res->num;
        res = res->next;
    }

    while (NULL != res) {
        NodeData* del_node = res;
        res = res->next;
        delete del_node;
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值