c语言博客作业04--数组

| 这个作业属于哪个班级 | C语言--网络2011/2012 |
| ---- | ---- | ---- |
| 这个作业的地址 | C博客作业04--数组 |
| 这个作业的目标 | 学习数组相关内容 |
| 姓名 | 李雷默 |

0.展示PTA总分


1.本章学习总结

1.1 学习内容总结

1.1.1查找数据:7-2 查找整数

    int  n, x, i, j;
    int a[20];
    scanf("%d", &n);
    scanf("%d", &x);
    for (i = 0; i < n; i++)
{
	scanf("%d", &a[i]);
	}
    for (i = 0; i < n; i++)
{
	if (a[i] == x)
	{
	j = i; 
        break; 
        }
}

在实验7-2中,我输入了一个数组,分别表达了数组中的每一个数字,与我们要求查找的整数x进行比较,成功找出了与x相等的数字在数组中的位置。

1.1.2插入数据:7-6 简化的插入排序

while(a[i]<x&&i<n)
         i++;
	for (j=n-1;j>=i;j--)
	{
		a[j+1]=a[j];
	}
	a[i]=x;

略过前面的定义和常规的输入数组,插入数组的思路是找到想要插入的位置,通过a[j+1]=a[j]将该位置以后的数字右移一位,再将输入插入空出来的位置。

1.1.3删除数据:7-9 数组元素的删除

 for(int i = m-1; i < n; i ++)
        {
            a[i] = a[i + 1];
        }

数据的删除与插入同理,通过a[i] = a[i + 1]将想要的数字以后的数据左移一位,覆盖掉原本的数字,完成删除。

1.1.4排序方法:选择法排序和冒泡法排序

  • 选择排序算法的基本思想就是依次选出数组最小的数放到数组的前面,在C语言中我们可以使用两个for循环,先从数组的第二个元素开始往后遍历,找出最小的数放到第一个位置,再从剩下数组中找出最小的数放到第二个位置,以此类推,直到数组有序。

  • 冒泡排序的基本思想就是不断比较相邻的两个数,让较大的元素不断地往后移。经过一轮比较,就选出最大的数;经过第2轮比较,就选出次大的数,以此类推。

1.1.5:枚举用法:

 for (i = 0; i < n; i++)
{
	if (a[i] == x)
	{
	j = i; 
        break; 
        }
}

在1.1.1中呈现的查找整数就是用了枚举的思路,通过将数组中的每个数字枚举并与x比较完成查找。

1.1.6哈希数组用法:

#include<stdio.h>
int main()
{
    char sz;
    int i=0;
    int sl[128]={0};
    while((sz=getchar())!='\n')
    {
        if(sl[sz]==0)
        {
            sl[sz]=1;
        }
    }
    for(i=0;i<128;i++)
    {
        if(sl[i]==1)
        {
            printf("%c",i);
        }
    }
}

1.1.7字符数组、字符串特点及编程注意事项:

    • 字符串被存储在元素类型为 char 或宽字符类型数组中,用于 scanf() 时不用添加 & 。
  • 字符串是连续的字符序列,最后以空字符'\0'作为终止符。一个字符串的长度指所有字符的数量,但不包括终止符。

  • 存储字符串的数组一定比字符串长度多一个元素,以容纳下字符串终止符(空字符'\0')。

2.PTA实验作业

2.1 7-8 有重复的数据!

2.1.1伪代码:

static int b[100001];                       //用静态变量static将数组b初始化为0
for (i = 0; i < n; i++){                 
		scanf("%d", &a[i]);         //输入a[n]    
	b[a[i]]++;                          //统计每个数字出现过的次数
	if (b[a[i]] > 1){                   //出现次数大于1的为重复数据
	 printf("YES");
	 break;
    }

2.1.2 代码截图:

#include<stdio.h>
int main()
{
	int n, i;
	scanf("%d", &n);
    int a[100001];
    static int b[100001];
	for (i = 0; i < n; i++){
		scanf("%d", &a[i]);
	b[a[i]]++;
	if (b[a[i]] > 1){
	 printf("YES");
	 break;
    }
    }
	if (i == n)
		printf("NO");
	return 0;
}

2.1.3同学代码:

#include<stdio.h>
#define MAX 100001
int SameData(int n);
int main()
{
	int n;
	scanf("%d", &n);
	if (SameData(n))
	{
		printf("YES");
	}
	else
	{
		printf("NO");
	}
	return 0;
}

int SameData(int n)
{
	static int a[MAX];
	int i, data;
	for (i = 1;i <= n;i++)
	{
		scanf("%d", &data);
		if (a[data] == 1)
		{
			return 1;
		}
		else
		{
			a[data] = 1;
		}
	}
	return 0;
}

这位同学的代码定义了一个函数SameData,不仅清晰易读,而且不忘使用驼峰法命名,而我的代码思路是统计数字出现的次数,各有优劣。我的代码比较适用短短代码,而他的代码适合长代码。

2.2 7-14 找鞍点

2.2.1伪代码:

 int k=0,y=0,flag=1,p=0;  
    if(n==1)  
        printf("0 0");               //考虑特殊情况,一行一列满足鞍点
    else  
    {  
        for(i=0; i<n; i++)  
        {  
            y=i;  
            for(p=0; p<n; p++)
            {  
                if(a[i][k]<=a[i][p])  //条件1:在该列最小
                {  
                    k=p;               
                }  
            }  
            for(j=0; j<n; j++)
            {  
                if(a[y][k]>a[j][k])   //条件2:在该行最大
                {  
                    y=j;  
                    break;  
                }  
            }  
            if(i==y)                  //检索出鞍点
            {  
                flag=0;  
                break;  
            }  
        }  
        if(flag==0)  
            printf("%d %d",i,k);  
        else                            //没有检索出鞍点
	    printf("NONE");  
    }  

2.2.2 代码截图:

#include <stdio.h>  
int main()  
{  
    int a[6][6],n;  
    scanf("%d",&n);  
    int i,j;  
    for(i=0; i<n; i++)  
        for(j=0; j<n; j++)  
        {  
            scanf("%d",&a[i][j]);  
        }  
    int k=0,y=0,flag=1,p=0;  
    if(n==1)  
        printf("0 0");
    else  
    {  
        for(i=0; i<n; i++)  
        {  
            y=i;  
            for(p=0; p<n; p++)
            {  
                if(a[i][k]<=a[i][p]) 
                {  
                    k=p;  
                }  
            }  
            for(j=0; j<n; j++)
            {  
                if(a[y][k]>a[j][k]) 
                {  
                    y=j;  
                    break;  
                }  
            }  
            if(i==y)
            {  
                flag=0;  
                break;  
            }  
        }  
        if(flag==0)  
            printf("%d %d",i,k);  
        else 
			printf("NONE");  
    }  
    return 0;  
}  

2.2.3请说明和超星视频做法区别,各自优缺点。

我的思路与林老师大致相同,但没有定义函数,所以行数较少,但实际上,没有林老师简洁,例如我没有很好的方法来解决一行一列的情况,所以单独列出来,不过在判断条件:在该行最大这一行我认为我的代码比林老师的更容易理解,但也更冗长。
总之我的代码还有所欠缺,一些只能做到自己读懂,没办法做到简洁,在一些注释上也没有林老师详细,仍需学习。

2.3 7-6 切分表达式——写个tokenizer吧

2.3.1伪代码:

while (now != '\n') {
        if ((now == '(') || (now == ')') || (now == '*') || (now == '/')) {
            if (last != '\0') {                                           //如果不是第一个字符便换行后输出
                printf("\n");
            }
        }
        if (now == '-') {
            if (!(((last >= '0') && (last <= '9')) || (last == ')'))) {
                flag = 1;                                                 //如果上一个字符不是数字或右括号,则该-号为负号
            }
            if (last != '\0') {
                printf("\n");                                             //如果不是第一个字符便换行后输出
            }
        }
        if (now == '+') {
            if (last == '\0') {                                           //如果是第一个字符,则该+号为正号
                flag = 1; 
            }
            else {
                printf("\n");                                             //如果不是第一个字符便换行后输出
            }
        }
        if ((now >= '0') && (now <= '9')) {
            if (flag == 1) {                                              //如果上一个字符为正负号,则不用换行直接输出字符,并消除正负号标记
                flag = 0; 
            }
            else {                                                        //如果上一个字符不是正负号且不是数字、空字符以及小数点则换行后输出
                if (!(((last >= '0') && (last <= '9')) || (last == '\0') || (last == '.'))) {
                    printf("\n");
                }
            }
        }
        printf("%c", now);                                                //每读取一个字符便输出,前面的代码分析是否应该在输出字符前输出一个换行符\n

2.3.2 代码截图:

#include <stdio.h>
int main(void) {
    char last = '\0', now, flag = 0;
    now = getchar();
    while (now != '\n') {
        if ((now == '(') || (now == ')') || (now == '*') || (now == '/')) {
            if (last != '\0') {  
                printf("\n");
            }
        }
        if (now == '-') {
            if (!(((last >= '0') && (last <= '9')) || (last == ')'))) {
                flag = 1;  
            }
            if (last != '\0') {
                printf("\n");  
            }
        }
        if (now == '+') {
            if (last == '\0') {  
                flag = 1;
            }
            else {
                printf("\n");  
            }
        }
        if ((now >= '0') && (now <= '9')) {
            if (flag == 1) {  
                flag = 0;
            }
            else {  
                if (!(((last >= '0') && (last <= '9')) || (last == '\0') || (last == '.'))) {
                    printf("\n");
                }
            }
        }
        printf("%c", now);  
        last = now;
        now = getchar();
    }
    printf("\n");

    return 0;
}

2.3.3 请说明和超星视频做法区别,各自优缺点。

我的思路是每种情况运算数、运算符都列出来,较为繁琐,相比林老师清晰易懂的代码还有所欠缺。

posted @ 2020-12-13 22:05  a丶落雨未  阅读(97)  评论(0编辑  收藏  举报