[LeetCode]Count And Say

题目

思路

这个题目是一个easy级别,算法本身没有难点,但是C++的语法有几点需要注意。下面分别说一下:

LeetCode中给的C++函数原型是这样的

string countAndSay(int n);

  也就是说给一个n得到一个string类型的数字串,但是n和这个数字串似乎没有什么关系,这个数字串是从上一个数字串推到过来的,所以基本上确定要递归。

看这个函数原型的返回类型是string的,乍一看到这个string我有点蒙,把C++和Java的东西弄混了。先说java,因为返回的string是一个类对象,它返回一个在堆上开辟的对象的引用,所以countAndSay函数外面的地方依然能很容易的看到这个对象,只要把引用赋值给一个string类型的引用。同时在countAndSay内部开辟的string对象空间也不用手动的释放,因为有GC。但是C++情况不一样,它没有GC,要考虑堆内存的手动释放,所以有点纠结。后来查了一下,说一下C++怎么实现的。

对于上面的这个函数,它返回的不是原来堆或栈内存中对象的引用,而是返回了这个对象本身。函数外面调用这个方法的时候,会调用string类的拷贝构造函数进行其他string对象的初始化,然后countAndSay里面的string类对象就被回收了。具体是谁回收的,从函数原型看到这里并没有指针或者引用,所以对象并没有必要在堆中开辟内存,在栈中足够了。既然是在栈中开辟的string对象的存储空间,那么这个string对象就随着函数栈的变化自动的回收了。具体的看下面这篇博文:

C++创建对象的方式

在返回值赋值给外部的string对象的时候,调用了string类的拷贝构造函数或者赋值符函数

C++构造/析构/赋值运算

同时,CountAndSay中用到一些string类的方法。

标准C++中string类的使用

标准C++中提供的string类得功能也是非常强大的,一般都能满足我们开发项目时使用。

要想使用标准C++中string类,必须要包含

#include <string>// 注意是<string>,不是<string.h>,带.h的是C语言中的头文件

using  std::string;

using  std::wstring;

或

using namespace std;

  

下面你就可以使用string/wstring了,它们两分别对应着char和wchar_t。

string和wstring的用法是一样的,以下只用string作介绍:


string类的构造函数:

string(const char *s);    //用c字符串s初始化
string(int n,char c);     //用n个字符c初始化
此外,string类还支持默认构造函数和复制构造函数,如string s1;string s2="hello";都是正确的写法。当构造的string太长而无法表达时会抛出length_error异常 ;


string类的字符操作:

const char &operator[](int n)const;
const char &at(int n)const;
char &operator[](int n);
char &at(int n);
operator[]和at()均返回当前字符串中第n个字符,但at函数提供范围检查,当越界时会抛出out_of_range异常,下标运算符[]不提供检查访问。
int size()const;        //返回当前字符串的大小

  

Vector中的两个函数

c++中的vector头文件里面就有这个push_back函数,在vector类中作用为在vector尾部加入一个数据。
string中也有这个函数,作用是字符串之后插入一个字符。类似的方法看C++中vector的方法。
 
提示:
字符char和int的转换,可以方便的通过+'0'或者-'0'实现,因为字符的存储都是其对应的ASCII code。
 
countAndSay代码实现:
string countAndSay(int n)
{
	if(n == 1)
		return "1";
	string analyzeStr = countAndSay(n - 1);
	int count = 1;
	string resultStr;

	int preInt = analyzeStr[0] - '0';
	for(int i = 1; i < analyzeStr.size(); i++)
	{
		int curInt = analyzeStr[i] - '0';
		if(preInt == curInt)
		{
			count++;
		}
		else
		{
			resultStr.push_back(count + '0');
			resultStr.push_back(preInt + '0');

			preInt = curInt;
			count = 1;
		}
	}//for

	resultStr.push_back(count + '0');
	resultStr.push_back(preInt + '0');

	return resultStr;
}

  

代码下载地址

 https://github.com/stemon/LeetCode/blob/master/countAndSay.cpp

原文地址:https://www.cnblogs.com/stemon/p/4465482.html