首页 > 代码库 > 字符串中字符的个数和字符序列

字符串中字符的个数和字符序列

题目

输出上次字符串中字符的个数和字符

最终的序列如下:

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
val1:
512
val2:
512

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类型对象