/*
codewars,525f4206b73515bffb000b21,Adding Big Numbers
写一个实现正整数字符串实现的大整数相加的函数
*/
#include <iostream>
#include <string>
#include <algorithm>std::string add(const std::string& a, const std::string& b) {if(a.empty()){return b;}else if(b.empty()){return a;}std::string num1 = std::string(std::max(a.size(),b.size())-a.size()+1,'0')+a;std::string num2 = std::string(num1.size()-b.size(),'0')+b;/*std::string(size_t n,char c);std::string的构造函数,用于创建一个包含n个字符c的字符串std::string(5,'A');将创建"AAAAA"上面两行代码将字符串a与字符串b的长度统一, 给较短的那个字符串前面补'0',使其长度跟较长的那个一样同时在长度统一后的两个字符串前面均再加上一个'0',以供可能的进位需要,这样可以统一操作*/for(int index = num1.size()-1,carry = 0;index>=0;--index){carry+=num1[index]+num2[index]-96;num1[index] = carry%10+'0';carry/=10;}int i = num1.find_first_not_of('0');/*find_first_not_of()用于查找第一个不在指定字符集合中的字符的位置size_t find_first_not_of(const std::string& str, size_t pos = 0) const;str: 指定的字符集合pos: 开始查找的位置,默认为0返回值如果找到这样的字符,返回其位置如果没有找到,返回std::string::npos*/return i>=0?num1.substr(i):"0";/*substr()方法获取从某个下标开始的子字符串,有两个参数第一个参数是要获取的子字符串起始位置的下标第二个参数是要获取的字符串的长度,如果省略,则默认获取从起始位置到字符串末尾的所有字符*/
}
int main(){std::cout<<add("99","2");
}/*
Best Practice*/
// using namespace std;// string add(string a, string b)
// {
// a = string(max(a.size(), b.size()) + 1 - a.size(), '0') + a;
// b = string(a.size() - b.size(), '0') + b;
// for (int i = a.size()-1, carry = 0; i >= 0; i--)
// {
// int sum = a[i] + b[i] - 96 + carry;
// carry = sum / 10;
// a[i] = sum % 10 + '0';
// }
// int i = a.find_first_not_of('0');
// return 0 <= i ? a.substr(i) : a.substr(0, 1);
// }/*
提问:
for(int i = 0;i<std::min(a.size(),b.size());++i)
这里面,i<std::min()的部分会不会在每次循环进行判断的时候都要执行std::min()函数而导致效率降低,
还是在第一次判断得出结果之后,之后的循环直接使用该结果而不用重复调用std::min()函数
回答:
每次循环判断的确会执行一次 std::min(a.size(), b.size()),不过:
- 编译器优化:现代编译器通常会内联这个函数(因为 std::min 很简单)并且检测到 a.size() 和 b.size() 在循环中未发生变化,从而将计算结果缓存起来,达到优化效果。- 手动缓存:如果担心编译器优化不理想,也可以在循环前缓存结果,例如:#include <algorithm> // 包含 std::min 的头文件
#include <string>std::string add(const std::string& a, const std::string& b) {if(a.empty()){return b;} else if(b.empty()){return a;}const std::size_t minSize = std::min(a.size(), b.size());for(std::size_t i = 0; i < minSize; ++i){// ...此处为处理逻辑...}// ...后续代码...
}使用这种方式可以确保只计算一次。综合来说,在性能影响方面影响非常小,但提前缓存会使代码更明确。
*/