物联网技术部&秘书部第一次软件培训总结

物联网技术部&秘书部第一次软件培训总结

一、二维数组

1.定义

类型说明符 数组名 [常量表达式1] [常量表达式2]

float a[3][4];

数组中的元素为:
a[0][0] a[0][1] a[0][2] a[0][3]
a[1][0] a[1][1] a[1][2] a[1][3]
a[2][0] a[2][1] a[2][2] a[2][3]

2.初始化

int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; 
int a[3][4]={{1},{0,6},{0,0,11}}; 
int a[3][4]={1,2,3}; 
int a[ ][3]={{1},{2},{3,4,5}};      //即 a[3][3] 
int a[ ][3]={1,2,3,4,5};            //即 a[2][3]

注意: 下标不能越界!

3.引用

数组名[常量表达式1][常量表达式2]

	//示例:
	b[1][2] = a[2][3]/2

4.应用

请设计一个程序,将一个4行4列的二维数组中行和列元素互换,并存放到另一个数组中。

小代码示例

    //C语言

#include<stdio.h>
int main(){
	int a[4][4] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14};
	int t;
	for (int i=0; i < 4; i++) {
		for (int j = 0; j < 4; j++) 
			printf("%3d", a[i][j]);
		printf("\n");
	}
	for (int i = 0; i < 4; i++) 
		for (int j = i + 1; j < 4; j++) {
			t = a[i][j];
			a[i][j]=a[j][i] ;
			a[j][i] = t;
		}
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) 
			printf("%3d", a[i][j]);
		printf("\n");
	}
return 0;
}
  //  C++
  
#include<iostream>
#include<iomanip>
using namespace std;

int main(){
	int a[4][4] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14};     
	int t;
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) 
			cout << setw(3) << setfill(' ') << a[i][j];
		cout << endl;
	}
	for (int i = 0; i < 4; i++) 
		for (int j = i + 1; j < 4; j++) {
			t = a[i][j];
			a[i][j]=a[j][i] ;
			a[j][i] = t;
		}
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) 
			cout << setw(3) << setfill(' ') << a[i][j];
		cout << endl;
	}
	return 0;
}

二、指针

1.概念

变量的值: 变量所代表的内存单元中的内容
变量的地址: 该变量所占存储单元的首地址
指针: 一个变量的地址,一个内存单元的地址,通常是一个无符号整数
指针变量: 存放变量地址的变量

2.定义与使用

类型说明符 *变量名

int *i_pointer , i=10; 
i_pointer=&i; 
printf(“%d”,*i_pointer);

说明: * 解引用 & 取地址符

小代码示例:

int main(){
	int i = 10;
	int *p;
	*p = i;          //危险!
	printf("%d", *p);
	return 0;
}

注意: 指针变量必须先赋值,再使用!

3.指针与一维数组

1)一维数组的地址

在这里插入图片描述

2)关系

	int a[10], *pa; 
	pa=a; pa =&a[0];  //等价

引用一个数组元素,有3种方法:
1)下标法: a[ i ]
2)数组名地址法: * (a+i )
3)指针法:
①指针地址法: * (pa+i )
②指针下标法: pa[ i ]

4.指针与多维数组

1)多维数组的地址

在这里插入图片描述
int a[3][4]={0};

a代表二维数组首行的首地址,记作a[0]或&a[0][0](现在的首元素不是一个简单的整型元素,而是由4个整型元素所组成的一维数组)
同理a+1为序号为1的行的首地址,记作a[1]==&a[1][0]
那1行1列的元素的地址? a[1]+1

2)关系

指向数组元素的指针变量

int a[3][4]={0};
int *p;
p = a[0];
p++;                    //p可以向下移动,依次指向下一个元素

指向数组的行指针变量

int a[3][4]={0};
int (*p)[4];
p = a;
a[i][j] == *(*(p+i)+j)

5.多级指针

如果指针变量中存放的是另一个指针变量的地址,就称该指针变量为指向指针的指针变量,也称为二级指针。

数据类型 **变量名

	int i=10,*ptrch=&i; 
	int **pp=&ptrch; 

6.malloc动态分配

void *malloc(unsigned int size);

int a[n];   !错误

int *a=(int *)malloc(n*sizeof(int));
//或
#define N 100
int a[N]

7.指针小应用

用指针改写二维数组中的矩阵转置

int *p=a;
int (*q)[4]=a;
a[i][j] = p[i*n+j] = *(p+(i*n+j));
a[i][j] = q[i][j] = *(*(q+i)+j);

三、函数

1.定义与声明

定义
类型名 函数名(形参表)
{
声明部分
执行语句
}

声明
类型名 函数名(形参表);

2.递归函数

如果一个函数在其函数体中直接或者间接地调用了自己,则该函数称为递归函数。
直接调用自己为直接递归;间接调用自己为间接递归

图解如下:
在这里插入图片描述

1)从数学角度看递归

例如
等差数列:
首项,即第一项的值a1;
递推公式,即连续项间的关系(an = an-1 +9)

当调用a(n)即执行a(n-1)+9,同时调用a(n-1)即a(n-2)+9……这样一直下去,最后到首项时,不再调用函数,直接返回数值。此时一路反向加回去,结束递归。

图解如下:
在这里插入图片描述

2)递归的注意点

1)结束条件:递归需要有明确的终止条件(首项)
2)逼近过程:处理好问题和子问题之间的关系,使得每次递归调用都要逼近终止条件
3)初始参数:调用递归函数的参数

3)递归的应用

1.请设计一个程序,利用递归求n!

小代码示例:

    // C语言
    
