Tips on using arrays in C language

This may be the fourth tutorial on C language. It mainly talks about some usage of arrays.

1. Usage of array subscript records

First, let’s look at an example question. First, let’s look at an example question:

A very large community needs to count the number of people in the community. Given n ( 0<=n<=10000 ) people, we need to write a program to read in their ages ( <=120 ) and output their ages from small to large.

Idea: If there are 10,000 people, using array sorting may make the program freeze. After all, there are 10,000! times cycle. So we don't need to use arrays, so how do we count them. Take a look at the following code:

#include<stdio.h>

int main()
{
	int n , age[121]={0}, m;
	scanf("%d", &n);
	for (int i=0; i<n;i++)
	{
		scanf("%d", &m);
		age[m]++;
	}
	for (int i=0; i<120;i++)
	{
		int s = age[i];
		for(int h=0; h < s; h++)
		{
			printf("%d ", i);
		}
	}
	return 0;
} 

The running result is:

We use the subscripts of the array as ages and use them as containers to store the number of people. Finally, the age is output according to the value of the array from small to large. (The expression is not very clear...please look at the code more!)

Summary: This approach is used when there is no sequential relationship between the same elements (for example, all 18-year-olds are 18 years old, there are no other differences), and they can all be mapped to array subscripts through some kind of correspondence, and the goals are all able to Arranged in one direction (from the left to the right of the array, or from the right to the left).

2. Notation of arrays

1. -1 mark:

We are still led by an example:

There is a corridor with 12 extinguished lights arranged in a straight line, and n children will pass by, (0<N<=6). These n children are numbered 1, 2, 3... respectively. When the sequence number of the light they pass happens to be an integer multiple of their sequence number, the switch of this light must be pressed. Question: After n children pass by, how will the lights turn on and off.

Idea: Because the light has two states, either on or off. Then we can use an array to simulate the on and off conditions of the lights. So what method can be used to transform a number into two different values? That's multiple multiplications of -1.

Let’s take a look at the code: (If the code is not fully displayed, you can drag it left or right!)

#include<stdio.h>

int main()
{
	int n, map[13]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
	scanf("%d", &n);
	for(int i = 1; i <= n; i++)
	{
		for(int m=1;m<=12;m++)
		{
			if(m % i ==0)
			{
				map[m]=-1 * map[m];
			} 	
		}
	} 
	for(int m=1;m<=12;m++)
	{
		if (map[m]==1)
		{
			printf("亮");
		}
		else
		{
			printf("灭");
		}
	}
	return 0;
} 

This is relatively simple and doesn’t require much explanation. The effect is like this:

2. Conventional array notation

An array can save some data, but every data may not be useful. In other words, sometimes the array data does not necessarily need to be output, so we can open the same array again to mark whether the simulation outputs a certain element in the array. (Hehe, after learning arrays, you can start doing search questions 2333). I couldn't find any examples, so I had to use an exercise question to illustrate it (in fact, you don't have to write the code like this, but I just wanted to show the notation and I was too lazy to write a QAQ question)

Please look at the example: 10 available numbers are read from the keyboard and stored in an array. The user is required to enter from small to large. The total number of numbers is less than 20. If it is found that a certain number read is not from small to large, the input of the number is invalid (it is an unusable number), and the subsequent input data will continue to be read until 10 available numbers are read. Output two lines, the first line is the input number, and the second line is the ten available numbers.

Idea: Because we want to save the input numbers, we need an array to save these numbers, and then we also need an array, which can be a marked array, or directly an array of ten numbers to save the available numbers. Because it is to demonstrate this notation, I write the code using a marked array, please see: (Remember to read the code comments!)

#include<stdio.h>

