Week 10

10.1 结构

结构

用户自定义的数据类型

struct 结构名
{
类型名 成员变量名;
类型名 成员变量名;
类型名 成员变量名;
……
};

例:

struct Student {
unsigned ID;
char szName[20];
float fGPA;
};

Student 即成为自定义类型的名字,可以用来定义变量

 Stuent s1,s2; 
  • 两个同类型的结构变量,可以互相赋值。但是结构变量之间不能用
    “==”、“!=”、“<”、“>”、“<=”、“>=”进行比较运算。
  • 一般来说,一个结构变量所占的内存空间的大小,就是结构中所有成员变
    量大小之和。结构变量中的各个成员变量在内存中一般是连续存放的,
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

访问结构变量的成员变量

在这里插入图片描述

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

struct Date {
	int year;
	int month;
	int day;
};

struct StudentEx {
	unsigned ID;
	char szName[20];
	float fGPA;
	Date Birthday;
};

int main()
{
	StudentEx stu;
	cin >> stu.fGPA;
	stu.ID = 12345;
	strcpy(stu.szName, "Tom");
	cout << stu.fGPA;
	stu.Birthday.year = 1984;
	unsigned int * p = &stu.ID;
}

小声BB:原来把我搞到云里雾里的结构竟如此简单?!

结构变量的初始化

  • 结构变量可以在定义时进行初始化
StudentEx stu = { 1234,"Tom",3.78,{ 1984,12,28 }};

结构数组

StudentEx MyClass [50];
StudentEx MyClass2[50] = {
{ 1234,"Tom",3.78,{ 1984,12,28 }},
{ 1235,"Jack",3.25,{ 1985,12,23 }},
{ 1236,"Mary",4.00,{ 1984,12,21 }},
{ 1237,"Jone",2.78,{ 1985,2,28 }}
};
MyClass[1].ID = 1267;
MyClass[2].birthday.year = 1986;
int n = MyClass[2].birthday.month;
cin >> MyClass[0].szName;

指向结构变量的指针

在这里插入图片描述
在这里插入图片描述

10.2 全局变量、局部变量

  • 定义在函数内部的变量叫局部变量(函数的形参也是局部变量)
  • 定义在所有函数的外面的变量叫全局变量
  • 全局变量在所有函数中均可以使用,局部变量只能在定义它的函数内部使用
  • 全局变量都是静态变量。局部变量定义时如果前面加了“static”关键字,
    则该变量也成为静态变量
  • 静态变量的存放地址,在整个程序运行期间,都是固定不变的
  • 非静态变量(一定是局部变量) 地址每次函数调用时都可能不同,在函数的一次
    执行期间不变
  • 如果未明确初始化,则静态变量会被自动初始化成全0(每个bit都是0),局
    部非静态变量的值则随机
  • 所有静态变量只初始化一次

静态变量示例

在这里插入图片描述

静态变量应用:strtok的实现

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int main()
{
	char str[] = "- This, a sample string, OK.";
	char *p = strtok(str, " ,.-");
	while (p)
	{
		cout << p << endl;
		p = strtok(NULL, " ,.-");
	}
	return 0;
}

在这里插入图片描述
这块看了好几次终于明白了,就是说先让指针走,跳过分隔字符,即:只要没走到\0并且字符都包含在sep里,则strchr返回值为1,即都是分隔字符,就一直++start,直到走到头或者遇到不是分隔字符的时候结束。下边就是判断如果是走到头儿了就return NULL,如果没有就说明是遇到了非分隔字符,此刻就将start指向的位置赋给指针q,指针q就指向非分隔字符,也就是我们需要的字符。之后,再跳过非分隔字符,即:只要指针没有走到头儿并且字符不在sep中,就一直++start,如果停下来并且没有走到头儿说明是遇到了分隔符号,即:如果*start不是0,那么将它赋值为0,也就是将分隔符号变为\0。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

char * Strtok(char * p, char * sep)	//p是指针,sep是分隔符
{
	static char * start;	//只在第一次的时候寻找start位置
	if (p)
		start = p;
	for (; *start && strchr(sep, *start); ++start);	//跳过分隔字符
	if (*start == 0)
		return NULL;
	char * q = start;	//q指向所需字符的第一个字符
	for (; *start && !strchr(sep, *start); ++start);	//跳过非分隔字符
	if (*start)
	{
		*start = 0;
		++start;
	}
	return q;
}

int main()
{
	char str[] = "- This, a sample string, OK.";
	char *p = Strtok(str, " ,.-");
	while (p)
	{
		cout << p << endl;
		p = Strtok(NULL, " ,.-");
	}
	return 0;
}

10.3 变量的作用域和生存周期

  • 静态局部变量的生存期,从定义它语句第一次被执行开始,到整个程序结束为止。
  • 函数形参的生存期从函数执行开始,到函数返回时结束。
  • 非静态局部变量的生存期,从执行到定义它的语句开始,一旦程序执行到了它的作用域之外,其生存期即告终止。

10.4 简单排序

选择排序

如果有N个元素需要排序,那么首先从N个元素中找到最小的那个(称为第0小的)放在第0个位子上(和原来的第0个位子上的元素交换位置),然后再从剩下的N-1个元素中找到最小的放在第1个位子上,然后再从剩下的N-2个元素中找到最小的放在第2个位子上……直到所有的元素都就位。

#include <iostream>
#include <cstdio>
using namespace std;

