剑指offer题库总结(二)之字符串(C语言版本)

剑指offer题库总结(二)之字符串(C语言版本)

题67:把字符串转换成数字

  • 题目具体要求
  • 将一个只有数字或“+”或“-”组成的字符串转换成对应的数字。(不能使用库函数atoi)
  • 示例:
    • input: “123” output: 123
    • input: “+56” output:56
    • input:“-23” output:-23
  • 用例测试:
    • 功能测试:需考虑输入字符串表示正数、负数、0。
    • 边界值测试:可能存在上溢出或者下溢出(即测试最大或者最小整数)
    • 特殊测试:输入字符串为null指针,输入字符串为空或者非数字字符串等。
  • 解题:
//==================================================================
// 面试题67:把字符串转换成整数
// 题目:请你写一个函数StrToInt,实现把字符串转换成整数这个功能。当然,
// 不能使用atoi或者其他类似的库函数。

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

enum Status{ 
    Valid = 0,
    Invalid 
};
//全局变量
int g_Status = Valid; //表示输入的字符串是否可以转成数字,0表示成功,1表示无效。

//函数声明
long long StrToIntCore(const char* str, int SignFlag);

//字符串转数字
int StrToInt(const char* str)
{
    g_Status = Invalid; //初始化为1,表示未转成功。
    long long num = 0;    //返回值

    if (str != NULL && *str != '\0') 
    {
        int SignFlag = 1; //1:表示正数,0表示负数

        if (*str == '+')
            str++;
        else if (*str == '-')
        {
            str++;
            SignFlag = 0;
        }

        if (*str != '\0') //输入字符串不是“+”或者“-”时
        {
            num = StrToIntCore(str, SignFlag);
        }
    }
    return (int)num;
}

long long StrToIntCore(const char *digit, int SignFlag)
{
    long long num = 0;

    while (*digit != '\0')
    {
        if (*digit >= '0' && *digit <= '9')
        {
            int flag = (SignFlag == 0) ? -1 : 1;
            num = num * 10 + flag * ((long long)*digit - '0');

            if (((SignFlag == 1) && (num > 0x7FFFFFFF)) 
                || ((SignFlag == 0) && (num < (signed int)0x80000000)))
            {
                num = 0;
                break;
            }
            digit++;
        }
        else
        {
            num = 0;
            break;
        }
    }
    if (*digit == '\0')
    {
        g_Status = Valid;
    }
    return num;
}

// ====================测试代码====================
void Test(const char *string)
{
    int result = StrToInt(string);
    if (result == 0 && g_Status == Invalid)
        printf("the input %s is invalid.\n", string);
    else
        printf("number for %s is: %d.\n", string, result);
}

int main(int argc, char* argv[])
{
    Test(NULL);    //the input (null) is invalid.
    Test("");      //the input  is invalid.
    Test("+");     //the input + is invalid.
    Test("-");     //the input - is invalid.
    Test("1a33"); //the input 1a33 is invalid.

    Test("123");//number for 123 is: 123.
    Test("+123");//number for +123 is: 123.
    Test("-123"); //number for - 123 is: -123.
    Test("+0");//number for +0 is: 0.
    Test("-0");//number for -0 is: 0.

    //有效的最大正整数, 0x7FFFFFFF,可能存在上溢出
    Test("+2147483647");//number for + 2147483647 is: 2147483647.
    Test("+2147483648"); //the input + 2147483648 is invalid.  

    //有效的最小负整数, 0x80000000,可能存在下溢出
    Test("-2147483648"); //number for - 2147483648 is : -2147483648.
    Test("-2147483649");//the input - 2147483649 is invalid.  

    return 0;
}

衍生题目:将两个字符串相加,若全为数值字符串则输出他们的和,否则认为无效。

  • 示例:
    • 输入:“123” “1” 输出:124
    • 输入:“123run" “12” 输出:无效
  • 解题思路:
    • 只需要将上面的StrToInt函数分别调一次,然后两次均有效即累加输出和。

题65:不用加减乘除做加法

  • 题目具体要求:写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
  • 数据范围:两个数都满足 0≤n≤1000
  • 进阶:空间复杂度 O(1),时间复杂度 O(1)
  • 示例1
    输入:1,2
    返回值:3
    -解题思路:不能用四则运算符,那就只能用位运算。
    输入:5,17
    按照十进制分步计算:
    (1)个位十位分别相加且不进位:5+7 = 2,0+1 = 1,得到值为12;
    (2)做进位,5+7有进位,进位得到10;
    (3)将前两步的数值相加:12+10 = 22
    按照2进制的分步计算:
    (1)各位都不进位:5(00101)+17(10001)= 10100 (对应异或运算)
    (2)考虑进位,只有最后一位是进位了,得到00010 (对应位与算法再左移1位)
    (3)然后将(1)(2)步骤循环累加,直到不进位。恰好不进位,得到10110。 (对应循环,直到不进位)
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 * @param num1 int整型 
 * @param num2 int整型 
 * @return int整型
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
int Add(int num1, int num2 ) {
    // write code here
    while(num2 != 0)
    {
        int c = ((unsigned int)(num1 & num2)) << 1;
        num1 ^= num2;
        num2 = c;
    }
    return num1;
}
  • 变式题:不用使用中间变量交换两个数的值。
/*方法1:通过加减法*/
int a = 6;
int b = 3;
a = a + b; //9
b = a - b;//6
a = a -b; //3
/*方法2:通过位或运算*/
int a = 6;
int b = 3;
a = a ^ b; //5
b = a ^ b; //6
a = a ^ b; //3   
//一个数与另一个不相等的数进行异或2次,就可以成本身:A^B^B = A(A!=B)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值