int main(void)
{
	int map[22], mark[22], min, n1, tot, sum;    //最大为20个数,所以开22个保证不溢出
	
	scanf("%d", &map[0]);       //模拟第一次循环
	min = map[0];    //因为第一个min不手动读的话,循环里第一个min是没有初值的,所以要手动赋值
	mark[0] = 1;    //标记第一个数
	tot = 1;    //因为第一个已经读完了,所以sum,tot都有一个了
	sum = 1;
	while (tot < 10)    //一共十个数
	{
		scanf("%d", &map[sum]);    //读数
		mark[sum] = 0;    //将标记置为0,等待下一步if的修改,如果if没有改动,说明没有被标记
		if (map[sum] > min)
		{
			tot++;    //读到可用数,可用数+1否则会出现死循环
			min = map[sum];    //更新min,让下一个数可以比较
			mark[sum] = 1;     //标记做好=1
		}
		sum++;    //无论是否是标记数,数组里多了一个数,所以要更新数组的下标
	}
	printf("\n");    //这个是所有的数
	for (n1 = 0; n1 < sum; n1++)
	{
		printf("%2d ", map[n1]);
	}
	printf("\n");    //这个是标记数组的标记,为了便于比较
        for (n1 = 0; n1 < sum; n1++)
	{
		printf("%2d ", mark[n1]);
	}
        printf("\n可用数10个:");
	for (n1 = 0; n1 < sum; n1++)    //这个是输出可用数,还是要将整个数组遍历(全部跑)一遍
	{
		if (mark[n1] == 1)    //如果被标记,则输出!
		{
			printf("%d ", map[n1]);
		}
	}
	return 0;
}

Then here are the results:

You will find that only the number marked as 1 in the array is the output number.

Summary: This method is used to open an array and mark it to achieve the purpose of the operation without destroying the original data or the original array needs to be used multiple times.

3. Superposition judgment method (the name you choose is equivalent to finding the intersection QAQ)

This method is very clever. Let’s use a simple example to illustrate: For example, there are many people, including men and women. Some are named A, B, C, and D. Some are in high school and some are in elementary school. Then we think of each of these people as an array member, and then we need to find the number that meets the following conditions: female, college student, named Kang Na Meow. Then we can use three loops. The first loop is to determine whether these members are female. If they are female, it will be +1; the second loop is to determine whether these members are in college. If they are in college, it will be +1. Elementary school, etc., the value of the members remains unchanged; the third loop is to determine whether these members are called Kangna Meow, and if so, +1. So when we finish running all three cycles, the one with a value of 3 must be the female Kang Na Meow who is in college.

Then please look at the example question: Find the saddle point of any m×n matrix - the saddle point means that the element at that position is the largest in the row and the smallest in the column. There may be no saddle points in the matrix, but there is at most one saddle point. . m, n (2<=m<=20, 2<=n<=20) and matrix elements are input from the keyboard (only the int type and the case where there is no parallel maximum/minimum in each row and column are considered).

Analysis: This is an exercise question, which may be a bit difficult.

However, you have just read this quotation, so you should have an idea. Traverse each column and each row, and then give +1 to those that meet the conditions, so that the final output value is 2. (This method is easier to understand than the answer!)

So please look at the code:

#include<stdio.h>

int main(void)
{
	int xx, yy, x2, y2;    //xx,yy是读取的行列 x2y2是结果需要的坐标
	int map[21][21], mark[21][21];    //两个数组,一个是标记数组
	int x1, y1, min, max;    //x1 y1用于循环 min max是遍历行列时的比较大小时用的

	x2 = -1;    //因为要判断是否有鞍点,且(0,0)可能出现鞍点,所以要把xy2给赋值为-1
	y2 = -1;
	printf("Please input m and n:");
	scanf("%d %d", &yy, &xx);    //纵坐标为行 横坐标为列
	printf("Please input a juZhen(%d hang, %d lie):\n", yy, xx);
	for (y1 = 0; y1 < yy; y1++)    //这个循环是读入矩阵,并将所有的标记都置为0
	{
		for (x1 = 0; x1 < xx; x1++)
		{
			scanf("%d", &map[x1][y1]);
			mark[x1][y1] = 0;
		}
	}
	for (y1 = 0; y1 < yy; y1++)    //这个是遍历行中的最大值
	{
		max = 0;
		for (x1 = 0; x1 < xx; x1++)    //所以内层循环时,y坐标不变,x坐标变,所以外层用y,内层用x
		{
			if (map[x1][y1] > map[max][y1])
			{
				max = x1;
			}
		}
		mark[max][y1]++;    //一次标记
	}   
	for (x1 = 0; x1 < xx; x1++)    //这个是遍历列中的最小值 所以
	{
		min = 0;
		for (y1 = 0; y1 < yy; y1++)    //所以内层循环时,x坐标不变,y坐标变,所以外层用x,内层用y
		{
			if (map[x1][y1] < map[x1][min])
			{
				min = y1;
			}
		}
		mark[x1][min]++;    //一次标记
	}
	for (y1 = 0; y1 < yy; y1++)    //这个循环是记录鞍点的位置
	{
		for (x1 = 0; x1 < xx; x1++)
		{
			if (mark[x1][y1] == 2)
			{
				y2 = y1;
				x2 = x1;
			}
		}
	}    //其实里面可以直接输加出return的 可是学校的格式不让...

	if ( x2 >= 0)     //判断x2是否有改动,如果有改动,说明鞍点存在
	{
		printf("\nyou an dian, wei: juZhen[%d][%d]=%d\n", y2, x2, map[x2][y2]);
	}
	else    //如果x2=-1,说明标记数组里没有=2的数,所以没有鞍点
	{
		printf("\nmei you an dian.\n");	
	}
	
	return 0;
}

