结构体与运算符重载(附赠重载高精度加法)

听作者讲骚话

无fuck说
等等,大家来看看,这是不是真的:

std::ios::sync_with_stdio(false);

教练大大说这关闭同步是骗你的
[手动滑稽][手动滑稽][手动滑稽][手动滑稽][手动滑稽]
别听我这么说你就不用[手动滑稽]

cin大法好cin大法好cin大法好cin大法好cin大法好cin大法好cin大法好cin大法好cin大法好cin大法好cin大法好
关闭同步大法好关闭同步大法好关闭同步大法好关闭同步大法好关闭同步大法好关闭同步大法好

我用scanf呵呵

什么是结构体

带过一下一些基础问题。
这是一个很高级的问题。啊,名字上很高级。
结构体其实就是一个自定义类型的变量,就是你自己创建的一个变量。C++给你提供的基本变量比如int,char,string,double,然而,我们可以创设自己的专属变量。好吧,我举一个更浅显易懂的例子:假设你想要记录一个美女的信息,我们可以创建一个名字为美女的结构体:beauty(允许我骚)
那么这结构体就是你创建的一个新的变量啦!
这个变量里会有几个成员,每一个成员记录着身高,体重,颜值这些都可以用int类型变量来表示,长发还是短发可以用bool类型表示,假设true就是长发,false就是短发。
那么这个结构体就可以表示为:

struct beauty{
	int height,wight,yanzhi;  //英语烂,原谅我
	bool long;
};

这很简单,难道不是么…
然而我们怎么访问里面的成员呢,我们是不是要先定义一下这个结构体?(如果一个变量都没有定义,你咋使用)这个定义的语法就是struct+结构体名字+结构体变量名字
比如我现在要定义一个类型为beauty的结构体girl。

struct beauty girl;

这就是一个结构体变量了。
当然,作者书写结构体的时候往往会嫌烦…他并不想写什么struct
所以,定义结构体的时候带上一个typedef就好了。
例如

typedef struct beauty{
	int height,wight,yanzhi;  //英语烂,原谅我
	bool long;
};

则定义的时候就可以酱紫:(仅仅书写结构体名)

beauty girl;

“捆绑”排序

我其实在学最小生成树的克鲁斯卡尔算法的时候,(或者说你按捺不住鸡冻的心情想看看克鲁斯卡尔算法的话,来看看我写的这篇——克鲁斯卡尔算法)我记得需要把边按照边权大小进行排序,这个就是应用一个贪心的思想。然而你给边排序的时候不可能就那么丢到一个sort里面吧(sort是一个位于algorithm里面的函数,可以对一个数组里面的数进行排序,默认升序,复杂度O(nlogn))。如果你就这么扔到一个sort里面,你到时候又该如何标记你取的位于数组头部的边(最小边权)是那一条呢?
当然,你如果没学过克鲁斯卡尔算法,建议看一看,这还挺重要,然后你就可以理解我上面说的话。
好吧,抛开克鲁斯卡尔不管,我们话归正题吧。
啥是捆绑排序?这其实就是我自己随便取的名字,然而很生动。其实就是将二元组
{2,1}{1,2}{5,3}{3,4}{9,5}{6,6}
根据前面那一个元素来排序(后面的跟着前面的动)。那么排序的结果就会是
{1,2}{2,1}{3,4}{5,3}{6,6}{9,5}
好像后面的元素被前面的绑在了一起进行排序。
这里提供一种很简单的办法,就是写一个cmp函数扔到sort里面。

bool cmp(node a,node b){
	return a.x<b.x;
}

假设我们定义了一个酱紫的结构体:

struct node{
	int x,y;
}d[maxm];

这后面的东西**d[maxm]**就是说定义了一个长度为maxm的结构体数组。
接下来直接使用这个就结束了。

sort(d+1,d+n+1,cmp);

