[LeetCode]415. Add Strings(计算两个字符串表示的数字的和)
2017-05-29 21:43
363 查看
415. Add Strings
原题链接Given two non-negative integers num1 and num2 represented as string, return the sum of num1 and num2.
给定两个用字符串表示的非负整数num1和num2,返回用字符串表示的num1和num2的和。
Note:
The length of both num1 and num2 is < 5100.(长度都是<5100)
Both num1 and num2 contains only digits 0-9.(只包含数字0-9)
Both num1 and num2 does not contain any leading zero.(不包含任何前导零)
You must not use any built-in BigInteger library or convert the inputs to integer directly.(不得使用任何内置的BigInteger库或直接将输入转换为整数)
先写出自己的理解,最下面是最好的解法
错误思路1:
刚开始把第一个Node看成了num1和num2小于5100,紧接着整体的想法就歪了。。。。
先将num1和num2转化为整数,相加后将结果转化为字符串输出
代码只能将在int范围的整数正确求和,超出int返回就发生错误,输出-1
错误代码1:
#include <iostream> #include <string> using namespace std; class Solution { public: string addStrings(string num1, string num2) {//错误 只能运行在int范围内 题目要求num1和num2长度小于5100 int NUM1 = stringToInt(num1); int NUM2 = stringToInt(num2); return intToString(NUM1+NUM2); } string intToString(int i){//整数转化为字符串 string s = ""; if(i < 0) return "-1"; if(i == 0) s = "0"; while(i > 0){ int temp = i%10; s = intToChar(temp) + s; i /= 10; } return s; } int stringToInt(string s){//字符串转化为整数 int Length = s.size(); int t = 1; int num = 0; for(int i=Length-1; i>=0; i--){ int temp = charToInt(s[i]); num += temp*t; t *= 10; } return num; } int charToInt(char c){//字符转化为整数 char charArray[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; for(int i=0; i<=9; i++){ if((charArray[i]^c) == 0){// ^ 优先级小于 ==, 必须在charArray[i]^c外加括号 return i; } } return -1; } char intToChar(int i){//整数转化为字符 char charArray[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; for(int m=0; m<=9; m++){ if((m^i) == 0){// ^ 优先级小于 ==, 必须在charArray[i]^c外加括号 return charArray[m]; } } return '-1'; } }; int main() { Solution S; string num1 = "13423452345345"; string num2 = "93423423423423423"; cout << S.addStrings3(num1, num2) << endl; return 0; }
正确思路1:
在错误思路1的基础上,我曾尝试将int改成long等各种类型,发现题目规定的范围太大了,数字类型都无法满足,只能换一个想法
思路是分情况讨论,字符串相等或不相等
字符串不相等时,将两个字符串相加,长字符串分成两部分,一部分是长字符串的右半部分(即低位),和短字符串长度相同,另一部分是剩下的字符串,左半部分(即高位)
将右半部分和短字符串相加得到一个数,加上左半部分
为此我还专门写了两个函数,一个用于相等字符串相加,一个用于不相等字符串相加(其实就是将不等的两个字符串分割开,利用相等字符串相加的函数求解)
最后历经坎坷,终于通过了,但是效率不是太高
代码如下:
#include <iostream> #include <string> using namespace std; class Solution { public: string addStrings1(string num1, string num2) {//正确 但是效率太低 12ms int length1 = num1.size(); int length2 = num2.size(); if(length1>length2) return addStrings2(num1, num2, length1, length2); else if(length1<length2) return addStrings2(num2, num1, length2, length1); else{//两个字符串长度相等 int a =0; string res = addStr(num1, num2, a); if(a == 1){ return '1'+res; } return res; } } //两个长度不相等的字符串相加 string addStrings2(string Max, string Min, int MaxLength, int MinLength){ string res = ""; string LString = ""; string RString = ""; int t = MaxLength-MinLength; for(int i=0; i<MaxLength; i++){//将长字符串分为左右两部分 if(i<t) LString += Max[i]; else RString += Max[i]; } int a = 0; res = addStr(Min, RString, a) + res;//将右半部分和短字符串相加赋值给res if(a == 1){//右半部分和短字符串相加有进位 string tempA = "1"; for(int j=0; j<LString.size()-1; j++) tempA = '0' + tempA; a = 0; LString = addStr(LString, tempA, a);//左半部分和进位相加 if(a == 1)//左半部分和进位相加仍然有进位 LString = '1' + LString; } res = LString + res; return res; } //字符串长度相同的相加,a代表是否有进位 string addStr(string num1, string num2, int &a){ string res = ""; for(int i=num1.size()-1; i>=0; i--){ int temp = charToInt(num1[i]) + charToInt(num2[i]) + a; if(temp < 10){ a =0; res = intToChar(temp) + res; } else{ a = 1; res = intToChar(temp%10) + res; } } return res; } int charToInt(char c){//字符转化为整数 char charArray[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; for(int i=0; i<=9; i++){ if((charArray[i]^c) == 0){// ^ 优先级小于 ==, 必须在charArray[i]^c外加括号 return i; } } return -1; } char intToChar(int i){//整数转化为字符 char charArray[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; for(int m=0; m<=9; m++){ if((m^i) == 0){// ^ 优先级小于 ==, 必须在charArray[i]^c外加括号 return charArray[m]; } } return '-1'; } }; int main() { Solution S; string num1 = "13423452345345"; string num2 = "93423423423423423"; cout << S.addStrings1(num1, num2) << endl; return 0; }
思路3:
我的代码AC后我看了一下时间,发现一个3ms的代码,代码理解起来不难,我还在他的代码上加上了一些括号便于理解,增加了一些注释
再看一下我的代码,实在是不忍直视。以后仍需努力
下面贴出代码
#include <algorithm> string addStrings(string num1, string num2) {//速度最快3ms string res = ""; int add=0,i=num1.size()-1,j=num2.size()-1; while(i>=0 || j>=0 || add>0) { int cur=add; cur+=(i>=0?num1[i--]-'0':0); cur+=(j>=0?num2[j--]-'0':0); add=cur/10;//用来判断是否有进位 cur%=10; res+=('0'+cur); } reverse(res.begin(), res.end());//翻转字符串 return res; }
相关文章推荐
- 415. Add Strings (计算由两个字符串表示的数字相加之和)
- Android计算两个时间戳的差值,以字符串的形式表示
- 高精度计算:最大公约数【两个数字字符串】
- 415. Add Strings--两个用字符串表示的数字相加
- 415. Add Strings 计算两个数字字符串的和
- Leetcode712. 计算两个字符串删除任意字符后使二者相等的最小删除字符和
- git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比如: base'<--base<--A<--A' ^ | --- B<--B' 小米工程师常常需要寻找两个分支最近的分割点,即base.假设git 树是多叉树,请实现一个算法,计算git树上任意两点的最近分割点。 (假设git树节点数为n,用邻接矩阵的形式表示git树:字符串数组matrix包含n个字符串,每个字符串由字符'0
- Multiply Strings 两个字符串代表数字相乘@LeetCode
- 每天一道LeetCode-----将用数组表示的整数加一,两个用字符串表示的(二进制)数相加
- LeetCode—**Edit Distance 计算两个字符串之间的距离
- 大数乘法。给定两个数字表示为字符串,返回乘数的数字作为一个字符串。
- leetcode_415(两个数字字符串相加,模拟大数相加)
- 每天一道LeetCode-----比较两个字符串,每个字符串被若干'.'分成多个数字,一个个比较
- LeetCode Valid Number(判断字符串是否是合法的数字表示 )
- LeetCode425——Add Strings(两个字符串中的数字相加(十进制或二进制),输出字符串形式的结果)
- LeetCode43——Multiply Strings(两个字符串表示的整数相乘)???
- C语言学习序列之面试题目-计算两个字符串中出现的相同英文字符
- 读入两个小于100的正整数A和B,计算A+B.A和B的每一位数字由对应的英文单词给出.
- 计算两个数字的最小公倍数
- 手把手地写了一个函数,计算出两个字符串日期之间的所有字符串型日期 集合