Okay, let's take a look at the results:


Wait, wait, wait, my God, you didn’t enter the number in your program! How come there is output?

How fat is that? That's what I'm going to talk about next.


It’s almost enough that we have mastered the four simple uses of our arrays, so let’s take a look at what else deserves our attention: (Haha, there are some tips here, only those who have the patience to see this should have them (๑• .•๑)!)

1. For array questions, there may be some large arrays. Is it troublesome to have to output them every time we debug? (It will be very tiring), so do we have any simple method? The answer is yes, absolutely. That's our freopen statement.

Let’s briefly talk about its usage: First, let’s remember these two lines of code: freopen("1.txt","r",stdin); freopen("1.txt","w",stdout); They all need to be put In the main function . So let me briefly analyze what their functions are: freopen(" 1.txt ","r",stdin); This statement reads data from 1.txt from the current C source code directory. In other words, you no longer have to manually enter data into the program! In the function, r represents read, stdin represents standard input; w represents write, and stdout is standard output. This way, you won’t remember the wrong code! . Among them, only the red part 1.txt can be changed. This is the file name of the file that saves the data. You can change it to messyguguchi.txt. Generally speaking, just adding stdin is enough. Because the output is displayed in the program and it is easier to observe. The question does not require saving the data to a file, so there is no need for stdout. And for the school system, you are just too lazy to write data again, so please delete freopen before you submit, otherwise you will get zero points! ! ! ! Remember, don’t say I harmed you.

2. When reading a string into an array, you do not need to add the address symbol &. Individual members still need to add the address symbol.

例如
    读入 Kanna
    我们有两种方式:
1.
int a[20];
scanf("%s",a);

2.基于freopen的操作
int main(void)
{
	char a[20],m=0;
	freopen("1.txt","r",stdin);
	while(scanf("%c", &a[m])!=0)
	{
		printf("%c ", a[m]);
		m++;
	}
	printf("YYY");
	return 0;
}

The results of the second method:

Let me show you another example and experience it for yourself: think about why this situation occurs!

你可以自己复制代码试试:
int main(void)
{
	char a[20]={0},m=0;
	scanf("%s", a);
	for (int i=0;i<3;i++)
	{
		printf("%d ",a[i]);
	}
	return 0;
}
输入123回车
输出49 50 51
-----------------
int main(void)
{
	char a[20]={0},m=0;
	scanf("%d",&a[0]);
	for (int i=0;i<3;i++)
	{
		printf("%d ",a[i]);
	}
	return 0;
}
输入123回车
输出123 0 0

So, there is a lot of nonsense, but in short, remember one thing: you don’t need to add & when reading a lot of things at one time. If you read it one by one, you need to add &.

3. Details of reading and output:

Sometimes the question requires us to read a, b, c, d, e. According to the urine properties of VC6.0, if you don't read the "," symbol, you will make an error! Then, we cannot read "%d," directly, because! There is no , after the last e. Through observation, we found that there are 5 numbers in total, 4 " ," bcde all have " , " in front of them. Then we manually read a into first, and then use ",%d" to loop into bcde.

In the same way, if we output a, b, c, e, f, then we will output "%d," for the first four, and the last one can manually output "%d"!


Well, this tutorial took a long time to write, I estimate it will take about 4 hours. Then the text I wrote for 40 minutes was lost due to network problems!

But fortunately, there is no faster shortcut in C language. Only by writing more, practicing more and thinking more can we reach an entry-level level like me with half a foot faster! >_< Therefore, if you find an error in this article, please contact me and we will discuss it together.


Thank you everyone for reading, no, you should be the ones thanking me for writing! If you have a chance, see you next time!

 

Guess you like

Origin blog.csdn.net/u011017694/article/details/84763815