剑指offer-字符串转为int数字,不用+来相加两个数,不用新增变量来交换数,在递增序列中找和为s的两个数字and找和为s的序列。

字符串转为int数字

思路:

思路不难,但又很多注意的地方,如输入的字符串为"",为空指针。字符串符号问题,字符串有非法字母。数据溢出。

代码:

static bool Invalid = 0;
#define MaxInt 0x7FFFFFFF
#define MinInt 0x80000000
long StringtoLong(char* str,bool flag)
{
    long num = 0;
    while (*str != '\0')
    {
        if (*str >= '0' && *str <= '9')
        {
            num = num * 10 + *str - '0';
            
            str++;
        }
        else
        {
            Invalid = true;
            return 0;
        }
    }
    cout << num << ' ';
    if (flag == 1)
        num = -num;
    if (num < (int)MinInt) //这里的num是long类型,0x8000000要转为int类型,否则,long的0x8000000为正数。
    {
        Invalid = 1;
        return 0;
    }
    else if (num > MaxInt)
    {
        Invalid = 1;
        return 0;
    }
    return num;
}
int StringtoInt(char* str)
{
    bool flag = 0;
    if (str == NULL)
    {
        Invalid = 1;
        return 0;
    }
    if (*str == '\0')
    {
        Invalid = 1;
        return 0;
    }
    if (*str == '+')
    {
        flag = 0;
        str++;
    }
    else if (*str == '-')
    {
        flag = 1;
        str++;
    }
    /*for (; *str != '\0'; str++)
    {
        cout << *str;
    }*/
    long ans = StringtoLong(str,flag);
    return (int)ans;
    
}

不用+来相加两个数

思路:

考察位操作。二进制中。第n位相加,都是1的话,结果为0,进位为0。一个为1,一个为0,结果为1,进位为0。都为0时,进位为0,结果为0.可以看到,结果为异或操作,进位为与操作。

代码:

int Add(int a, int b)
{
    do//先要运行一次,因为b可能是0
    {
        int sum = a ^ b;
        int carry = (a & b )<< 1;
        a = sum;
        b = carry;
    } while (b != 0);
        return a;
}

PS.不用新增变量来交换数

思路:

有两种,一种位运算,一种加减法。

代码:

void exchange1(int a, int b)
{
    a = a + b;
    b = a - b;;
    a = b;
}
void exchange2(int a, int b)
{
    a = a ^ b;
    b = a ^ a;
    a = a ^ b;
}

在递增序列中找和为s的两个数字and找和为s的序列。

思路:

递增序列,可以从两头往中间走,和小于s,前面的指针向后,大于s,后面的指针向前。
找和为s的序列也是这个思路,两个指针一开始指向第一个第二个数字,随后比较sum和s,sum<s,后指针往后,增加一个数字。反之,前指针向前,抛弃一个数字。不从从两头往中间走是因为,数组的和在一直变小。

代码:

bool find_twonumbers(int arr[], int len,int k)
{
    bool found = false;
    if (arr == NULL||len<=0)
        return found;
    int head = 0;
    int tail = len - 1;
    while (head < tail)
    {
        int sum = arr[head] + arr[tail];
        if (sum == k)
        {
            cout << arr[head] << ' ' << arr[tail] << endl;
            found = true;
            break;
        }
        else if (sum < k)
        {
            head++;
        }
        else
        {
            tail--;
        }
    }
    return found;
}
void FindContinueSequence(int sum)
{
    if (sum < 3)
        return;
    int small = 1;
    int big = 2;
    int middle = (sum + 1) / 2;  
    int current = 3;
    while (small < middle)  //当small大于等于middle时,small到big的数字肯定大于sum
    {
        
        if (current == sum)
        {
            for (int i = small;i < big + 1; i++)
            {
                cout << i << ' ';
            }
            big++;
            current += big;
            cout << endl;
        }
        else if (current < sum)
        {
            big++;  //加入一个大的数字
            current += big;
        }
        else
        {
            current -= small;
            small++;  //去掉一个小的数字
            
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/void-lambda/p/12431877.html