字符串转换成整数,字符串匹配问题
本文转自csdn大神v_JULY_v的博客
地址:
http://blog.csdn.net/v_july_v/article/details/9024123
阅读心得:自己原先想得太天真了。。。
第三十~三十一章:字符串转换成整数,字符串匹配问题
前言
之前本一直想写写神经网络算法和EM算法,但写这两个算法实在需要大段大段的时间,而平时上班,周末则跑去北大教室自习看书(顺便以时间为序,说下过去半年看过的自觉还不错的几本书:《数理统计学简史》《微积分概念发展史》《微积分的历程:从牛顿到勒贝格》《数学恩仇录》《数学与知识的探求》《古今数学思想》《素数之恋》),故一直未曾有时间写。
然最近在负责一款在线编程挑战平台:http://hero.pongo.cn/(简称hero,通俗理解是中国的topcoder,当然,一直在不断完善中,与一般OJ不同点在于,OJ侧重为参与ACM竞赛者提供刷题练习的场所,而hero则着重为企业招聘面试服务),在上面出了几道编程面试题,有些题目看似简单,但一coding,很多问题便立马都在hero上给暴露出来了,故就从hero上的编程挑战题切入,继续更新本程序员编程艺术系列吧。
况且,前几天与一朋友聊天,他说他认识的今年360招进来的三四十人应届生包括他自己找工作时基本都看过我的博客,则更增加了更新此编程艺术系列的动力。
OK,本文讲两个问题:
- 第三十章、字符串转换成整数;
- 第三十一章、字符串匹配问题
第三十章、字符串转换成整数
先看题目:
输入一个表示整数的字符串,把该字符串转换成整数并输出,例如输入字符串"345",则输出整数345。
请完成函数StrToInt,实现字符串转换成整数的功能,不得用库函数atoi。
我们来一步一步分析,直至写出第一份准确的代码:
1、本题考查的实际上就是字符串转换成整数的问题,或者说是要你自行实现atoi函数。那如何实现把表示整数的字符串正确地转换成整数呢?以"345"作为例子:
- 当我们扫描到字符串的第一个字符'3'时,由于我们知道这是第一位,所以得到数字3。
- 当扫描到第二个数字'4'时,而之前我们知道前面有一个3,所以便在后面加上一个数字4,那前面的3相当于30,因此得到数字:3*10+4=34。
- 继续扫描到字符'5','5'的前面已经有了34,由于前面的34相当于340,加上后面扫描到的5,最终得到的数是:34*10+5=345。
因此,此题的思路便是:每扫描到一个字符,我们便把在之前得到的数字乘以10,然后再加上当前字符表示的数字。
2、思路有了,有一些细节需要注意,如zhedahht所说:
- “由于整数可能不仅仅之含有数字,还有可能以'+'或者'-'开头,表示整数的正负。因此我们需要把这个字符串的第一个字符做特殊处理。如果第一个字符是'+'号,则不需要做任何操作;如果第一个字符是'-'号,则表明这个整数是个负数,在最后的时候我们要把得到的数值变成负数。
- 接着我们试着处理非法输入。由于输入的是指针,在使用指针之前,我们要做的第一件是判断这个指针是不是为空。如果试着去访问空指针,将不可避免地导致程序崩溃。
- 另外,输入的字符串中可能含有不是数字的字符。每当碰到这些非法的字符,我们就没有必要再继续转换。
- 最后一个需要考虑的问题是溢出问题。由于输入的数字是以字符串的形式输入,因此有可能输入一个很大的数字转换之后会超过能够表示的最大的整数而溢出。”
- //copyright@zhedahht 2007
- enum Status {kValid = 0, kInvalid};
- int g_nStatus = kValid;
- // Convert a string into an integer
- int StrToInt(const char* str)
- {
- g_nStatus = kInvalid;
- long long num = 0;
- if(str != NULL)
- {
- const char* digit = str;
- // the first char in the string maybe '+' or '-'
- bool minus = false;
- if(*digit == '+')
- digit ++;
- else if(*digit == '-')
- {
- digit ++;
- minus = true;
- }
- // the remaining chars in the string
- while(*digit != '\0')
- {
- if(*digit >= '0' && *digit <= '9')
- {
- num = num * 10 + (*digit - '0');
- // overflow
- if(num > std::numeric_limits<int>::max())
- {
- num = 0;
- break;
- }
- digit ++;
- }
- // if the char is not a digit, invalid input
- else
- {
- num = 0;
- break;
- }
- }
- if(*digit == '\0')
- {
- g_nStatus = kValid;
- if(minus)
- num = 0 - num;
- }
- }
- return static_cast<int>(num);
- }
两个问题:
- 当输入的字符串不是数字,而是字符的时候,比如“1a”,上述程序直接返回了0(而正确的结果应该是得到1):
- // if the char is not a digit, invalid input
- else
- {
- num = 0;
- break;
- }
- 处理溢出时,有问题。
- //copyright@SP_daiyq 2013/5/29
- int StrToInt(const char* str)
- {
- int res = 0; // result
- int i = 0; // index of str
- int signal = '+'; // signal '+' or '-'
- int cur; // current digit
- if (!str)
- return 0;
- // skip backspace
- while (isspace(str[i]))
- i++;
- // skip signal
- if (str[i] == '+' || str[i] == '-')
- {
- signal = str[i];
- i++;
- }
- // get result
- while (str[i] >= '0' && str[i] <= '9')
- {
- cur = str[i] - '0';
- // judge overlap or not
- if ( (signal == '+') && (cur > INT_MAX - res*10) )
- {
- res = INT_MAX;
- break;
- }
- else if ( (signal == '-') && (cur -1 > INT_MAX - res*10) )
- {
- res = INT_MIN;
- break;
- }
- res = res * 10 + cur;
- i++;
- }
- return (signal == '-') ? -res : res;
- }
" 10522545459" 1932610867 2147483647" +10523538441s" 1933603849 2147483647" +10432359437" 1842424845 2147483647
5、上面说给的程序没有“很好的解决溢出问题。由于输入的数字是以字符串的形式输入,因此有可能输入一个很大的数字转换之后会超过能够表示的最大的整数而溢出。”那么,到底代码该如何写呢?
- //copyright@淹死鲨鱼ronkins 2013/5/29
- //挑战题目:http://hero.pongo.cn/Question/Details?ID=47&ExamID=45
- int atoi(const char* str)
- {
- long long res = 0;
- int sign = 1;
- while(isspace(*str))++str;
- if('+' == *str){
- ++str;
- }else if('-' == *str){
- sign = -1;
- ++str;
- }
- for(; isdigit(*str); ++str){
- res *= 10;
- if(sign > 0)
- res += (*str - '0');
- else
- res -= (*str - '0');
- if(res >= INT_MAX)return INT_MAX;
- else if(res <= INT_MIN)return INT_MIN;
- }
- return res;
- }
上面的代码看似能处理数据溢出的问题,其实它只是做了个取巧,即把返回的值res定义成了long long,如下所示:
- long long res = 0;
故严格说来,我们依然未写出准确的规范代码。
- //atol函数
- //Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.
- long __cdecl atol(
- const char *nptr
- )
- {
- int c; /* current char */
- long total; /* current total */
- int sign; /* if ''-'', then negative, otherwise positive */
- /* skip whitespace */
- while ( isspace((int)(unsigned char)*nptr) )
- ++nptr;
- c = (int)(unsigned char)*nptr++;
- sign = c; /* save sign indication */
- if (c == ''-'' || c == ''+'')
- c = (int)(unsigned char)*nptr++; /* skip sign */
- total = 0;
- while (isdigit(c)) {
- total = 10 * total + (c - ''0''); /* accumulate digit */
- c = (int)(unsigned char)*nptr++; /* get next char */
- }
- if (sign == ''-'')
- return -total;
- else
- return total; /* return result, negated if necessary */
- }
- isspace(int x)
- {
- if(x==' '||x=='/t'||x=='/n'||x=='/f'||x=='/b'||x=='/r')
- return 1;
- else
- return 0;
- }
- isdigit(int x)
- {
- if(x<='9'&&x>='0')
- return 1;
- else
- return 0;
- }
- //atoi调用上述的atol
- int __cdecl atoi(
- const char *nptr
- )
- {
- //Overflow is not detected. Because of this, we can just use
- return (int)atol(nptr);
- }
但很遗憾的是,上述atoi标准代码依然返回的是long:
- long total; /* current total */
- if (sign == ''-'')
- return -total;
- else
- return total; /* return result, negated if necessary */
再者,下面这里定义成long的total与10相乘,即total*10很容易溢出:
- long total; /* current total */
- total = 10 * total + (c - ''0''); /* accumulate digit */
- simple_strtol,把一个字符串转换为一个有符号长整数;
- simple_strtoll,把一个字符串转换为一个有符号长长整数;
- simple_strtoul,把一个字符串转换为一个无符号长整数;
- simple_strtoull,把一个字符串转换为一个无符号长长整数
- //linux/lib/vsprintf.c
- //Copyright (C) 1991, 1992 Linus Torvalds
- //simple_strtol - convert a string to a signed long
- long simple_strtol(const char *cp, char **endp, unsigned int base)
- {
- if (*cp == '-')
- return -simple_strtoul(cp + 1, endp, base);
- return simple_strtoul(cp, endp, base);
- }
- EXPORT_SYMBOL(simple_strtol);
然后,上面的strtol调下面的strtoul:
- //simple_strtoul - convert a string to an unsigned long
- unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
- {
- return simple_strtoull(cp, endp, base);
- }
- EXPORT_SYMBOL(simple_strtoul);
接着,上面的strtoul调下面的strtoull:
- //simple_strtoll - convert a string to a signed long long
- long long simple_strtoll(const char *cp, char **endp, unsigned int base)
- {
- if (*cp == '-')
- return -simple_strtoull(cp + 1, endp, base);
- return simple_strtoull(cp, endp, base);
- }
- EXPORT_SYMBOL(simple_strtoll);
最后,strtoull调_parse_integer_fixup_radix和_parse_integer来处理相关逻辑:
- //simple_strtoull - convert a string to an unsigned long long
- unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
- {
- unsigned long long result;
- unsigned int rv;
- cp = _parse_integer_fixup_radix(cp, &base);
- rv = _parse_integer(cp, base, &result);
- /* FIXME */
- cp += (rv & ~KSTRTOX_OVERFLOW);
- if (endp)
- *endp = (char *)cp;
- return result;
- }
- EXPORT_SYMBOL(simple_strtoull);
重头戏来了。接下来,我们来看上面strtoull函数中的parse_integer_fixup_radix和_parse_integer两段代码。如鲨鱼所说
- “真正的处理逻辑主要是在_parse_integer里面,关于溢出的处理,_parse_integer处理的很优美,
- 而_parse_integer_fixup_radix是用来自动根据字符串判断进制的”。
- //lib/kstrtox.c, line 39
- //Convert non-negative integer string representation in explicitly given radix to an integer.
- //Return number of characters consumed maybe or-ed with overflow bit.
- //If overflow occurs, result integer (incorrect) is still returned.
- unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p)
- {
- unsigned long long res;
- unsigned int rv;
- int overflow;
- res = 0;
- rv = 0;
- overflow = 0;
- while (*s) {
- unsigned int val;
- if ('0' <= *s && *s <= '9')
- val = *s - '0';
- else if ('a' <= _tolower(*s) && _tolower(*s) <= 'f')
- val = _tolower(*s) - 'a' + 10;
- else
- break;
- if (val >= base)
- break;
- /*
- * Check for overflow only if we are within range of
- * it in the max base we support (16)
- */
- if (unlikely(res & (~0ull << 60))) {
- if (res > div_u64(ULLONG_MAX - val, base))
- overflow = 1;
- }
- res = res * base + val;
- rv++;
- s++;
- }
- *p = res;
- if (overflow)
- rv |= KSTRTOX_OVERFLOW;
- return rv;
- }
- 上头出现了个unlikely,其实unlikely和likely经常出现在linux相关内核源码中
- if(likely(value)){
- //等价于if(likely(value)) == if(value)
- }
- else{
- }
likely表示value为真的可能性更大,而unlikely表示value为假的可能性更大,这两个宏被定义成:
- //include/linux/compiler.h
- # ifndef likely
- # define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))
- # endif
- # ifndef unlikely
- # define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))
- # endif
- 呈现下div_u64的代码:
- //include/linux/math64.h
- //div_u64
- static inline u64 div_u64(u64 dividend, u32 divisor)
- {
- u32 remainder;
- return div_u64_rem(dividend, divisor, &remainder);
- }
- //div_u64_rem
- static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
- {
- *remainder = dividend % divisor;
- return dividend / divisor;
- }
- //lib/kstrtox.c, line 23
- const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
- {
- if (*base == 0) {
- if (s[0] == '0') {
- if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
- *base = 16;
- else
- *base = 8;
- } else
- *base = 10;
- }
- if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
- s += 2;
- return s;
- }
第三十一章、字符串匹配问题
字符串匹配问题,给定一串字符串,按照指定规则对其进行匹配,并将匹配的结果保存至output数组中,多个匹配项用空格间隔,最后一个不需要空格。
要求:
- 匹配规则中包含通配符?和*,其中?表示匹配任意一个字符,*表示匹配任意多个(>=0)字符。
- 匹配规则要求匹配最大的字符子串,例如a*d,匹配abbdd而非abbd,即最大匹配子串。
- 匹配后的输入串不再进行匹配,从当前匹配后的字符串重新匹配其他字符串。
请实现函数:char* my_find(char input[], char rule[])
举例说明
input:abcadefg
rule:a?c
output:abc
input :newsadfanewfdadsf
rule: new
output: new new
input :breakfastfood
rule: f*d
output:fastfood
注意事项:
- 自行实现函数my_find,勿在my_find函数里夹杂输出,且不准用C、C++库,和Java的String对象;
- 请注意代码的时间,空间复杂度,及可读性,简洁性;
- input=aaa,rule=aa时,返回一个结果aa,即可。
1、本题与上述第三十章的题不同,上题字符串转换成整数更多考察对思维的全面性和对细节的处理,本题则更多的是编程技巧。闲不多说,直接上代码:
- //copyright@cao_peng 2013/4/23
- int str_len(char *a) { //字符串长度
- if (a == 0) {
- return 0;
- }
- char *t = a;
- for (;*t;++t)
- ;
- return (int) (t - a);
- }
- void str_copy(char *a,const char *b,int len) { //拷贝字符串 a = b
- for (;len > 0; --len, ++b,++a) {
- *a = *b;
- }
- *a = 0;
- }
- char *str_join(char *a,const char *b,int lenb) { //连接字符串 第一个字符串被回收
- char *t;
- if (a == 0) {
- t = (char *) malloc(sizeof(char) * (lenb + 1));
- str_copy(t, b, lenb);
- return t;
- }
- else {
- int lena = str_len(a);
- t = (char *) malloc(sizeof(char) * (lena + lenb + 2));
- str_copy(t, a, lena);
- *(t + lena) = ' ';
- str_copy(t + lena + 1, b, lenb);
- free(a);
- return t;
- }
- }
- int canMatch(char *input, char *rule) { // 返回最长匹配长度 -1表示不匹配
- if (*rule == 0) { //已经到rule尾端
- return 0;
- }
- int r = -1 ,may;
- if (*rule == '*') {
- r = canMatch(input, rule + 1); // *匹配0个字符
- if (*input) {
- may = canMatch(input + 1, rule); // *匹配非0个字符
- if ((may >= 0) && (++may > r)) {
- r = may;
- }
- }
- }
- if (*input == 0) { //到尾端
- return r;
- }
- if ((*rule == '?') || (*rule == *input)) {
- may = canMatch(input + 1, rule + 1);
- if ((may >= 0) && (++may > r)) {
- r = may;
- }
- }
- return r;
- }
- char * my_find(char input[], char rule[]) {
- int len = str_len(input);
- int *match = (int *) malloc(sizeof(int) * len); //input第i位最多能匹配多少位 匹配不上是-1
- int i,max_pos = - 1;
- char *output = 0;
- for (i = 0; i < len; ++i) {
- match[i] = canMatch(input + i, rule);
- if ((max_pos < 0) || (match[i] > match[max_pos])) {
- max_pos = i;
- }
- }
- if ((max_pos < 0) || (match[max_pos] <= 0)) { //不匹配
- output = (char *) malloc(sizeof(char));
- *output = 0; // \0
- return output;
- }
- for (i = 0; i < len;) {
- if (match[i] == match[max_pos]) { //找到匹配
- output = str_join(output, input + i, match[i]);
- i += match[i];
- }
- else {
- ++i;
- }
- }
- free(match);
- return output;
- }
2、本题也可以直接写出DP方程,如下代码所示:
- //copyright@chpeih 2013/4/23
- char * my_find(char input[], char rule[]) {
- int len = str_len(input);
- int *match = (int *) malloc(sizeof(int) * len); //input第i位最多能匹配多少位 匹配不上是-1
- int i,max_pos = - 1;
- char *output = 0;
- for (i = 0; i < len; ++i) {
- match[i] = canMatch(input + i, rule);
- if ((max_pos < 0) || (match[i] > match[max_pos])) {
- max_pos = i;
- }
- }
- if ((max_pos < 0) || (match[max_pos] <= 0)) { //不匹配
- output = (char *) malloc(sizeof(char));
- *output = 0; // \0
- return output;
- }
- for (i = 0; i < len;) {
- if (match[i] == match[max_pos]) { //找到匹配
- output = str_join(output, input + i, match[i]);
- i += match[i];
- }
- else {
- ++i;
- }
- }
- free(match);
- return output;
- }
- char* my_find(char input[], char rule[])
- {
- //write your code here
- int len1,len2;
- for(len1 = 0;input[len1];len1++);
- for(len2 = 0;rule[len2];len2++);
- int MAXN = len1>len2?(len1+1):(len2+1);
- int **dp;
- //dp[i][j]表示字符串1和字符串2分别以i j结尾匹配的最大长度
- //记录dp[i][j]是由之前那个节点推算过来 i*MAXN+j
- dp = new int *[len1+1];
- for (int i = 0;i<=len1;i++)
- {
- dp[i] = new int[len2+1];
- }
- dp[0][0] = 0;
- for(int i = 1;i<=len2;i++)dp[0][i] = -1;
- for(int i = 1;i<=len1;i++)dp[i][0] = 0;
- for (int i = 1;i<=len1;i++)
- {
- for (int j = 1;j<=len2;j++)
- {
- if(rule[j-1]=='*'){
- dp[i][j] = -1;
- if (dp[i-1][j-1]!=-1)
- {
- dp[i][j] = dp[i-1][j-1]+1;
- }
- if (dp[i-1][j]!=-1 && dp[i][j]<dp[i-1][j]+1)
- {
- dp[i][j] = dp[i-1][j]+1;
- }
- }else if (rule[j-1]=='?')
- {
- if(dp[i-1][j-1]!=-1){
- dp[i][j] = dp[i-1][j-1]+1;
- }else dp[i][j] = -1;
- }
- else
- {
- if(dp[i-1][j-1]!=-1 && input[i-1]==rule[j-1]){
- dp[i][j] = dp[i-1][j-1]+1;
- }else dp[i][j] = -1;
- }
- }
- }
- int m = -1;//记录最大字符串长度
- int *ans = new int[len1];
- int count_ans = 0;//记录答案个数
- char *returnans = new char[len1+1];
- int count = 0;
- for(int i = 1;i<=len1;i++)
- if (dp[i][len2]>m){
- m = dp[i][len2];
- count_ans = 0;
- ans[count_ans++] = i-m;
- }else if(dp[i][len2]!=-1 &&dp[i][len2]==m){
- ans[count_ans++] = i-m;
- }
- if (count_ans!=0)
- {
- int len = ans[0];
- for (int i = 0;i<m;i++)
- {
- printf("%c",input[i+ans[0]]);
- returnans[count++] = input[i+ans[0]];
- }
- for (int j = 1;j<count_ans;j++)
- {
- printf(" ");
- returnans[count++] = ' ';
- len = ans[j];
- for (int i = 0;i<m;i++)
- {
- printf("%c",input[i+ans[j]]);
- returnans[count++] = input[i+ans[j]];
- }
- }
- printf("\n");
- returnans[count++] = '\0';
- }
- return returnans;
- }
欢迎于本文评论下或hero上 show your code。
参考文献及推荐阅读
- http://zhedahht.blog.163.com/blog/static/25411174200731139971/;
- http://hero.pongo.cn/,本文大部分代码都取自左边hero上参与答题者提交的代码,欢迎你也去挑战;
- 字符串转换成整数题目完整描述:http://hero.pongo.cn/Question/Details?ID=47&ExamID=45;
- 字符串匹配问题题目完整描述:http://hero.pongo.cn/Question/Details?ID=28&ExamID=28;
- linux3.8.4版本下的相关字符串整数转换函数概览:https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/lib/vsprintf.c?id=refs/tags/v3.9.4;
- 关于linux中的likely和unlikely:http://blog.21ic.com/user1/5593/archives/2010/68193.html;
字符串转换成整数,字符串匹配问题相关推荐
- 程序员编程艺术第三十 三十一章 字符串转换成整数,通配符字符串匹配
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 第三十~ ...
- 字符串转换成整数,带通配符的字符串匹配
之前本一直想写写神经网络算法和EM算法,但写这两个算法实在需要大段大段的时间,而平时上班,周末则跑去北大教室自习看书(顺便以时间为序,说下过去半年看过的自觉还不错的数学史方面的书:<数理统计学简 ...
- 程序员编程艺术第三十~三十一章:字符串转换成整数,通配符字符串匹配
第三十~三十一章:字符串转换成整数,带通配符的字符串匹配 前言 之前本一直想写写神经网络算法和EM算法,但写这两个算法实在需要大段大段的时间,而平时上班,周末则跑去北大教室自习看书(顺便以时间为序,说 ...
- 字符串转换成整数,通配符的字符串匹配问题
http://blog.csdn.net/v_july_v/article/details/9024123#comments 前言 之前本一直想写写神经网络算法和EM算法,但写这两个算法实在需要大段大 ...
- 判断字符为空_49. 把字符串转换成整数(剑指offer)
49. 把字符串转换成整数 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数. 数值为0或者字符串不是一个合法的数值则返回0. 输入描述: 输入一个字符串,包括数字字母符号,可以为空 输 ...
- c语言字符怎么变成整数,c语言,字符串转换成整数
c语言的数字字符串转换为整数,1.可接受"123 2123"处理为1232123;2.空指针.正负号.非纯数字字符串.数据越界溢出的错误处理. #include #include ...
- 如何把一个字符串转换成整数
剑指offer第一章的例子,据说是微软的面试题,发现自己又躺枪了.字符串处理有多烦人不用我多说了吧. //基础版代码 int StrToInt(char* string) {int number = ...
- oracle 转化为整数,字符串转换成整数——从源码学习
字符串转换成整数:输入一个表示整数的字符串,把该字符串转换成整数并输出,例如输入字符串"345",则输出整数345. 在笔试面试中,atoi 即「字符串转换成整数」是一个经典问题了 ...
- python 字符串转换成整数
| String to Int 写一个函数 StrToInt,实现把字符串转换成整数这个功能.不能使用 atoi 或者其他类似的库函数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个 ...
最新文章
- c语言后缀表达式构造二叉树,C ++程序为后缀表达式构造表达式树
- [AngularJS学习笔记] 基础学习01
- LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)
- 励志:读书七年,为了挣钱,我竭尽全力
- 03程序结构if for while
- Codeforces Round #716 (Div. 2) D. Cut and Stick 主席树 + 思维
- “Device eth0 does not seem to be present”解决办法
- 不要在有反馈的平台上输出
- 做游戏,学编程(C语言) 1 实现弹跳小球
- Robo 可视化mongoDb的操作
- Linux应用开发【第十四章】CAN编程应用开发
- 第二十八篇 -- 学习第五十一天打卡20190819
- 【华为云技术分享】漫谈LIteOS-物联网操作系统介绍
- 执行Hive SQL时报错:Map operator initialization failed
- 深度学习配置环境全攻略
- 手游平台开发怎么做?
- 计算机一级wps选择题必背知识点,计算机一级WPS提高练习题及答案
- 数字电视至显示android,手机投屏到电视的5种方法 看完才知道原来这么简单!
- 你见过哪些令你瞠目结舌的Python代码技巧?
- MyEclipse 2013优化技巧