Bootstrap

C++笔试强训day5

目录

1.大数加法

2.链表相加

3.大数乘法


1.大数加法

链接

就是模拟就好了,模拟加法计算的过程:

class Solution {
  public:
    int tmp, m, n;

    string solve(string s, string t) {
        string ret;

        m = s.size() - 1;
        n = t.size() - 1;
        tmp = 0;

        while (m >= 0 || n >= 0 || tmp) {
            if (m >= 0) {
                tmp += s[m] - '0';
                m--;
            }
            if (n >= 0) {
                tmp += t[n] - '0';
                n--;
            }
            ret += tmp % 10 + '0';
            tmp /= 10;
        }
        
        reverse(ret.begin(), ret.end());
        return ret;
    }
};

最后别忘记将ret逆置一下,因为是从尾开始存入的。

2.链表相加

链接

因为要模拟加法运算,链表又是单向的,所以需要将其逆转,再进行加法模拟。

即(逆序 + 高精度加法

注意:最后的结果是倒过来的,所以需要写逆置再返回。

详细代码:

class Solution {
public:
    ListNode* Reverse(ListNode* head)
    {
        ListNode* newhead = new ListNode(0);

        ListNode* cur = head;
        while(cur)
        {
            ListNode* next = cur->next;
            cur->next = newhead->next;
            newhead->next = cur;

            cur = next;
        }
        cur = newhead->next;

        delete newhead;
        newhead = nullptr;

        return cur;
    }

    ListNode* addInList(ListNode* head1, ListNode* head2) {
        head1 = Reverse(head1);
        head2 = Reverse(head2);
        
        ListNode* reth = new ListNode(0);
        ListNode* prev = reth;

        int t = 0;
        ListNode* cur1 = head1, *cur2 = head2;
        while(cur1 || cur2 || t)
        {
            if(cur1)
            {
                t += cur1->val;
                cur1 = cur1->next;
            }

            if(cur2)
            {
                t += cur2->val;
                cur2 = cur2->next;
            }
            prev = prev->next = new ListNode(t % 10);
            t /= 10;
        }
        ListNode* cur = reth->next;
        delete reth;
        reth = nullptr;
    
        return Reverse(cur);
    }
};

3.大数乘法

链接

实际上就是模拟乘法运算。

根据上述分析可以得到,其在一个点的和的下标正好为s和t的下标相加。(因此将每个string反过来更好分析和计算【因为下标的缘故】

最后将得到的和进行高精度加法就可得结果(返回时记得除去前导零与逆置

这道题要处理的细节还是蛮多的,要多加分析特殊情况

详细代码:

class Solution {
public:
  string solve(string s, string t) {
        int m = s.size();
        int n = t.size();

        vector<int> tmp(m + n);
        string ret;
        reverse(s.begin(), s.end());
        reverse(t.begin(), t.end());

        // 用vector存储每个位置的和
        for(int i = 0; i < m; ++i)
        {
            for(int j = 0; j < n; ++j)
            {
                tmp[i + j] += (s[i] - '0') * (t[j] - '0');
            }
        }

        // 遍历vector且高精度相加
        int tt = 0;
        for(int i : tmp)
        {
            int sum = i + tt;
            ret += sum % 10 + '0';
            tt = sum / 10;
        }

        // 加上剩余的进位
        while(tt)
        {
            ret += tt % 10 + '0';
            tt /= 10;
        }

        // 出去前导0
        while(ret.size() > 1 && ret.back() == '0') 
            ret.pop_back();

        // 逆置返回
        reverse(ret.begin(), ret.end());
        return ret;
    }
};

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;