LintCode 1398: K Decimal Addition

本文介绍了一种解决K进制数相加问题的算法,通过去除前导零、比较字符串长度并调整循环逻辑,实现高效求解。文章提供了三种不同的实现方式,包括去除前导零、使用循环进行逐位相加以及处理进位等关键步骤。

1398. K Decimal Addition

Give kab, which means a and b are all k base numbers, and output a + b.

Example

Example1

Input: k = 3, a = "12", b = "1"
Output: 20
Explanation: 
12 + 1 = 20 in 3 bases.

Example2

Input: k = 10, a = "12", b = "1"
Output: 13
Explanation: 
12 + 1 = 13 in 10 bases.

Notice

  • 2 <= k <= 10
  • a, b are strings, the length does not exceed 1000.
  • There may be a leading zero.

Input test data (one parameter per line)How to understand a testcase?

解法1:

class Solution {
public:
    /**
     * @param k: The k
     * @param a: The A
     * @param b: The B
     * @return: The answer
     */
    string addition(int k, string &a, string &b) {
        if (a.size() == 0) return b;
        if (b.size() == 0) return a;
        int non_zero_pos_a = 0;
        int non_zero_pos_b = 0;
        
        while(a[non_zero_pos_a] == '0') non_zero_pos_a++;
        while(b[non_zero_pos_b] == '0') non_zero_pos_b++;
        
        a = a.substr(non_zero_pos_a);
        b = b.substr(non_zero_pos_b);
        int len_a = a.size();
        int len_b = b.size();
        
        int min_len = min(len_a, len_b);
        int carry = 0;
        string result;
        for (int i = 0; i < min_len; ++i) {
            int v_a = a[len_a - 1 - i] - '0';
            int v_b = b[len_b - 1 - i] - '0';
            int v = v_a + v_b + carry;
            carry = v / k;
            v %= k;            
            result = to_string(v) + result;
        }
        len_a -= min_len; len_b -= min_len;

        if (len_a == len_b) {
            if (carry == 0)  return result;
            return '1' + result;
        }
        
        string c = (len_a > 0) ? a.substr(0, len_a) : b.substr(0, len_b);
        int len_c = (len_a > 0) ? len_a : len_b;
        for (int i = len_c - 1; i >= 0; --i) {
            int v_c = c[i] - '0';
            int v = v_c + carry;
            carry = v / k;
            v %= k;
            result = to_string(v) + result;
            len_c--;
        }
        
        if (carry > 0) return '1' + result;
        return result;
    }
};

解法2:上面的解法稍微有点冗余,因为有2段核心程序重复了。下面是标准解法,没有冗余,用一个循环就实现了。

注意: 可在一开始的时候把a,b中较长的那个指定为a, 短的那个指定为b。

class Solution {
public:
    /**
     * @param k: The k
     * @param a: The A
     * @param b: The B
     * @return: The answer
     */
    string addition(int k, string &a, string &b) {
        int temp = 0;
        for(int i = 0; i < a.size(); i++) {
            if(a[i] != '0') {
                a = a.substr(i);
                break;
            }
        }
        for(int i = 0; i < b.size(); i++) {
            if(b[i] != '0') {
                b = b.substr(i);
                break;
            }
        }
        if(a.size() < b.size()) {
            swap(a, b);
        }
        int j = b.size() - 1;
        for(int i = a.size() - 1; i >= 0; i--) {
            int sum = a[i] - '0';
            if(j >= 0) {
                sum += b[j] - '0';
                j--;
            }
            if(temp != 0) {
                sum += temp;
            }
            a[i] = '0' + sum % k;
            temp = sum / k;
        }
        string ans;
        if(temp != 0) {
            ans.push_back(temp + '0');
        }
        ans = ans + a;
        return ans;
    }
};

二刷:
 

class Solution {
public:
    /**
     * @param k: The k
     * @param a: The A
     * @param b: The B
     * @return: The answer
     */
    string addition(int k, string &a, string &b) {
        string res = "";
        int posa = a.size() - 1, posb = b.size() - 1, carry = 0;
        int starta = 0, startb = 0;

        for (int i = 0; i < posa; i++) {
            if (a[i] != '0') {
                starta = i;
                break;
            }
        }
        for (int i = 0; i < posb; i++) {
            if (b[i] != '0') {
                startb = i;
                break;
            }
        }

        while (posa >= starta || posb >= startb) {
            int numa = posa >= 0 ? a[posa] - '0' : 0;
            int numb = posb >= 0 ? b[posb] - '0' : 0;
            int num = numa + numb + carry;
            if (num >= k) {
                carry = 1;
                num = num - k;
            } else {
                carry = 0;
            }
            res = to_string(num) + res; //res = (char)(num + '0') + res; is also OK
            posa--;
            posb--;
        }
        
        if (carry > 0) res = '1' + res;
       
        return res;
    }
};

三刷:

class Solution {
public:
    /**
     * @param k: The k
     * @param a: The A
     * @param b: The B
     * @return: The answer
     */
    string addition(int k, string &a, string &b) {
       string res;
       //remove heading zeros
       while (a[0] == '0') a = a.substr(1);
       while (b[0] == '0') b = b.substr(1);
       int sizeA = a.size(), sizeB = b.size();
       int posA = sizeA - 1, posB = sizeB - 1;
       int carry = 0, sum = 0;
       while (posA >= 0|| posB >= 0) {
           sum = carry;
           if (posA >= 0) {
               sum += a[posA] - '0';
               posA--;
           }
           if (posB >= 0) {
               sum += b[posB] - '0';
               posB--;
           }
           carry = sum / k;
           sum = sum % k;
           res = to_string(sum) + res;
       }
       if (carry > 0) res = to_string(carry) + res;
       return res;
    }
};


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值