24-简单结构体操作、一个数字超过数组长度一半、数组移动、找最长单词、冒泡排序、将十六进制数字转为十进制数字

项目:测试冒泡排序的优化是否有效,周三前交
rand():产生一个随机数字
共用体:也称为联合体,union.所有的成员共用同一段内存,共用低地址
大小端:考试的重点,你的笔试一定会出现
大端:低地址放大数据
小端:低地址放小数据
内存重叠
1.判断是不是闰年的标准方式:
year % 4 == 0 && year % 100 != 0 || year % 400 == 0

二、代码:

1.从主函数输入一个年月日,判断这天是当前这年的第多少天
typedef struct Date
{
	int year;
	int month;
	int day;
}Date;

//判断pd是当年的第几天
int GetDays(const Date *pd)//2021,1,1->1,如果实参不需要修改的话,需要加上const
{
	int days = 0;
	int arr[] = {31,28,31,30,31,30,31,31,30,31,30,31};//从一到十二月每月的天数

	//处理年
	if(pd->year%4==0 && pd->year%100!=0 || pd->year%400==0)//判断是不是闰年的标准方式
		arr[1] = 29;//闰年的二月是29天

	//处理月
	for(int i=0;i<pd->month-1;i++)//必须有-1,如果没有的话,如果日期为一月一日,那么结果就会为31(第一个月的天数)天
	{
		days += arr[i];
	}

	//处理天
	days += pd->day;

	return days;
}

int main()
{
	Date first = {2021,1,1};//1
	Date today = {2021,5,16};//136
	
	printf("%d\n",GetDays(&first));
	printf("%d\n",GetDays(&today));

	return 0;
}
2.简单结构体操作
typedef struct Student
{
	int num;//学号
	char name[20];
	int score[3];//三门课的成绩
}Student;

void Input(Student *arr,int len)//输出,总是传数组和数组的长度
{
	for(int i=0;i<len;i++)
	{
		scanf("%d%s%d%d%d",
			&arr[i].num,arr[i].name,&arr[i].score[0],&arr[i].score[1],&arr[i].score[2]);
	}
}

void Show(const Student *arr,int len)//打印
{
	printf("学生的信息如下:\n");
	for(int i=0;i<len;i++)
	{
		printf("%d,%s,%d,%d,%d\n",arr[i].num,arr[i].name,arr[i].score[0],arr[i].score[1],arr[i].score[2]);
	}
}

void Score(const Student *arr,int len)
{
	int sum1 = 0;//第一门课的总成绩
	int sum2 = 0;//第二门课的总成绩
	int sum3 = 0;//第三门课的总成绩

	int tmp = 0;//当前这个学生的总成绩
	int max = 0;//最高分的总成绩
	int index = 0;//最高分的下标

	for(int i=0;i<len;i++)
	{
		sum1 += arr[i].score[0];
		sum2 += arr[i].score[1];
		sum3 += arr[i].score[2];

		tmp = arr[i].score[0] + arr[i].score[1] + arr[i].score[2];
		if(tmp > max)
		{
			max = tmp;
			index = i;
		}
	}
	printf("三门课的平均成绩分别为:%d,%d,%d\n",sum1/len,sum2/len,sum3/len);
	printf("最高分的信息:%d,%s,%d,%d,%d,平均成绩%d\n",
		arr[index].num,arr[index].name,arr[index].score[0],arr[index].score[1],arr[index].score[2],
		max/3);
}

int majorityElement(int* nums, int numsSize){
    int cur = nums[0];
    int count = 1;
    for(int i=1;i<numsSize;i++) {
        if(count == 0) {//新的数字
            cur = nums[i];
            count = 1;
        }
        else if(cur == nums[i])
           count++;
        else
            count--;
    }
    return cur;
}

int main()
{
	Student arr[3];
	Input(arr,sizeof(arr)/sizeof(arr[0]));
	Show(arr,sizeof(arr)/sizeof(arr[0]));
	Score(arr,sizeof(arr)/sizeof(arr[0]));

	return 0;
}
3.数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字
算法:两个两个数相抵消,如果当前这个数和已保存的数相等,则count++,否则–,如果count为0,则直接把当前这个数拷贝到cur中,最后剩下的那个数就是出现次数最多的这个数
int majorityElement(int* nums, int numsSize)
{
    int cur = nums[0];
    int count = 1;
    for(int i=1;i<numsSize;i++) {
        if(count == 0) {//新的数字
            cur = nums[i];
            count = 1;
        }
        else if(cur == nums[i])
           count++;
        else
            count--;
    }
    return cur;
}

int main()
{
	int arr[] = {1, 2, 3, 2, 2, 2, 5, 4, 2};
	int a = majorityElement(arr,sizeof(arr)/sizeof(arr[0]));
	printf("%d\n",a);
	
	return 0;
}
4.数组移动
void Move(int *arr,int n,int m)
{
	assert(arr != NULL);
	if(arr==NULL || n<=0 || m<=0 || m>=n)
		return ;
	//创建m个长度的数组
	int *brr = (int *)malloc(m*sizeof(int));
	assert(brr != NULL);
	//将后面的m个数据拷贝到新数组
	int i;
	for(i=0;i<m;i++)
	{
		brr[i] = arr[n-m+i];
	}
	//将前面n-m个数字后移.注意移到数据的方向
	for(i=n-m-1;i>=0;i--)
	{
		arr[i+m] = arr[i];
	}
	//将新数组中的数字移到前面
	for(i=0;i<m;i++)
	{
		arr[i] = brr[i];
	}
	free(brr);	
}

int main()
{
	int arr[] = {1,2,3,4,5,6,7,8,9,10};
	Move(arr,sizeof(arr)/sizeof(arr[0]),3);
	Show(arr,sizeof(arr)/sizeof(arr[0]));

	return 0;
}
5.找最长单词
最后一个if的作用,比较最后一个单词是否为最长单词,如果是最长单词,则更新
har * MaxWord(const char *str)//"abc"
{
	//char curstr[50]; //存在越界的风险
	char *curstr = (char *)malloc((strlen(str)+1)*sizeof(char));
	char *maxstr = (char *)malloc((strlen(str)+1)*sizeof(char));
	assert(curstr!=NULL && maxstr!=NULL);
	int cur = 0;//curstr的长度
	int max = 0;//maxstr的长度

	while(*str != '\0')
	{
		if(isalpha(*str))
		{
			curstr[cur++] = *str;
		}
		else
		{
			if(cur > max)//更新单词
			{
				curstr[cur] = '\0';
				strcpy(maxstr,curstr);
				max = cur;
			}
			cur = 0;
		}
		str++;
	}
	if(cur > max)//最后判断一下最后一个单词长度是不是长于保存最长单词的长度
	{
		curstr[cur] = '\0';
		strcpy(maxstr,curstr);
		max = cur;
	}

	return maxstr;
}

int main()
{
	char *p = MaxWord("adf urtiw");//bug
	printf("%s",p);
	free(curstr);
	free(maxstr);

	return 0;
}
6.利用冒泡对整数数组进行排列
优化排序算法:创建一个标记,如果当前一趟没有交换,此时,就可以提前结束
void BubbleSort1(int *arr,int len)
{
	int tmp;
	for(int i=0;i<len-1;i++)
	{
		for(int j=0;j+1<len-i;j++)
		{
			if(arr[j] > arr[j+1])
			{
				tmp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = tmp;
			}
		}
	}
}

//优化冒泡
void BubbleSort(int *arr,int len)
{
	int tmp;
	bool flg;//标记是否有交换
	for(int i=0;i<len-1;i++)
	{
		flg = false;
		for(int j=0;j+1<len-i;j++)
		{
			if(arr[j] > arr[j+1])
			{
				tmp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = tmp;
				flg = true;
			}
		}
		if(!flg)//没有交换数据
		{
			return;
		}
	}
}

int main()
{
	int arr[] = {34,2,6,8,9,12,56,78,91,32,66,8,99,17,69};
	BubbleSort(arr,sizeof(arr)/sizeof(arr[0]));
	
	return 0;
}
7.将十六进制的字符串转为数字,遇到非十六进制字符,转换结束
int HexToi(const char *str)//"0x123","0X123","123","0x1a2","0x1A2","1a2","0x1z2"->1
{
	assert(str != NULL);
	int tmp = 0;

	if(str[0]=='0'&&str[1]=='x'||str[1]=='X')//跳过"0x"或者"0X"
		str += 2;
	while(isxdigit(*str))//是十六进制字符则循环继续
	{
		if(isdigit(*str))//*str在'0'~'9'
			tmp = tmp*16+(*str-'0');
		else if(islower(*str))//*str是小写字母
			tmp = tmp*16+ (*str-'a'+10);
		else 
			tmp = tmp*16+(*str-'A'+10);

		str++;
	}
	
	return tmp;
}

int main()
{
	int a = HexToi("0x12ab34x");
	printf("%d,%x\n",a,a);
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值