#include<stdio.h>
int multiple(int n) {
    if (n == 1) 
        return 1;
    else 
        return n*multiple(n - 1);
}

int main() {
    int n,m;
    scanf("%d", &n);
    m = multiple(n);
    printf("%d", m);
    return 0;
}
  //  C++
  
#include<iostream>
using namespace std;
int multiple(int n) {
	if (n == 1) {
		return 1;
	}else {
		return n*multiple(n - 1);
	}
}
int main() {
	int n,m;
	cin >> n;
	m = multiple(n);
	cout << m;
	return 0;
}

2.有一对兔子,从出生后第三个月起每个月都生一对兔子,小兔子长到第三个月后,每个月又生一对兔子。假设兔子都不死,问第20个月的兔子的对数为多少

小代码示例

    //	C语言

#include<stdio.h>

int birth(int n) {
	int result;
	if (n == 1)
		result = 1;
	else if (n == 2)
		result = 1;
	else if (n == 3)
		result = 2;
	else
		result = birth(n-1)+birth(n-3);
	return result;
}

int main()
{
	int n,x;
    scanf(“%d”,&n);
    x=birth(n);
    printf(“%d”,x);
    return 0;
}
      //  C++

#include<iostream>
using namespace std;

int birth(int n) {
	int result;
	if (n == 1)
		result = 1;
	else if (n == 2)
		result = 1;
	else if (n == 3)
		result = 2;
	else
		result = birth(n-1)+birth(n-3);
	return result;
}

int main()
{
	int n,x;
	cin >> n;
	x=birth(n);
	cout << x;
	return 0;
}

3.函数的优缺点

函数用于包装一些代码片段,使得他能够方便的被重复使用。
函数主要有以下的几个优点:
1)函数是实现代码重用的一种方式
2)友好的函数名字便于传达代码的含义
3)函数会简化代码的实现,使思路更清晰
同时,函数主要也有以下的几个缺点:
1)调用函数会时间和空间的消耗
2)递归函数拥有栈溢出的风险

四、OJ小技巧

1.关于输入问题

1)做题的时候尽量使用scanf printf。cin cout比scanf printf慢20倍左右,一旦遇到大数据量,光是读入就有可能跪掉。
2)scanf和cin混用可能就会造成一些奇怪的错误。
3)关于输入多组数据

#include <stdio.h>
int main(){   
	int input;    
	while(scanf("%d",&input) != EOF) {   
		//在此处理数据        
		printf("%d\n",input);    
	}    
	return 0;
}

还可以:
while( ( scanf(“%d”,&a) ) != -1 )
while( ( scanf(“%d”,&a) ) == 1 )
while( ~( scanf(“%d”,&a) ) )
while(cin>>a) //C++

读到一个0时,程序结束,可用:
while( scanf(“%d”,&a) ,a)
while( scanf(“%d”,&a) &&a!=0)
while (cin>>i,i) //C++

2.关于输出格式(presentation error)

1)行末空格:比如我输出需要打印多个数需要使用空格分隔的时候,我们循环使用printf(“%d “,x);这种会很方便,但是这样会导致行末多一个空格,后台系统会严格比对你的输出和.out文件,这样也会被判错误
2)换行问题:对于每个样例,建议输出完全之后都换行一下。对于一些题目,可能就是不换行就导致了后面输入数据错位,那就肯定不可能过了。
3)大部分题处理一组数据后可直接输出,不需要用数组保存每一个Case的数据。

3.关于数组问题

1)数组定义int a[10]={0};可以对其全部元素赋值为0;但是数组太大不要这样。
2)定义数组时,数组大小最好比告诉的最大范围大一点。
3)字符数组大小必须比字符串最大长度大1。
4)处理字符数组时不要忘了在最后加’/0’或者0。

4.关于Runtime error

1)下标越界
2)要表示的数值太大,超出了定义类型数的范围。
3)未赋值的变量就直接使用
4)在无限递归或函数里使用了太大的数组变量
!一定要好好排查,不仔细一般找不出来。

5.关于字符串

1)纯字符串用puts()输出,会增快速度。
2)先用scanf(),再用gets()会读入回车。要使用getchar()吸收空格和回车的录入。
!使用c语言读字符和字符串一定要十分小心。尽量写好就自己输出一下看看是否是自己需要的值被读入。

6.总结

1)输入输出是不是按照题意进行的。
2)是不是有些步骤没有完成。
3)对于边界输入的检查
4)算法的复杂度是不是过高
牢记:
代码不通过肯定是自己哪里出了什么问题,检查代码!再三看题读懂题意!!!

7.OJ小例题

输入
输入包含多个测试用例。每个测试用例以数字N开始(0 < N <= 1000)——分布的气球总数。接下来的N行每一行都包含一种颜色。气球的颜色是由15个小写字母组成的字符串。
输出
对于每一种情况,打印气球颜色最流行的问题在一行。保证每个测试用例都有唯一的解决方案。
sample input:
orange
orange
pink
red
blue
sample
output:
orange

代码小示例:

#include <stdio.h>
#include <string.h>
main(){
    int n, i, j, t, max, num[1000];
    char color[1000][16];
    while(scanf("%d", &n) != EOF){
        if(n){
            num[0]=0;
            scanf("%s", color[0]);
            for(i=1; i <n; i++){
                num[i]=0;
                scanf("%s", color[i]);
                for(j=0; j <i-1; j++)
                    if(strcmp(color[i], color[j])==0) num[i] +=1;
            }
            max=num[0];
            t=0;
            for(i=1; i <n; i++)
               if(max <num[i]) {max =num[i]; t=i;}
            printf("%s\n",color[t]);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/NOTFOUND_Liu/article/details/83713281