void SelectionSort(int a[], int size)
{
	for (int i = 0; i < size - 1; ++i)	//每次循环后将第i小的元素放好
	{
		int tmpMin = i;	//用来记录从第i个到第size-1个元素中,最小的那个元素的下标
		for (int j = i + 1; j < size; ++j)
		{
			if (a[j] < a[tmpMin])
				tmpMin = j;
		}
		//下面将第i小的元素放在第i个位子上,并将原来占着第i个位子的元素挪到后面
		int tmp = a[i];
		a[i] = a[tmpMin];
		a[tmpMin] = tmp;
	}
}

int main()
{
	int a[] = { 4,3,2,1 };
	for (int i = 0; i < 4; ++i)
		cout << a[i] << " ";
	SelectionSort(a, 4);
	for (int i = 0; i < 4; ++i)
		cout << a[i] << " ";
	return 0;
}

插入排序

  • 将整个数组a分为有序的部分和无序的两个部分。前者在左边,后者在右边。
  • 开始有序的部分只有a[0],其余都属于无序的部分
  • 每次取出无序部分的第一个(最左边)元素,把它加入到有序部分。假设插入到合适位置p, 则原p位置及其后面的有序部分元素,都向右移动一个位子。有序的部分即增加了一个元素。
  • 直到无序的部分没有元素
#include <iostream>
#include <cstdio>
using namespace std;

void InsertionSort(int a[], int size)
{
	for (int i = 1; i < size; ++i)	//a[i]是最左的无序元素,每次循环将a[i]放到合适位置
	{
		for (int j = 0; j < i; ++j)	//有序部分的下标是从0到i-1,目的是把a[i]插入到a[0]~a[i-1]
		{
			if (a[j] > a[i])	//要把a[i]放到位置j,原下标j到 i-1的元素都往后移一个位子
			{
				int temp = a[i];	//先记住这个值
				for (int k = i; k > j; --k)	//后移
					a[k] = a[k - 1];
				a[j] = temp;	//插入
				break;
			}
		}
	}
}

int main()
{
	int a[] = { 4,3,2,1 };
	for (int i = 0; i < 4; ++i)
		cout << a[i] << " ";
	InsertionSort(a, 4);
	for (int i = 0; i < 4; ++i)
		cout << a[i] << " ";
	return 0;
}

冒泡排序

  • 将整个数组a分为有序的部分和无序的两个部分。前者在右,后者在左边与插入排序相反)。
  • 开始,整个数组都是无序的。有序的部分没有元素。
  • 每次要使得无序部分最大的元素移动到有序部分第一个元素的左边。移动的方法是:依次比较相邻的两个元素,如果前面的比后面的大,就交换他们的位置。这样,大的元素就像水里气泡一样不断往上浮。移动结束有序部分增加了一个元素。
  • 直到无序的部分没有元素
#include <iostream>
#include <cstdio>
using namespace std;

void BubbleSort(int a[], int size)
{
	for (int i = size - 1; i > 0; --i)	//i右边的元素,i+1到size-1的元素已经排好序
	{//每次要将未排序部分的最大值移动到下标i的位置
		for (int j = 0; j < i; ++j)
		{
			//依次比较相邻的两个元素
			if (a[j] > a[j + 1])
			{
				int tmp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = tmp;
			}
		}
	}
}

int main()
{
	int a[] = { 4,3,2,1 };
	for (int i = 0; i < 4; ++i)
		cout << a[i] << " ";
	BubbleSort(a, 4);
	for (int i = 0; i < 4; ++i)
		cout << a[i] << " ";
	return 0;
}

简单排序的效率

上面3种简单排序算法,都要做 n2量级次数的比较(n是元素个数)! 好的排序算法,如快速排序,归并排序等,只需要做n*log2n量级次数的比较!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习是一种人工智能(AI)的子领域,致力于研究如何利用数据和算法让计算机系统具备学习能力,从而能够自动地完成特定任务或者改进自身性能。机器学习的核心思想是让计算机系统通过学习数据中的模式和规律来实现目标,而不需要显式地编程。 机器学习应用非常广泛,包括但不限于以下领域: 图像识别和计算机视觉: 机器学习在图像识别、目标检测、人脸识别、图像分割等方面有着广泛的应用。例如,通过深度学习技术,可以训练神经网络来识别图像中的对象、人脸或者场景,用于智能监控、自动驾驶、医学影像分析等领域。 自然语言处理: 机器学习在自然语言处理领域有着重要的应用,包括文本分类、情感分析、机器翻译、语音识别等。例如,通过深度学习模型,可以训练神经网络来理解和生成自然语言,用于智能客服、智能助手、机器翻译等场景。 推荐系统: 推荐系统利用机器学习算法分析用户的行为和偏好,为用户推荐个性化的产品或服务。例如,电商网站可以利用机器学习算法分析用户的购买历史和浏览行为,向用户推荐感兴趣的商品。 预测和预测分析: 机器学习可以用于预测未来事件的发生概率或者趋势。例如,金融领域可以利用机器学习算法进行股票价格预测、信用评分、欺诈检测等。 医疗诊断和生物信息学: 机器学习在医疗诊断、药物研发、基因组学等领域有着重要的应用。例如,可以利用机器学习算法分析医学影像数据进行疾病诊断,或者利用机器学习算法分析基因数据进行疾病风险预测。 智能交通和物联网: 机器学习可以应用于智能交通系统、智能城市管理和物联网等领域。例如,可以利用机器学习算法分析交通数据优化交通流量,或者利用机器学习算法分析传感器数据监测设备状态。 以上仅是机器学习应用的一部分,随着机器学习技术的不断发展和应用场景的不断拓展,机器学习在各个领域都有着重要的应用价值,并且正在改变我们的生活和工作方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值