前言:本期是关于出租的详解,内容包括四大模块:题目,代码实现,大致思路,代码解读,今天你c了吗?
题目:
下面是新浪微博上曾经很火的一张图:
一时间网上一片求救声,急问这个怎么破。其实这段代码很简单,index
数组就是arr
数组的下标,index[0]=2
对应 arr[2]=1
,index[1]=0
对应 arr[0]=8
,index[2]=3
对应 arr[3]=0
,以此类推…… 很容易得到电话号码是18013820100
。
本题要求你编写一个程序,为任何一个电话号码生成这段代码 —— 事实上,只要生成最前面两行就可以了,后面内容是不变的。
输入格式:
输入在一行中给出一个由11位数字组成的手机号码。
输出格式:
为输入的号码生成代码的前两行,其中arr
中的数字必须按递减顺序给出。
输入样例:
18013820100
输出样例:
int[] arr = new int[]{8,3,2,1,0};
int[] index = new int[]{3,0,4,3,1,0,2,4,3,4,4};
代码实现:
#include<stdio.h>
int bubble_sort_and_del(int number[], int sz)
{
//排序
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (number[j] < number[j + 1])
{
int tmp = number[j];
number[j] = number[j + 1];
number[j + 1] = tmp;
}
}
}
//删除重复数字
int m = 1;
int n = 1;
for (m = 1; m < sz; m++)
{
if (number[m] != number[m - 1])
{
number[n] = number[m];
n++;
}
}
return n;
}
int index_find(int key, int number[], int len)
{
int i = 0;
for (i = 0; i < len; i++)
{
if (key == number[i])
{
return i;
}
}
}
int main()
{
char num[12] = { 0 };
gets(num);
int number[11] = { 0 };
int number2[11] = { 0 };
int i = 0;
for (i = 0; i < 11; i++)
{
number[i] = num[i] - '0';
number2[i] = num[i] - '0';
}
int len = bubble_sort_and_del(number, 11);
printf("int[] arr = new int[]{");
for (i = 0; i < len; i++)
{
printf("%d", number[i]);
if (i != len - 1)
{
printf(",");
}
}
printf("};\n");
printf("int[] index = new int[]{");
for (i = 0; i < 11; i++)
{
int index = index_find(number2[i], number, len);
printf("%d", index);
if (i != 10)
{
printf(",");
}
}
printf("};");
}
大致思路:
预备了解:
bubble_sort_and_del函数:将无序数组变成降序数组并删除重复数字
index_find函数:寻找匹配的下标
num数组:存储字符串形式的号码
number数组与number2数组:存储由字符串转变而来的号码
len:删除重复数字后的数组中的数字个数
下标m:遍历降序后的数组
下标n:记录要被存储非重复数字的空间位置
key:存储号码的一个数字
1. 将电话号码这一串数字一个个正序存入整型数组中,我们采用以下方法:
a. 将号码看成字符串,存入字符数组中,再将字符数组中的每一个数字字符转成字符
数字字符-'0'=数字
b. 将一个个数字字符转化而来的数字存入整型数组number中
考虑到number数组会进行降序排列并删除重复数字,使得电话号码发生改变
故而我们另外定义number2数组存储一份原原本本的电话号码,用以后面的下标与值匹配
2. 将number数组中的电话号码进行降序排列,并删除重复数字
我们交由自己编写的 bubble_sort_and_del函数实现
3. 按要求打印
需要在降序后且删除重复数字的number数组中,匹配电话号码一个一个数字的下标
交由 index_find函数实现
代码解读:
函数部分:
part 1:bubble_sort_and_del函数:返回降序排列并删除重复数字的数组中数字个数
int bubble_sort_and_del(int number[], int sz)
{
//排序
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (number[j] < number[j + 1])
{
int tmp = number[j];
number[j] = number[j + 1];
number[j + 1] = tmp;
}
}
}
//删除重复数字
int m = 1;
int n = 1;
for (m = 1; m < sz; m++)
{
if (number[m] != number[m - 1])
{
number[n] = number[m];
n++;
}
}
return n;
}
这里使用:
冒泡排序 (详解在我的另一篇博客,点击即跳转)
删除重复数字的双指针法:(详解在我的另一篇博客,点击即跳转,这里做粗略讲解)
删除重复数字,我们使用双指针法,即同时定义两个下标,指向同一个数组
way:a.使用双指针法删除重复数字的前提是数组有序(降序or有序)
我们已经在冒泡排序函数内部将数组排好序了
b. 排序后的number数组第一个元素一定不是重复数字,因为它是第一个出现的数字
故而我们要排查的范围和要被存储非重复数字的空间范围从第二个元素开始
下标m:遍历降序后(未删除任何一个元素)的number数组中的每一个数字
下标n:记录要被存储非重复数字的空间位置
m和n都最开始指向第二个元素,即m和n都初始化为1
c. 拿m指向的元素和它前一个的元素进行比较:
若是二者值相同:
则m此时指向的元素是重复数字,无需存入n指向的空间
然后m++,走向下一个元素进行下一轮判断,n不动因为此时n指向的空间尚未存入数字
若是二者值不同:
则m此时指向的元素不是重复数字,需要存入n指向的空间,存入数字后,n要指向下一个需要被存入非重复数字的空间,m++,走向下一个要是否为重复数字的元素,代码如下:
if (number[m] != number[m - 1])
{
number[n] = number[m];
n++;
}
d. 当m遍历数组结束后,n指向的每一个空间已经存入了非重复的数字,
此时n的值就是number数组删除重复数字后的数字个数
返回n
part 2:index_find函数:匹配号码的每一个数字在处理后number数组中对应的下标
int index_find(int key, int number[], int len)
{
int i = 0;
for (i = 0; i < len; i++)
{
if (key == number[i])
{
return i;
}
}
}
电话号码的每一个数字都要在经过降序删除重复数字处理后的number数组中去匹配对应的下标
主体部分:
part 1:将电话号码存入整型数组中
char num[12] = { 0 };
gets(num);
int number[11] = { 0 };
int number2[11] = { 0 };
int i = 0;
for (i = 0; i < 11; i++)
{
number[i] = num[i] - '0';
number2[i] = num[i] - '0';
}
先将电话号码以字符串的形式读取到字符数组num中,在将字符数组中的每一个数字字符转成数字并存入整型数组中
可能会有人问:为什么不直接让号码存入整型数组,而要经过字符转化成数字的形式?
答:这样做的优势是可以将电话号码正序存入整型数组中
part 2:打印第一行的输出
int len = bubble_sort_and_del(number, 11);
printf("int[] arr = new int[]{");
for (i = 0; i < len; i++)
{
printf("%d", number[i]);
if (i != len - 1)
{
printf(",");
}
}
printf("};\n");
len:接收处理后的number数组中的数字个数
如:原本存入number数组中的电话号码 18013820100
处理后变成: 8 3 2 1 0
part 3:打印第二行的输出
printf("int[] index = new int[]{");
for (i = 0; i < 11; i++)
{
int index = index_find(number2[i], number, len);
printf("%d", index);
if (i != 10)
{
printf(",");
}
}
printf("};");
index:接收与电话号码的每一个数字匹配的下标