LintCode解题记录17.8.9 字符串处理5
来源:互联网 发布:智慧城市业务数据库 编辑:程序博客网 时间:2024/06/05 14:43
LintCode Binary Representation
给定一个数(包含小数),返回其二进制形式。如果小数点后的二
进制位大于32位,则返回ERROR。
思路
整数部分转化为二进制是模2取余,小数部分是乘2取整。
代码
string binaryRepresentation(string n) { // wirte your code here int l = n.size(); int split = n.find('.'); int former = atoi(n.substr(0, split).c_str()); double latter = atof(n.substr(split).c_str()); //get the former interger and latter fractional part. string res = ""; if (former == 0) res += '0'; while (former) { res += former%2 + '0'; former /= 2; } reverse(res.begin(), res.end()); int cnt = 0; if (latter) res += '.'; while (latter && cnt < 32) { latter *= 2; res += latter >= 1? '1' : '0'; if (latter >= 1) latter--; cnt++; } return cnt == 32 ? "ERROR" : res; }
总结
1.C/C++分割字符串
在本题中体现在将给定字符串以小数点分割,分成整数部分和小数部分。
四种方法,第一种用C库的strtok函数,函数原型为 char *strtok(char *str, const char *delim);str是要分割的字符串,delim是分割的字符串,strtok函数在遍历str的过程中如果遍历到delim则会将其修改为’/0’。
简单应用:
char str[] = "Hello,World,Ni,Hao."; char *delim = ","; //在第一次调用时,strtok()必需给予参数str字符串,往后的调用则将参数str设置成NULL。每次调用成功则返回下一个分割后的字符串指针。 char *p = strtok(str, delim); while (p != NULL) { printf("%s\n", p); p = strtok(NULL, delim); }
第二种方法是C++ STL库的find函数和substr函数。
贴官网的函数解释:
http://www.cplusplus.com/reference/string/string/find/
http://www.cplusplus.com/reference/string/string/substr/
第三种是C++IO类的stringstream
利用getline函数读取,istream& getline(istream &in, string str, char delim)
第四种是Boost库提供了split函数,我也很少用到Boost库,这里就简单提一下吧。
2.取整
在本题的体现是处理小数部分时,虽然做题的时候没有用。
可以看一下这个http://www.cnblogs.com/zjutlitao/p/3558218.html
3.字符串转整数,转双精度
atoi函数和atof函数。开头的a是ASCII码的意思。需要掌握这两种函数的具体实现,因为面试可能会问到。itoa不推荐使用。
http://blog.csdn.net/lanzhihui_10086/article/details/39989841
LintCode Regular Expression Matching
给定两个字符串,问你他们是不是匹配的正则表达式(假设正则表达式只支持.和*这两种符号)
思路1
两种思路递归和动态规划。
首先来说说递归,基本思路就是看字符串s从i位开始和字符串p从j位开始的子字符串是否匹配,递归遍历到串的末尾,最后回溯结果。假设当前位于字符串s的第i位,字符串p的第j位,那么可以分为两种情况考虑:
(1) p[j+1] != ‘*’;
这一种情况比较简单,只需要判断s[i] == p[j]即可(如果p[j] == ‘.’也代表相等)。如果不相等,则返回False,否则,递归遍历i+1位和j+1位。
(2) p[j+1] == ‘*’;
在这种条件下,匹配的情况有哪几种呢?由于*的意思是该符号前面的字符可以取0次,1次..很多次,也就是说匹配的情况就有前面的字符取了0次,取了1次,取了2次..,在这里面的一种情况实现匹配。如果取了0次,那么下一次递推就是从第i位和第j+2位开始(跳过了p上的’*’和前一字符),如果取了1次,那么下一次递推就是从第i+1位和第j+2位开始,以此类推,直到s上的第i+k位不等于p[j]位(也就是不等于’*’的前一字符)。
举个例子,假设s=”aaaab”,p=”a*b”,i=1,p=1。
因为p[1] == ‘*’,按照上面的思考就是分情况考虑。取了0次,意思就是如果s[1:]和p[2:]匹配的话,那么s[1:]一定和p[0:]匹配,反之亦然。取了1次,意思就是如果s[2:]和p[2:]匹配的话,那么s[1:]一定和p[0:]匹配。
代码
bool isMatch(const char *s, const char *p) { string s1(s), p1(p); return helper(s1, p1, 0, 0); } bool helper(string s, string p, int i, int j) { if (j == p.size()) return i == s.size(); if (j == p.size()-1 || p[j+1] != '*') { if (i == s.size() || (s[i] != p[j] && p[j] != '.')) return false; else return helper(s, p, i+1, j+1); } // p[j] == '*' while (i < s.size() && (s[i] == p[j] || p[j] == '.')) { if (helper(s, p, i, j+2)) return true; i++; } return helper(s, p, i, j+2); }
思路2
动态规划,不过此题的动态规划属于情况比较多比较复杂的情况了,需要仔细分析一下。
我们当然还是维护一个变量dp[i][j],表示字符串s的前i位和字符串p的前j位是否匹配。我们已知了之前所有的子状态,如何得到新的状态呢?
1) p[j-1] != ‘*’
在条件下我们有递推式
dp[i][j] = dp[i-1][j-1] if p[j-1] != ‘*’ && (s[i-1] == p[j-1] || p[j-1] == ‘.’)
2)p[j-1] == ‘*’
在这种条件下又可以分为重复0次,重复1次,重复2次,等等..
重复0次:dp[i][j] = dp[i][j-2]
重复1次: dp[i][j] = dp[i-1][j] && (s[i-1] == p[j-2] || p[j-2] == ‘.’)
重复2次:dp[i][j] = dp[i-2][j] && ((s[i-2] == s[i-1] && s[i-1] == p[j-2]) || p[j-2] == ‘.’)
其实重复大于一次的情况都可以归结到重复1次的里面,因为你的i是顺序遍历的,会先判断dp[i-2][j]是否能匹配,如果能,才会接着考虑dp[i-1][j]能否匹配。
代码
bool isMatch(const char *s, const char *p) { // write your code here string s1(s), p1(p); int m = s1.size(), n = p1.size(); vector<vector<bool> > dp(m+1, vector<bool>(n+1, false)); dp[0][0] = true; for (int i = 0; i <= m; i++) { for (int j = 1; j <= n; j++) { if (j > 1 && p1[j-1] == '*') { dp[i][j] = dp[i][j-2] || (i > 0 && dp[i-1][j] && (s1[i-1] == p1[j-2] || p1[j-2] == '.')); } else dp[i][j] = i > 0 && dp[i-1][j-1] && (s1[i-1] == p1[j-1] || p1[j-1] == '.'); } } return dp[m][n]; }
感受
这道题真是绝了,自己xjb想两个多小时没做出来,看别人讲两个多小时也没看懂,自己再抄出来理解一下又花了两个多小时也迷迷糊糊。另外这道题的描述真是操蛋,没有说只有p包含了.和*,s是只有字母的字符串,不过测试用例全是这个。这下就导致自己做的时候既考虑了s又考虑了p绕着绕着把自己绕晕了。
- LintCode解题记录17.8.9 字符串处理5
- LintCode 解题记录17.8.4 字符串处理2
- LintCode 解题记录 17.8.7 字符串处理3
- LintCode 解题记录17.8.8 字符串处理4
- LintCode 解题记录17.8.19 字符串处理6
- LintCode 解题记录 字符串处理1.0 17.7.29
- LintCode解题记录17.9.9
- LintCode 解题记录 17.8.30 两个指针
- LintCode 解题记录 Array 17.6.5
- LintCode 解题记录 17.10.5 递归
- LintCode 解题记录17.4.27
- LintCode解题记录17.4.28
- LintCode解题记录 17.5.3
- LintCode 解题记录 2017.6.3
- LintCode 解题记录 7.11 ~ 7.16
- LintCode 解题记录 Matrix专题
- LintCode解题记录-Catalan Number
- LintCode 解题记录17.10.21
- Post Office POJ
- 欢迎使用CSDN-markdown编辑器
- ES5基础
- 有关itoa将整型转换成字符型的使用
- BZOJ3670 [Noi2014]动物园 解题报告【字符串】【KMP】
- LintCode解题记录17.8.9 字符串处理5
- Delphi获得与设置系统时间格式《转》
- Android视频直播的实现(推流完整实现001)
- 线程与进程1
- 关于带有缓存的Spring的pom.xml文件
- 单例模式-恶汉-懒汉
- laravel笔记-请求与响应
- 关于Android活动的四种启动模式
- 美团(猫眼)电影爬虫/美团(猫眼)电影价格图片混淆破解