0x01 先安利一下:kata,很好的英文练习编程网站,可以提高英语水平,而且他的界面还有过程和别人写的极简洁的代码让我有把自己代码写到最简的强迫症。比较喜欢它的机制,比leetcode有趣合理一些
0x02 题目
话不多说,先上题目吧:
Given a positive number n > 1 find the prime factor decomposition of n. The result will be a string with the following form :
“(p1n1)(p2n2)…(pknk)"
with the p(i) in increasing order and n(i) empty if n(i) is 1.
Example: n = 86240 should return "(25)(5)(7**2)(11)”
其实就是分解质因数,要求格式化输出罢了~
虽然没写过,但是感觉C++学了这么久应该很简单,还不是枚举质数,然后输出
0x03
先放网站的最佳解答:
std::string factor(int n) {
std::ostringstream res;
for (int i = 2; n > 1; i++) {
int k = 0;
while (n % i == 0) {
n /= i;
k++;
}
if (k == 1)
res << '(' << i << ')';
else if (k > 1)
res << '(' << i << "**" << k << ')';
}
return res.str();
}
(╯’ - ')╯︵ ┻━┻ (掀桌子) ┬─┬ ノ( ’ - 'ノ)(摆好摆好)(╯°Д°)╯︵ ┻━┻(再TA喵掀一次)
0x04 My turn
然后是我的心路历程:
思路确定了就写代码。。。因为刚刚学了点sstream的用法,就先入为主地想用,就有了我的答案:
string factors(int lst) {
stringstream ss; //使用sstream流暂存质因数
string ans; //用来保存答案
for (int i = 2; lst != 1; ++i) {
if (lst % i == 0) {
ss << (to_string(i) + " ");
lst /= i;
i -= 1;
}
}
int i = 1, j = 0;
for (string str; ss >> str; ) { //从sstream流里取string,因为流的特性会自己读取到" "停下来
if(ans.size() == 0){
ans.push_back('(');
ans += str;
j = str.size();
continue;
}
else if (str.size() == j && str == ans.substr(ans.size() - str.size(), str.size())) {
++i;
continue;
}
if (i > 1) {
ans += "**";
ans += to_string(i);
i = 1;
}
ans.push_back(')');
ans.push_back('(');
ans += str;
j = str.size();
}
if (i > 1)
ans += to_string(i);
ans.push_back(')');
return ans;
}
是不是看不起我2333,写了这么长,快40行。。(还单步调试3次,外加kata上面attempt错误2次。。。
这个是我最后提交通过了的,思路还算清晰能够看清,之前的if-else才叫我绝望,留下没技术的泪水(;´д`)ゞ
下面是我调试过程中写的for循环:
for (string str; ss >> str; ) {
if(ans.size() == 0 || ans[ans.size() - 1] == ')'){
ans.push_back('(');
}
else if (str != ans.substr(ans.size() - str.size(), str.size())) {
if (ans[ans.size() - 1] == '*' && i > 1) {
ans += to_string(i);
i = 1;
}
else if (i == 1) {
ans.erase(ans.size() - 2, 2);
}
ans.push_back(')');
ans.push_back('(');
}
else if(i == 1){
ans += "**";
++i;
continue;
}
else {
++i;
}
ans += str;
}
我之前还有更加离谱的操作,懒得CTRL+z退回去复制过来了 /_ \
自我总结起来就是:
1、有如:必须不等于或优先判别的条件必须放在第一判断,并且直接接上continue,break,return等;
2、要抓住主要矛盾,尽量先找到一个大if-else,这个if尽量使用"肯定"的条件,不要整 “!” 然后后面一大堆的操作(我就犯了这个问题,我上面第二个if用的就是否定。。。后面发现要是质因数是:“331567*50923=718167069”时会因为3和1567字符宽度不同导致取子串比较时出错,否定条件使我加个变量j来表示字符宽度也不好加)。然后再分别于if/else内细分,那样思路清晰不容易错,也容易在考虑不完全的情况加入调试代码;
3、珍惜每一次循环,尽量想一举多得的操作,不要像我一样,想着先取出来存起来,再用方法打印。
0x05 总结
感觉挺有收获的,而且算是自我锻炼了一下sstream的用法,还收获了一点if-else的简化经验,keep going,go all the way ( o=^•ェ•)o ┏━┓