首页
社区
课程
招聘
[原创]给师弟做了刘涛涛题目
2007-6-13 00:14 15477

[原创]给师弟做了刘涛涛题目

2007-6-13 00:14
15477
好像是刘涛涛面试的题目
// 刘涛涛题目
// 有一个字符串,里面包含一些数字,写一个函数, 把这些数字加起来。
// 比如“我30你40他50”结果就是120。

运行结果如下:

C:\tst\calc_str>cal
[+] Usage:   cal {#input string}
[-] Example: cal 我30你40他50
[-] ---->Result: 120

C:\tst\calc_str>cal 我30你40他50
input string length = 12
input string is:  我30你40他50
copyed string is: 我30你40他50
i = 3   current string: 30      sum =     30
i = 7   current string: 40      sum =     70
i = 11  current string: 50      sum =    120
---->Result: 120

代码如下:
//////////////////////////////////////////////////////////////////////////////
//
// 刘涛涛题目
// 有一个字符串,里面包含一些数字,写一个函数, 把这些数字加起来。
// 比如“我30你40他50”结果就是120。
// coded by aker
//
//////////////////////////////////////////////////////////////////////////////
// 头文件
#include <stdio.h>

//////////////////////////////////////////////////////////////////////////////
// 全局变量

//////////////////////////////////////////////////////////////////////////////
// 参数表

//////////////////////////////////////////////////////////////////////////////
// 入口点
int main(int argc, char* argv[])
{
    char *cPtr=NULL,*cIter=NULL;
    char *buf;
    int len,i,sum=0;
    if (argc < 2)
    {
            printf("[+] Usage:   %s {#input string} \n"
                   "[-] Example: %s 我30你40他50\n"
                   "[-] ---->Result: 120\n",
                   argv[0],argv[0]);
            exit(1);
    }
   
    // 复制字符串
    len = strlen(argv[1]);
    buf = (char*)malloc(len+1);
    strcpy(buf,argv[1]);
   
    printf("input string length = %d\n",len);
    printf("input string is:  %s\n",argv[1]);
    printf("copyed string is: %s\n",buf);

    // 截断字符串,将其变为多个字符串,计算每个数字字串
    for(i=0;i<len;i++)
    {
        if(buf[i] >= '0' && buf[i] <= '9') // 字符为数字
        {
            cPtr = buf+i;
            cIter = cPtr+1;
            
            while (*cIter >= '0' && *cIter <= '9') // 寻找数字字符串
            {
                cIter++;
                i++;
            }               
            *cIter = '\0';
            sum += atoi(cPtr);
            printf("i = %d\tcurrent string: %s\tsum = %6d\n",i,cPtr,sum);
        }
    }
    printf("---->Result: %d\n",sum);
    free(buf);
    return 0;
}
//////////////////////////////////////////////////////////////////////////////

[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞7
打赏
分享
最新回复 (29)
雪    币: 6073
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
forgot 26 2007-6-13 02:09
2
0
不知道为什么考这个。。。估计要现场而且要一次通过
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
Aker 4 2007-6-13 02:31
3
0
感觉只要知道一些字符编码知识,逻辑没有问题,就很块可以做出来,这应该是简单题:P,我花了10分钟不到,还是因为修改格式的
问我的兄弟主要是没有把那个数字串连起来的整体考虑,然后写了n多代码..........
雪    币: 258
活跃值: (230)
能力值: ( LV12,RANK:770 )
在线值:
发帖
回帖
粉丝
qiweixue 19 2007-6-13 09:14
4
0
呵呵,我是容易的做不对,难的又不会...
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
dwing 1 2007-6-13 10:18
5
0
#include <stdio.h>
#include <stdlib.h>

int sum(const char *str)
{
	int s=0;
	do
	{
		s+=atoi(str);
		while(*str>='0' && *str<='9') ++str;
	}while(*str++);
	return s;
}

void main(int argc,char **argv)
{
	if(argc==2) printf("%d\n",sum(argv[1]));
}
雪    币: 232
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
auser 2007-6-13 10:38
6
0
很适合当高级管理人员!
雪    币: 1767
活跃值: (751)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
yijun8354 12 2007-6-13 13:10
7
0
不难~~
雪    币: 380
活跃值: (101)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
llydd 9 2007-6-13 22:08
8
0
如果参数字符串中带有符号可能会出错
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ddrmsdos 2007-6-13 22:22
9
0
DFA的问题了......
S->aS
a为0-9
用确定性有穷自动机搞定...不知道行不行
雪    币: 380
活跃值: (101)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
llydd 9 2007-6-13 22:45
10
0
呵呵,编译原理来了
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
Aker 4 2007-6-14 09:17
11
0
dwing的思路和我一样,都是截断字符串计算,但是实现看起来清爽很多:)
问题:
1。实现时有错误,看了下atoi的实现,如果输入字符中有两个--相连的时候,atoi会跳过该数字,如 "aker--9=10"只会计算10

2。另外感觉dwing每次调用atoi还是有些不好,稍微改了下,主要是加了个判断,这样就会少调用很多次atoi了。

int sum(const char *str)
{
        int s=0;
        do
        {
                if(*str>='0' && *str<='9')
                {        // 如果是数字则试图计算
                        s+=atoi(str);
                        do
                                ++str;
                        while(*str>='0' && *str<='9'); // 该数字串已计算,跳过数字
                }
        }while(*str++);
        return s;
}

但是"--"的问题还存在,需要修改判断条件
感觉我的那个老实的程序没错;)
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
Aker 4 2007-6-14 09:19
12
0
感觉dwing的程序如果自己实现atoi,并且加上判断的话就比较完美了
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
dwing 1 2007-6-14 09:19
13
0
嗯,如果考虑"+"和"-",把:
s+=atoi(str);
换成:
if(*str>='0') s+=atoi(str);

#include <stdio.h>
#include <stdlib.h>

int sum(const char *str)
{
  int s=0;
  do
  {
    if(*str>='0') s+=atoi(str);
    while(*str>='0' && *str<='9') ++str;
  }while(*str++);
  return s;
}

void main(int argc,char **argv)
{
  if(argc==2) printf("%d\n",sum(argv[1]));
}


输入:"aker--9=++10"
输出:19

程序的目标是尽量简单,如果要考虑极高效率,atoi就要自己写了.
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
Aker 4 2007-6-14 09:25
14
0
问一下,怎么贴代码的哈;)
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
dwing 1 2007-6-14 09:32
15
0
使用:
[CODE]
代码写在这里
[/CODE]
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
Aker 4 2007-6-14 09:34
16
0
我这不可以用sum,有个库里面有sum,
刚才我没测试,用了if(*str>='0' && *str<='9')判断,并把数字后跳得过程后移则没有"--"的问题了

哈哈,我学会贴代码了,谢...........

int mysum(const char *str)
{
	int s=0;
	do
	{
		if(*str>='0' && *str<='9')
		{	// 如果是数字则试图计算
			printf("sum = %6d\tcurrent string: %s\n",s,str);
			s+=atoi(str);
			while(*str>='0' && *str<='9')++str; // 该数字串已计算,跳过数字
		}
	}while(*str++);
	return s;
}
雪    币: 268
活跃值: (10)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
三根火柴 4 2007-6-14 15:25
17
0
又学了不少东西啊!
雪    币: 709
活跃值: (2265)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
sudami 25 2007-6-15 07:26
18
0
弱弱的问一下:

do
  {
    s+=atoi(str);
    while(*str>='0' && *str<='9') ++str;
  }while(*str++);


其中的while(*str++)为什么以此字符串作为判断是否结束的条件呢?

当把字符串读完时,是'\0',  while ('\0')是啥意思呢,和while (0)不一样的吧?
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
Aker 4 2007-6-15 10:41
19
0

printf("%.2X",0xff&'\0');
printf("%.2X",0xff&0);
看下就知道了
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
dwing 1 2007-6-15 11:54
20
0
严格地说,'\0'是char的空字符,0是int类型整数的0,二者是不同的.
但实际上几乎所有的计算机都使用ASCII编码的字符,所以'\0'==(char)0,
而char(0)和(int)0可以安全地隐式转换,所以'\0'==(int)0.
在while中,C++只判断bool类型,而(int)0和false可以约定俗成地隐式转换.
所以最后得到的结论是:'\0'==false.
雪    币: 709
活跃值: (2265)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
sudami 25 2007-6-15 12:26
21
0
嗯,谢谢讲解,我明白了
雪    币: 709
活跃值: (2265)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
sudami 25 2007-6-16 10:23
22
0
罗嗦一句,楼上的大牛看到了麻烦再分析下啊 :

-----------------------------------------------------------------------
嗯,当指针str移动到 '\0' 时,执行最后一次循环:s+=atoi(str);

然后跳出循环,此时str指向NULL, while(0) 就退出了...

----------------------------
那这个解释好象存在问题:

'\0'==false.

其实'\0' 还是一个字符串,和0不同,只是str指针再挪一位时为NULL了才退出的.
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
dwing 1 2007-6-16 16:31
23
0
'\0' != "\0"
雪    币: 515
活跃值: (1223)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
RoBa 16 2007-6-16 17:08
24
0
atoi()不是ANSI标准,要尽量避免使用,比方说在GCC里就是编译不过的。想要转化的话也可以用sscanf()。

写个不用库函数的:
int calc(char *buf) {
	int i, s, ans;
	for (i = s = ans = 0 ; buf[i] ; i++) {
		if (buf[i] >= '0' && buf[i] <= '9') 
			s = s * 10 + buf[i] - '0';
		else {ans += s; s = 0;}	
	}
	return ans + s;
}
雪    币: 267
活跃值: (16)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
Rinrin 1 2007-6-16 19:14
25
0
这样的话,S只能是数字了
游客
登录 | 注册 方可回帖
返回