题目概述:
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储 单个 数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例1:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。
示例2:
输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。
示例3:
输入:digits = [0]
输出:[1]
提示:
1 <= digits.length <= 100
0 <= digits[i] <= 9
解题思路:
这道题是一道相对简单的题,正好给刚学完数组的我练练手。老样子还是先在VS上创建好基本框架准备好:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define Max_Range 100 // 数组最大长度为100
int* plusOne(int* arr, int arrSize, int* returnSize) // 计算加一
{
}
void printArr(int* arr, int arrSize) // 打印数组
{
}
int main()
{
// ① 输入数组
// ② 加一计算
// ③ 打印数组
return 0;
}
我的基本思路是第①步在主函数中先输入源数组,第②步通过调用一个计算加一函数获得结果数组,第③步通过调用打印函数对数组进行打印(没错还是在控制台)。输入数组的代码还是很简单的,这边我就直接动手先解决了这一步:
// ① 输入数组
int arr[Max_Range];
int arrSize = 0; // 原数组有效长度
while (1)
{
printf("请输入第%d个数字为(输入完成后可输入-1结束输入):", arrSize+1);
scanf("%d", &arr[arrSize]);
//判断是否结束数组
if (arr[arrSize] < 0 || arr[arrSize] > 9)
break;
else
++arrSize;
}
第②步就开始要动脑子了,首先加1其实很好解决,直接在数组最后一位加1就好,但是麻烦的是进位,当位数为9时加1就得到下一位,数组的长度也因此变长,但我目前所学的数组并不能做到变长变短(因为数组的长度必须是个常量),这一点难住了我,于是我再次打开b站进行学习,由于是有针对性的查找,很快我便找到了能满足我要求的那块拼图
——动态分配数组malloc和数组复制memcpy:
// 插入头文件
#include<string.h>
#include<stdlib.h>
// 动态分配数组定义方式:数组类型* 数组名 = (类型强转以防报错)malloc(所占内存空间大小)
Type* result = (Type*)malloc(sizeof(Type) * arrSize);
// 数组复制方法:memcpy(目标地址, 源地址, 所占内存空间大小)
memcpy(result, arr, sizeof(Type) * arrSize);
这两个函数可以让我能定义一个可以用变量控制长度的数组,并将原来那个输入的数组内容复制到这个动态数组中,这样我就能做到进位的操作(也就是将9置0,并将高位+1),再通过一个循环判断依次判断每一位数,因此根据分析可以写出代码如下:
#include<string.h>
#include<stdlib.h>
int* plusOne(int* arr, int arrSize, int* returnSize) // 计算加一后有效数组
{
// 动态分配一个数组,数组大小为原数组大小+1(以防结果最高位进位)
// 动态分配数组定义方式:数组类型* 数组名 = (类型强转以防报错)malloc(所占内存空间大小)
int* result = (int*)malloc(sizeof(int) * (arrSize + 1));
// 复制arr数组内容至result数组中
// 数组复制方法:memcpy(目标地址, 源地址, 所占内存空间大小)
memcpy(result, arr, sizeof(int) * arrSize);
// 循环检查数组中每一位元素(即所输入数字中每一位)是否为9
for (int i = arrSize - 1; i >= 0; --i)
{
if (result[i] == 9)
result[i] = 0; // 若该位为9则该位置零
else
{
result[i]++; // 若该位不为9则该位加一,并直接返回结果数组
*returnSize = arrSize;
return result;
}
}
// 最后如果跳出循环,则意味着需进一位(即将首位置于1,末位置于0)
result[0] = 1;
result[arrSize] = 0;
*returnSize = arrSize + 1;
return result; // 最后返回结果数组
}
// ② 计算加1
int returnSize; // 加一后数组有效长度
int* result = plusOne(arr, arrSize, &returnSize);
最后再循环打印结果数组:
void printArr(int* arr, int arrSize) // 打印有效数组
{
printf("结果为:");
for (int i = 0; i < arrSize; ++i)
{
printf("%d", arr[i]);
}
printf("\n");
}
// ③ 打印数组
printArr(result, returnSize);
最后将代码补全进之前写出的框架中,再套入提示与循环得出完整代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define Max_Range 100 // 数组最大长度为100
int* plusOne(int* arr, int arrSize, int* returnSize) // 计算加一后有效数组
{
// 动态分配一个数组,数组大小为原数组大小+1(以防结果最高位进位)
// 动态分配数组定义方式:数组类型* 数组名 = (类型强转以防报错)malloc(所占内存空间大小)
int* result = (int*)malloc(sizeof(int) * (arrSize + 1));
// 复制arr数组内容至result数组中
// 数组复制方法:memcpy(目标地址, 源地址, 所占内存空间大小)
memcpy(result, arr, sizeof(int) * arrSize);
// 循环检查数组中每一位元素(即所输入数字中每一位)是否为9
for (int i = arrSize - 1; i >= 0; --i){
if (result[i] == 9)
result[i] = 0; // 若该位为9则该位置零
else{
result[i]++; // 若该位不为9则该位加一,并直接返回结果数组
*returnSize = arrSize;
return result;
}
}
// 最后如果跳出循环,则意味着需进一位(即将首位置于1,末位置于0)
result[0] = 1;
result[arrSize] = 0;
*returnSize = arrSize + 1;
return result; // 最后返回结果数组
}
void printArr(int* arr, int arrSize) // 打印有效数组
{
printf("结果为:");
for (int i = 0; i < arrSize; ++i) {
printf("%d", arr[i]);
}
printf("\n");
}
int main()
{
// ① 输入数组
int arr[Max_Range];
int arrSize = 0; // 原数组有效长度
while (1) {
printf("请输入第%d个数字为(输入完成后可输入-1结束输入):", arrSize+1);
scanf("%d", &arr[arrSize]);
//判断是否结束数组
if (arr[arrSize] < 0 || arr[arrSize] > 9)
break;
else
++arrSize;
}
// ② 加一计算
int returnSize; // 加一后数组有效长度
int* result = plusOne(arr, arrSize, &returnSize);
// ③ 打印数组
printArr(result, returnSize);
return 0;
}
成功运行后如下:
第二天我进一步巩固了一下数组的使用,整体效果还行,虽然暂时还没学到如何更好的应付之前那个小BOSS(杨辉三角),但是至少把一个精英怪先拿下了(虽然还是控制台输出),但俗话说的好:“打不过BOSS就得多刷刷精英怪练练级!”因此我后续有空估计还会多刷几遍这个精英怪(多种思路),来多攒攒经验!