有一些很sao的人会问(其实就是我
如果里面不止一个y,还有什么**char a[520],string b[520]**肿么办???
告诉你,也是这么办,不过是结构体里多了一些成员而已!

因为你问了这个问题,那么就很有必要让你知道为什么这样就是合法的。
首先你无非就是根据成员x进行排序,那么使用这个cmp函数并添加在sort里面,其实就是告诉sort要根据这个cmp函数来比较。
又有一些sao到不行的人会问(其实还是我
你这个**return a.x<b.x;**是什么鬼写法?
其实这个鬼写法等同于下面的写法(这个再看不懂好好回去学函数吧)

bool cmp(node a,node b){
	if(a.x<b.x) return true;
	return false;
}

大家知道一个结构体里有许多成员,所以是无法直接比较结构体谁大谁小的,这个函数其实就是把比较的依据锁定为x成员,只有 a.x<b.x,那么才算结构体a小于结构体b。

运算符重载和结构体初始化函数

说真的这个东西我今天才学会。
集训的教练“霍金”(因为爱坐这电脑椅在机房滑来滑去而且比我还sao)不教我重载运算符…作者表示很生气。当然了我凭着一己之力学会了它。
我好伟大啊
学会了才发现这明明死简单的为什么我不会…而且还要天天看霍金插手长啸:*ε=(´ο`)))**唉你们结构体学得太浅

运算符重载其实就是重新定义运算符的含义。
比如,你可以做一件很无聊的事情,就是把大于号的功能改成小于号的功能…
没事,我现在带你无聊一下。

typedef struct node{
	int a;
	node(){a=0;return;}
	bool operator > (const node &x)const{
		if(a<x.a) return true;
		return false;
	}
}; 

我在结构体里设置了一个初始化函数,初始化函数必须要以结构体的名字命名,而且不能写成void什么的,里面主要写一些赋值操作然后return。当然你可以写一些奇奇怪怪的操作甚至调用外部变量。这里就是把a初始化为0而已。
下面这个是重载函数。
bool是函数类型声明,说明了函数的返回值,为什么要写成布朗类型的返回值,原因就类似我们刚刚讲的cmp函数。operator是一个标志,说明这是重载函数。
“>”符号是我们被重载的运算符,这个被重载的运算符仅仅在结构体比较大小的时候才会生效,其他时候大于号还是大于号。
(const node &x),const是常量标识符,代表和当前结构体比较的结构体在比较时是一个确定的值,node不解释…&x中的&不是取地址的意思,而是引用。就是指引用和当前结构体比较的结构体到这个函数里来。类似于写函数时的形式参数(其实这个就是啊)
最后的const不用理他,这就像operator一样都是必须写的东西,没有为什么
函数的内容就是当这个结构体里的a比当前结构体比较的结构体的a要小时,反而是true,否则反而是false
接下来,我们这样写:

cin>>m.a>>n.a;
	if(m>n) cout<<"1";
	else cout<<"2";

程序的运行结果是1,重载成功。
实现捆绑排序也是很简单的,代码如下

typedef struct node{
	int a,b;
	node(){a=0;return;}
	bool operator < (const node &x)const{
		if(a<x.a) return true;
		return false;
	}
}; 

事实上这个跟重载大于号几乎一摸一样,这个只是没有改变其运算规则而已。

接下来做一些有水平的运算符重载。
这是高精度加法,这里我重载了加法运算符,可以直接输入数字然后相加。
最后你自己把结果打印到屏幕上就好了。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxm=100001;
int t[maxm],lenc;
typedef struct node{
	char a[maxm];
	node(){memset(a,0,sizeof(a))memset(t,0,sizeof(t));lenc=0;return;}
	bool operator + (const node &x)const{
		int lena,lenb,m[maxm],n[maxm];
		lena=strlen(a);lenb=strlen(x.a);
		lenc=max(lena,lenb); 
		for(int i=lenc,j=lena-1,k=lenb-1;i>=1;i--,j--,k--){
			if(a[j]) m[i]=a[j]-'0';
			if(x.a[k]) n[i]=x.a[k]-'0';
		}bool flag=0,f=0;
		for(int i=lenc;i>=1;i--){
			if(m[i]+n[i]+flag>=10){
				if(i==1){
					t[i]=m[i]+n[i]+flag-10;
					t[0]=1;
					return true;
				}
				t[i]=m[i]+n[i]+flag-10;
				flag=1;
			}else{
				t[i]=m[i]+n[i]+flag;
				flag=0;
			}
		} 
		return false;
	}
};
node p,q;

int main(){
	std::ios::sync_with_stdio(false);
	int g;
	cin>>p.a>>q.a;
	for((p+q)?g=0:g=1;g<=lenc;g++)
		cout<<t[g];
	return 0;
}

#####################################################################################

后期更新内容

新鲜出炉,戳我继续!

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值