c语言-数组中插入元素

1.前言

本文章仅为某高校大学生对于学习所得进行的理解与分享,如有错误请大胆批评指教(码子大学牲卑微跪谢)本代码为敝人在b站和学校等平台学习所得,如有侵权请联系作者。

2.代码部分

  2.1问题描述

本题目难点在于将不同的数插入到动态变化的数组中,即在每次插入后,数组中的数均会发生变化。因此需要将插入数这一部分封装成函数,将每次的插入用一个函数解决。

  2.2解题思想

在样例中,第一次是在数组的第2个和第3个数中间插入"5",那么只需要将元素"2,3,4"在数组中的位置向后移动一位,即将其下标增大1,然后赋值数组第2个数为"5"即可。同理,那么第二次将"6"插入到第3个与第4个数之间也可以使用相同的做法,只不过原来的数组发生了变化,从"1 2 3 4"变成了"1 5 2 3 4"。

那么问题就清晰化了:

1.将原数组中的部分元素下标增1。2.在数组中的指定位置赋值。3.将插入部分函数封装。

  2.3整体代码

​
#include<stdio.h>

void insert(int a, int b, int c, int n, int* s)//a为插入元素的位置,b为插入的元素,
                                               //c为第几次插入,n为初始数组中的元素个数
{
	int j;
	for (j = n+c; j >a; j--)
	{
		s[j] = s[j-1];
	}
	s[a] = b;
}

int main()
{
	int n, m,arr[100000],i,a,b;          //n为第一次输入数组的元素个数,m为此后插入元素的个数
	scanf("%d ", &n);
	for (i = 0; i < n; i++)
	{
		scanf("%d ", &arr[i]);
	}
	scanf("%d ", &m);
	for (i = 0; i < m; i++)
	{
		scanf("%d %d ", &a, &b);
		insert(a, b,i,n, arr);
	}
	for (i = 0; i <n + m; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

​

2.4main函数部分

因为对于插入的次数与初始数组元素的位置,那么就需要保证数组不会溢出,故将数组定义的足够大,当数组过于小时,就会出现无法满足所需解决能力的问题。

在第二个 for 循环中,我们首先输入a,b两数,然后调用 insert 函数。使用函数封装就可以有效避免单个函数过于冗杂与定义变量混淆不清等问题,同时在日常工作中,代码函数化也可以提高写完成项目的效率。

同时,针对代码的命名部分,在本文当中,我们所需要的函数功能为插入元素,因此对函数命名为"insert"(插入)。在我们的日常工作与学习中,函数功能命名法是最为普遍和有效的命名法,例如:判断是否为闰年的函数通常命名为"is_leap_year";判断是否为素数的函数命名为"is_prime"等,此类方法可以有效解决函数名称重复与函数功能不能快速识别等问题。(当然,不同的工程师与同学们的代码风格之间存在差异,有同学喜欢用女朋友的名字来命名函数也不是不可以(狗头保命哈哈哈哈))。

此外,虽然大家的代码风格大不相同,但是函数功能独立化是我们应该学习的一大重点。在main函数中,最终结果打印部分就没有封装在insert函数中,因为insert函数所起的功能仅仅为插入函数。若将打印部分封装到函数中就会出现功能冗余问题,在日常工作项目中,通常一个项目不是一个人能够完成的,需要几个工程师共同完成,此时就会需要不同的工程师写不同的函数,如果函数功能不独立化的话就非常影响工作效率与代码的解决能力,同时在日常的代码维护中也会出现阻碍。



int main()
{
	int n, m,arr[100000],i,a,b;        //n为第一次输入数组的元素个数,m为此后插入元素的个数
	scanf("%d ", &n);
	for (i = 0; i < n; i++)
	{
		scanf("%d ", &arr[i]);
	}
	scanf("%d ", &m);
	for (i = 0; i < m; i++)
	{
		scanf("%d %d ", &a, &b);
		insert(a, b,i,n, arr);
	}
	for (i = 0; i <n + m; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

​

​

2.5insert函数部分

首先在函数的参数中,a为插入元素的位置,b为插入的元素,c为所插入的次数,即main函数中的第二个for循环之中的i。

此前已经明确了所需要解决的问题:1.将部分元素后移   2.数组中指定位置赋值

在元素移动部分,我们采用倒序的方法,即从后面遍历到前面,从第n+1到n到a;在第一次元素移动中,需要将元素"2 3 4"向后移动,那么就从4开始向后移动,接着是3,最后才是2。

s[j]=s[j-1]

j--;

因此实现。

若采用顺序,就会出现问题,顺序即以下代码

for (j=a+1;j<n+c+a;j++)
{
  s[j]=s[j-1];
}

当使用了次方法时,就会发现所有应该移动的元素都变成了顺序的第一个元素了,这是因为在使用顺序方法时,由于 遍历是向前走的,第一个元素移动后,此后所有位置都等于前一个数,即第一个元素,即在次样例中,就是所有移动的数都等于2的情况。

​


void insert(int a, int b, int c, int n, int* s)//a为插入元素的位置,b为插入的元素,
                                               //c为第几次插入,n为初始数组中的元素个数
{
	int j;
	for (j = n+c; j >a; j--)
	{
		s[j] = s[j-1];
	}
	s[a] = b;
}

​

​

3.后言

在次代码中,本大学生觉得最重要的部分就是部分元素移动的问题了,是直接使用指针?还是使用数组的方式?还有就是移动的过程是用顺序移动还是倒序移动?二者会有 什么差别?这都是我们所需要思考的过程。

今天的分享就到这里啦,小编就是想通过这种方式把自己的思考过程与结果和大家分享分享,希望能更加提高自己的代码能力与表达基础,希望能下次再与大家见面

同时祝大家新年快乐,去岁千般皆如愿,今年万事定称心!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值