您的位置:首页 > 编程语言 > C语言/C++

【C/C++】再探string

2016-04-11 16:37 781 查看
最近做了很多笔试,各种被虐,别的不说,还是被虐出了一条经验:STL 真的很重要!!!

先从最简单的 String 练起~

String 表示可变长的字符序列,常用的操作包括:

in >> s                    从in输入流读取字符串到s,字符串以空白(Tab、空格等)分隔
out << s                   把s输出到out输出流
getline(in, s)        从in中读取一行赋给s,以换行符为界,但换行符不存入s
s.empty()                  s为空返回true,否则返回false
s.size()                   返回s中字符的个数
s
返回s中第n个字符的引用,位置从0计起
s1+s2                      返回s1和s2连接后的结果,可以与字面字符串相加,但注意加号两边必须有一个是str
isspace()                  判断是否空格
isalpha()                  判断是否字母
isdigit()                  判断是否数字
isalnum()                  判断是否字母或数字


用leetcode练手如下:
8. String to Integer (atoi)

这道题比较全面考到 String 的相关操作,还要很细心,做了一个小时。。。

class Solution {
public:
int myAtoi(string str) {
long long num = 0;                                    //使用long long 保证num不会溢出
long long MAX = (long long)INT_MAX + 1;               //一定注意 INT_MAX 直接加一后就会溢出
int len = str.size();
if(len == 0)
return 0;

int i = 0;
while(isspace(str[i]))                                //越过前面的空格
++i;
if(str[i] == '-')
{
i++;
while(isdigit(str[i]))                           //判断是否数字
{
num = num * 10 + (int) (str[i] - '0');
if(num > MAX)                                //判断是否溢出
return INT_MIN;
++i;
if(i == len)                                 //判断是否字符串尾
break;
}
num = -num;
return (int) num;                                //由于num初始化0,保证'+ -'符后若无数字,能够成功返回0

}
else if(str[i] == '+')
{
i++;
while(isdigit(str[i]))
{
num = num * 10 + (int) (str[i] - '0');
if(num > INT_MAX)
return INT_MAX;
++i;
if(i == len)
break;
}
return (int) num;
}
else if(isdigit(str[i]))
{
while(isdigit(str[i]))
{
num = num * 10 + (int) (str[i] - '0');
if(num > INT_MAX)
return INT_MAX;
++i;
if(i == len)
break;
}
return (int) num;
}
else
return 0;
}
};


leetcode #151. Reverse Words in a String

这道题一开始题意不是很明确,提交几次才搞清楚。

What constitutes a word?

A sequence of non-space characters constitutes a word.


也即标点,字母,数字可以看做是word的组成部分,其他的只需跳过空格即可。

class Solution {
public:
void reverseWords(string &s) {
int i = 0;
int len = s.size();
string tmp;
vector<string> str;
while(1)
{
if(i == len)
break;
if(isspace(s[i]))
{
++i;
continue;
}
while(isalnum(s[i]) || ispunct(s[i])) //注意!!!此处不能使用 !isspace() ,指针会越界。
tmp += s[i++];
str.push_back(tmp);
tmp.clear();
}

s.clear();
if(!str.empty())
{
for(i = str.size() - 1; i >= 0; --i)
s = s + str[i] + " ";

string::iterator it = s.end() - 1;
s.erase(it);
}
return;
}
};


leetcode #205. Isomorphic Strings

这道题用到了Map容器:Map容器简单介绍如:http://mropengate.blogspot.com/2015/12/cc-map-stl.html(Mr. Opengate)

然后通过Map将字符串用数字来表示,比如:

Given "paper", return "01023".

Given "foo", return "011".

Given "isomorphic", return "0123245607".


于是有了下面的解:

class Solution {
public:
vector<int> getVector(string s)
{
vector<int> vec;                        //保存对应的数字串
if(s.empty())
return vec;
map<char, int> str;                     //保存char与int的对应表
map<char, int>::iterator iter;
int i = 0, index = 0;

for(; i < s.size(); ++i)
{
iter = str.find(s[i]);
if(iter == str.end())
{
str.insert(pair<char, int>(s[i], index));
vec.push_back(index++);
}
else
{
vec.push_back(str[s[i]]);
}
}
return vec;
}

bool isIsomorphic(string s, string t) {
vector<int> vec_s = getVector(s);
vector<int> vec_t = getVector(t);
for(int i = 0; i < s.size(); ++i)       //题目说可以假设s与t有着相同的长度
{
if(vec_s[i] != vec_t[i])
return false;
}
return true;
}
};


做完这道,再看一道类似的题目

leetcode #290. Word Pattern

class Solution {
public:
vector<int> getVector1(string s)
{
map<string, int> str2int;
map<string, int>::iterator iter;
vector<int> vec;
if(s.empty())
return vec;

int i = 0;
int index = 0;

for(; i < s.size(); ++i)
{
if(isspace(s[i]))
continue;

string tmp;
while(isalpha(s[i]))
tmp += s[i++];

iter = str2int.find(tmp);
if(iter == str2int.end())
{
str2int.insert(pair<string, int>(tmp, index));
vec.push_back(index++);
}
else
vec.push_back(str2int[tmp]);
}
return vec;
}

vector<int> getVector2(string s)
{
vector<int> vec;
if(s.empty())
return vec;
map<char, int> str;
map<char, int>::iterator iter;
int i = 0, index = 0;

for(; i < s.size(); ++i)
{
iter = str.find(s[i]);
if(iter == str.end())
{
str.insert(pair<char, int>(s[i], index));
vec.push_back(index++);
}
else
{
vec.push_back(str[s[i]]);
}
}
return vec;
}

bool wordPattern(string pattern, string str) {
vector<int> vec1 = getVector1(str);
vector<int> vec2 = getVector2(pattern);

if(vec1.size() != vec2.size())
return false;

for(int i = 0; i < vec1.size(); ++i)
{
if(vec1[i] != vec2[i])
return false;
}
return true;
}
};


我们发现 string[] 可以当做 char 操作,包括将 string[] 赋值给 char,或者和 char 比较,甚至是 string[]++ 都可以。于是我想到这样的话不是可以只把 str改变成 pattern 不就行了(前提是pattern严格按照 a, b, c的顺序增加新增的字母,比如"aabbccdd" 而不能是"bbaaccdd"这样b出现在a的前面)

代码如下:

class Solution {
public:
vector<char> getVector(string s)
{
map<string, char> str2char;
map<string, char>::iterator iter;
vector<char> vec;
if(s.empty())
return vec;

int i = 0;
char index = 'a';

for(; i < s.size(); ++i)
{
if(isspace(s[i]))
continue;

string tmp;
while(isalpha(s[i]))
tmp += s[i++];

iter = str2char.find(tmp);
if(iter == str2char.end())
{
str2char.insert(pair<string, char>(tmp, index));
vec.push_back(index++);
}
else
vec.push_back(str2char[tmp]);
}
return vec;
}

bool wordPattern(string pattern, string str) {
vector<char> vec = getVector(str);

if(vec.size() != pattern.size())
return false;

for(int i = 0; i < vec.size(); ++i)
{
if(vec[i] != pattern[i])
return false;
}
return true;
}
};


后来证明有这样的pattern----->“bbaa”,o(╯□╰)o没办法了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: