职业经验 # 每日一道面试题 # 写一个方法,把字符串转为数字,比如 str="1234",变成 int 1234。

陈子昂 for 求职面试圈 · 2018年03月16日 · 最后由 蚩尤 回复于 2018年04月03日 · 4069 次阅读

感谢某同学提供的面试题,立马打赏了红包。如果有同学有面试题愿意分享的话,可以关注社区公众号,在那里把面试题给我们。

写一个方法,把字符串转为数字,比如 str="1234",变成 int 1234。你以为这么简单?那么请设计方法实现之后的测试用例!

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 26 条回复 时间 点赞

import string
if 1234 == string.atoi("1234");
return Ture
else
return False

def stringtoint(string):
“”” 不考虑为负数的情况”””
if string.isdecimal()==False:
raise Exception("input should be number!")
result = 0
temp = 0
for str in string[::-1]:
if str in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']:
result += int(str) * (10 ** temp)
temp += 1
return result
白盒测试用例解析
可使用语句覆盖和分支覆盖,因为本代码中的条件仅为一个,所以不考虑条件覆盖,分支条件覆盖,条件组合覆盖
语句覆盖
1)画流程图,识别路径:P1:a-b F2:a-c
流程图简述:真分支为 b,输出语句块 1,假分支路径为 c,输出语句块 2
2)记录分支节点及真假分支: M=string.isdecimal()
3)设计语句覆盖的测试用例 (简写)
测试用例输入 输出 语句块 1 语句块 2 覆盖路径
‘123’ 123 123 P1
‘-123’ input should be number input should be number P2
4)设计分支覆盖的测试用例
测试用例输入 输出 M 覆盖路径
‘123’ 123 123 P1
‘-123’ input should be number P2

考虑等价类和边界值两种设计方法
用例编号 等价类集合 边界值
1 (10-2147483647 之间的数字 0
2 2147483647
3 100000
4 (2)负整数 -1
5 -999999
6 (3)含非数字字符 abcd
7 Abc123efg
8 123 456
9 123[TAB] 456
10 123\t
11 123.01
12 (5) 位数超过 2147483647 2147483648
13 (6) 为空

robin 回复

这是考你思路的。。

def char2num(s):
  return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
def str2int(s):
  return reduce(lambda x,y: x*10+y, map(char2num, s))
robin 回复

因为 大家喜欢造轮子

感觉得看看 parseInt 的源码了

  1. 去掉空格
  2. 首位有没有正负符号
  3. 边界值
  4. 从左到右扫描,每个字符必须在 0 到 9 之间,然后循环取每个字符,之前的字符乘 10 加当前字符

public int atoi(String str) {
if (str == null || str.length() < 1)
return 0;

str = str.trim();

char flag = '+';

int i = 0;
if (str.charAt(0) == '-') {
flag = '-';
i++;
} else if (str.charAt(0) == '+') {
i++;
}

double result = 0;

while (str.length() > i && str.charAt(i) >= '0' && str.charAt(i) <= '9') {
result = result * 10 + (str.charAt(i) - '0');
i++;
}

if (flag == '-')
result = -result;

if (result > Integer.MAX_VALUE)
return Integer.MAX_VALUE;

if (result < Integer.MIN_VALUE)
return Integer.MIN_VALUE;

return (int) result;
}

感觉这个跑不起来😅

这种有现成的 api 为啥不用呢,而且这些异常应该在 api 底层都已经判断过了,不需要我们再判断一遍了,加个抛出异常应该可以了吧。
public class StrToInt {
public void strToInt(String s){
int value = 0;
try {
value = Integer.valueOf(s);
System.out.println(value);
}catch (Exception e){
System.out.println(e);
}
}
public static void main(String[] args){
StrToInt s = new StrToInt();
s.strToInt("-2147483647");
}
}

public class Change {
    private int returnNum=0;

    /*
     * 输入一个string,转换成int
     */
    Change(String string) {
        byte[] by = string.getBytes();
        //判断是否带负号
        if (by[0] == '-') {
            for (int i=1;i<by.length;i++) {
                returnNum =returnNum*10+(by[i]-48);
//              System.out.println(returnNum);
            }
            returnNum = ~returnNum+1;
        }else{
        for (byte b : by) {
            returnNum =returnNum*10+(b-48);
//          System.out.println(returnNum);
        }
        }
    }

    public int getNum() {
        return returnNum;
    }

    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        Change change =new Change("-1234");
        System.out.println(change.getNum());
    }

}

好吧,我也不清楚自己到底什么程度算自己写,就这样吧,本来只想写正数的,但是强迫症。。请大神多多指教。
用例的话:
1.正向用例一个,就输入 1234
2.边界值总要考虑的,输入的数字超过 int 范围。
3.a) 题目说的是把字符串转化成数字,可能会考虑到 asdf 这种字母。
b) 输入汉字。
c) 标点符号特殊字符。
4.性能的话,实在才疏学浅。不献丑了。。

看了上面同学的例子,越发觉得自己想得不够全面。😂 我觉得首先还是要明确需求,输入的条件千千万,输出的条件只有一个,对象的类型是 int。那我也举个例子,输入’abc123‘,我输出 123 是否符合需求?如果符合,那我可以用正则表达式匹配出所有 str 里的数字,然后打印出来。如果不符合,我应该抛出什么样的异常?类似的情况还有浮点数,空格,字符 + 数字组合等等,要把所有的异常都抓出来恐怕不太容易,所以我就干脆用 except Exception as e 这个方法直接抛出 python 自带的异常了。不同的系统可输出的 int 边界值不同这一点是应该考虑到的,不过平时没有怎么接触过这么大的数据😅

写一个方法,把字符串转为数字,比如 str="1234",变成 int 1234。你以为这么简单?那么请设计方法实现之后的测试用例!
功能方面的考虑:
def chenjie(self,number):
numbers=int(number)
print number
这样强制转换就可以但是如果,str=“-1234” 的时候就会报错所以需要修改程序
def chenjie(self,number):
if number[0]=='-':
numbers=int(number[1:])*-1
else:
numbers=int(number)
print number

边界方面的考虑:
我使用的 py2
我还要考虑 str 的取值长度 int 的取值范围
python 本身对 string 长度无强制性限制。使用过程中主要需要考虑电脑性能和程序效率
https://yq.aliyun.com/articles/415562?utm_content=m_41515(有人已经做过实验了,谢谢分享)
32 位系统 int 的范围为 -2*31 到 231-1 -2147483648~2147483647
64 位系统 int 的范围为 -2
63 到 2*63-1 -9223372036854775808~9223372036854775807
我生成测试数据
边界用例测试数据:
32 位机器上:
-2147483649
-2147483648
2147483647
2147483648

64 位机器上:
-9223372036854775808
-9223372036854775809
9223372036854775807
9223372036854775808

要满足这个条件有需要要修改代码
def chenjie(self,number):
biajielists=[-2147483648,2147483647,-9223372036854775808,9223372036854775807]:
if biajielists[0]<=biajielists<=biajielists[1] or biajielists[2]<=biajielists<=biajielists[3]
if number[0]=='-':
numbers=int(number[1:])*-1
else:
numbers=int(number)
print number
else:print "Out of int length"

# 我在编写这个小程序的时候,使用了变量 number 和 numbers 两个变量,开辟了 2 块内存地址
number 在 numbers 执行后 number 不要使用了,不是长期变量,这里不存在内存不够用的情况。
但是我还是要手动把 number 对象引用删除。
我的理由:我在公司中需要拉取股票基本数据,再使用股票基础数据参与计算,生成数据表给到投研做统计,我当时有一个表 85 字段,15 个基础数据,剩下对都是 15 个字段计算出来的数据,我引用了很多的基础字段后,发现有些字段在计算后就不在使用了,但是,它的应用计数是在程序结束后在变为 0,垃圾回收机制才回收那块内存,有时候我的内存会不够,所以,我后来就开始及时释放不用的对象。我的表大小 85 个字段 20 多年数据(每年 220 条数据)有股票数是 3445 支。85*220*20*3445
所以,我加上了 del(number)
def chenjie(self,number):
biajielists=(-2147483648,2147483647,-9223372036854775808,9223372036854775807)
if biajielists[0]<=number<=biajielists[1] or biajielists[2]<=number<=biajielists[3]:
if number[0]=='-':
numbers=int(number[1:])*-1
else:
numbers=int(number)
del number
print number
else:print "Out of int length"

如果有不对的地方 希望大家指正

匿名 #16 · 2018年03月16日
槽神 回复

被大神点名了😂

看语言吧,请各位记得测试 65535,还有数据库的 int、Integer 类型测试,9 楼那个测试显然太黑盒了

if(Int32.TryParse("123"+"4",out int Num))
{
return Num
}
else
{
throw new Exception("无法转换")
}

233

#-*- coding: utf-8 -*-
# @Time    : 2018/3/16 11:53
# @File    : StrToInt.py 
# @Author  : 守望@天空~

def str_to_int(string):
    """
    字符串转整数
    :param string: 字符串 str unicode
    :return: 整数 int
    """
    numbers = [0,1,2,3,4,5,6,7,8,9]
    numbers_str = map(str,numbers)
    if not isinstance(string ,(str,unicode)):
        # raise  Exception(u"请输入字符串")
        return u"请输入字符串"
    if string.startswith("-"):
        status = -1
        string =string[1:]
    elif string.startswith("+"):
        status = 1
        string = string[1:]
    else:
        status=1
    for  i in string:
        if i not in numbers_str:
            # raise Exception(u"请输入正确的整数")
            return  (u"请输入正确的整数")
    result =0
    length = len(string)
    if not length:
        # raise Exception(u"请输入有效数字")
        return "请输入有效数字"
    for i,value in enumerate(string):
        result += numbers[numbers_str.index(value)]*10**(length-i-1)
    return result*status

if __name__=="__main__":
    print str_to_int("1234")
    print str_to_int("01234")
    print str_to_int("#!@#1234")
    print str_to_int("asd")
    print str_to_int("-1234")
    print str_to_int("+1234")
    print str_to_int(u"+1234")
    print str_to_int(u"+")
    print str_to_int(u"-0")
    print str_to_int("1234.1234")
    print str_to_int(1234)
    print str_to_int(1234.1234)
    print str_to_int("9"*10086)
def str_to_int(s):
    """
    字符串转整形
    :param s: 字符串
    :return: 结果
    """
    if s is None or len(s) == 0:
        return '字符串有误。'
    try:
        return int(s)
    except Exception:
        return '转换失败'

if __name__ == "__main__":
    print(str_to_int('sds'))

这样行吗?

# Python 黑魔法之 不安全的方式
In [1]: eval('1234')
Out[1]: 1234

# 安全的方式
In [2]: import ast

In [3]: ast.literal_eval('1234')
Out[3]: 1234


kotlin
import java.util.*
val str :String? =  Scanner(System.`in`).nextLine()
print( "${try { str?.toInt() ?: 0 } catch (e: Exception) { 0 }}")

#Testcase1 # 正常输入 123
#Testcase2 # 输入 none
#Testcase3 # 输入""
#Testcase4 # 输入 +
#Testcase5 # 输入-
#Testcase6 # 输入 +0
#Testcase7 # 输入-0
#Testcase8 # 输入 +123
#Testcase9 # 输入-123
#Testcase10 # 输入 abc123
#Testcase11 # 输入 1.234
#Testcase12 # 输入?~!@#$%&*()
#Testcase13 # 输入 99999999999999999999999999999999999999999...9999(测最大有效数字)
#Testcase14 # 输入-99999999999999999999999999999999999999999...9999(测最小有效数字)


我看到了这句话

def StrToInt():
    words = input('input:')
    try:
        word = words.replace(' ','')
        word = int(word)
        return word
    except Exception as e:
        return e

if __name__=="__main__":
    a = StrToInt()
    print(a)

面试官:你可以走了😂

写一写不难吧,关键是设计出对应测试用例,自证自己的实现是正确的

String str = "123";
String s1 = String.valueOf(str.charAt(str.length()-1));
int i = Integer.valueOf(s1) + 1;
String s2 = String.valueOf(i);
str = str.concat(s2);
int result = Integer.valueOf(str);

我遇到过同样的面试题😂

import re

def string2int01(string):
    result = 0
    sign = 0
    temp = 0
    if string[0] == '-':
        sign = 1
    for str in string[::-1]:
        if str in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']:
            result += int(str) * (10 ** temp)
            temp += 1
    if sign == 1:
        result = 0 - result
    return result

def string2int02(string):
    result = 0
    aim = re.findall('[0-9]+', string)
    size = len(aim) - 1
    for i in range(size, -1, -1):
        result += int(aim[i]) * (10 ** (size - i))
    if string[0] == '-':
        result = 0 - result
    return result
sincool 回复

你这个方法是自己写的?

这道题我曾经也见过😂

String str="123"+"4"
int num=Integer(str)
那么请设计方法实现之后的测试用例!这句话是啥意思????

变成 123

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册