题目
输出上次字符串中字符的个数和字符
最终的序列如下:
1, 11, 21, 1211, 111221, ...
n=1时,输出字符串"1"
n=2时,输出上次字符串中字符的个数和字符,因为上次字符串有1个1,所以输出11
n=3时,由于上次字符是11,有2个1,所以输出21
n=4时,由于上次字符串是21,有1个2和1个1,所以输出1211
依次类推,写个countAndSay(n)函数返回字符串。
参考代码
class Solution {
public:
string getNextVal(const string &s)
{
stringstream rev;
char pre = s[0];
int preCount = 1;
for (int i = 1; i <= s.size(); ++i)
{
if (s[i] == pre)
++preCount;
else
{
rev << preCount << pre;
preCount = 1;
pre = s[i];
}
}
return rev.str();
}string countAndSay(int n) {
if (n <= 0)
return string();
string say = "1";
for (int i = 1; i < n; ++i)
{
say = getNextVal(say);
}
return say;
}
};
细嚼
1. 利用流,将整数、字符转化成字符串——stringstream提供转化或格式化
stringstream的一个常用的用法是:在多种数据类型之间实现自动格式化。
案例
#include <iostream>
#include <sstream>
#include <ctime>
#include <string>
#include <vector>
using namespace std;int main()
{
ostringstream ostrm;
int val1 = 512, val2 = 1024;
ostrm << "val1: " << val1 << "\n"
<< "val2: " << val2 << "\n";string str1, str2;
int vals1, vals2;
istringstream istrm(ostrm.str());
istrm >> str1 >> vals1 >> str2 >> vals2;
cout << str1 << endl;
cout << vals1 << endl;
cout << str2 << endl;
cout << vals1 << endl;
}
输出
?
1 2 3 4 |
|
2. 函数定义为
string getNextVal(const string &s)
- 因为不改变s的值,故加上const修饰避免对s的修改
- 因为string不是c++基本类型,故直接操作(利用引用&),可以避免较费力的复制
- 返回类型不可以为const,因为返回值要赋值给非常量
- 返回值不可以加引用,因为在函数体内的流为临时变量,函数结束,流也就夭折了
3. 空间复杂度为O(1),避免使用数组存放中间结果,例如
string countAndSay(int n)
{
vector<string> vec;
if (n < 0)
return "";
vec.push_back("1");
for (int i = 1; i < n; ++i)
{
string tmp = getNext(vec[i-1]);
vec.push_back(tmp);
}
return vec[n-1];
}
4.
利用字符串最后一个字符字节为‘\0‘,下面函数体写在一起,使整体更连贯
for (int i = 1; i <= s.size(); ++i)
{
if (s[i] == pre)
++preCount;
else
{
rev << preCount << pre;
preCount = 1;
pre = s[i];
}
}
而不是写成如下
for (int i = 1; i < s.size(); ++i)
{
if (s[i] == pre)
++preCount;
else
{
rev << preCount << pre;
preCount = 1;
pre = s[i];
}
}
rev << preCount << pre; //单独处理最后一个字符
5. 流转化为字符串:str()函数——返回流中存储的string类型对象