3.2算法基本工具和优化技巧---算法与数据结构


1、原始信息与处理结果的对应存储

例题1(选票)

学校投票,有个候选人,编号分别是1、2、3、4、5选举一人,统计选票
void ballot() {
	int xp;
	int a[6] = {0};

	scanf_s("%d", &xp);
	while (xp != -1) {
		if (xp >= 1 && xp <= 5) {
			a[xp]++;
		}
		else {
			printf("输入错误!!!");
		}
		scanf_s("%d", &xp);
	}
}

例题2(统计身高)

编程统计身高,统计分为150-154,155-159,160-164,165-169,170-174,175-179,低于150,高于179
void statistics() {
	int high;
	int a[8] = {0};

	scanf_s("%d", &high);
	while (high != -1) {
		if (high > 179) {
			a[7]++;
		}else if (high < 150) {
			a[0]++;
		}else {
			a[high / 5 - 29]++;
		}
		scanf_s("%d", &high);
	}
	for (int i = 0; i < 8; i++) {
		printf("%d 等级有%d个人", i+1, a[i]);
		printf("\n");
	}
}

例题3(数组统计)

一次考试共考了语文、代数、外语3科,某小组共有9人,知道考后几个名单,找出三科全及格的人

用数组统计数值为3的人

2.数组使信息有序化

例题1(数字翻译英文)

将编号35701翻译成three-five-seven-zero-six
#include<stdio.h>
#include<string.h>

void translation() {
	int n;
	char num[40];
	char eng[10][6] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };

	printf("input a number:");
	scanf("%s", &num);
	n = strlen(num);
	for (int i = 0; i < n; i++) {
		printf("%c", num[i]);
	}
	
	if (n == 0) {
		printf("input error");
	}
	else {
		printf("翻译是:%s", eng[num[0] - 48]);
		for (int i = 1; i <= n - 1; i++) {
			printf("-%s", eng[num[i] - 48]);
		}
	}
}

void main() {
	translation();
}

例题2(找钱)

#include<stdio.h>

//x元的商品,给了y元
void change(int x, int y) {
	int money[7] = { 0, 50, 20, 10, 5, 2, 1 }, s[7] = {0};
	int balance;
	int num;

	balance = y - x;
	for (int i = 1; i <= 6; i++) {//6种钱
		num = balance / money[i];
		s[i] = num;
		balance -= num * money[i];
	}
	for (int i = 1; i <= 6; i++) {
		if (s[i] != 0) {
			printf("%d元----%d张\n", money[i], s[i]);
		}
	}
}

void main() {
	change(46, 100);
}

3.数组记录状态信息

例题1(求满足要求的x)

#include<stdio.h>
void qiuX() {
	long x, y1, y2;
	int p[10], t, k;

	for (int x = 10000; x < 32000; x++) {
		for (int i = 0; i < 10; i++) {
			p[i] = 1;
		}
		y1 = x * x;
		y2 = y1;

		k = 0;
		for (int i = 0; i < 10; i++) {
			t = y2 % 10;
			y2 /= 10;
			if (p[t] = 1) {
				k++;
				p[t] = 0;
			}else {
				break;
			}
		}
		if (k == 9) {
			printf("%d\n", x);
		}
	}
}


void main() {
	qiuX();
}

4.高精度数据存储及运算

将大数据存储在数组中,数据的每位可以占一个数组元素空间,也可以几位数字占一个数组空间
若要从键盘中输入高精度数据,可以使用字符类型,然后转换为数字,用ascii码

例题1(高精度数据 x 长整数)

#include<stdio.h>
#include<string.h>

void highPrecision() {
	long b, c, d;
	int a[256], n, i, j;
	char s[256];

	printf("输入高精度数字:");
	scanf("%s", &s);
	printf("输入相乘的数:");
	scanf("%ld", &c);

	n = strlen(s);
	d = 0;
	for (i = 0, j = n - 1; i < n; i++, j--) {
		b = (s[j] - 48) * c + d;	//b来计算每一位。最后一位 * c + 进位
		a[i] = b % 10;  //因为是10进制,才对10求余
		d = b / 10;    //b剩下的作为进位
	}
	while (d != 0) {	//最后的进位(可能大)(按位来)
		a[n] = d % 10;
		d = d / 10;
		n++;
	}
	for (i = n - 1; i >= 0; i--) {
		printf("%d", a[i]);
	}
}

void main() {
	highPrecision();
}
1、算法中没有独立进行字符串------>数字的转换,而是和运算同时进行的
2、按位运算,然后进位
3、d存储的进位可能很大(长整型范围之内),所以运算完,不能将d的值直接存入结果数组a中,
需要将d逐位存入结果数组不同的存储单元中,除非,将数组定义为“长整型”, 但是浪费空间

例题2(n!)

编程求当n <= 100时。n!的准确值
#include<stdio.h>
#include<string.h>

void highPrecision() {
	int i, j, r = 1;
	long a[256], b, d;
	int m = 1;	//m是结果的位数,一开始只有一个1,结果只有1位
	int n;
	printf("n!中的n:");
	scanf("%d", &n);

	
	for (i = 0; i < 256; i++) {
		a[i] = 0;
	}
	a[1] = 1;

	//运算
	d = 0;
	for (i = 2; i <= n; i++) {	//n-1个数,一个一个来
		for (j = 1; j <= m; j++) {
			b = (a[j] * i) + d;
			a[j] = b % 1000000;	//10e6进制,倒存入a
			d = b / 1000000;
		}
		if (d != 0) {
			a[j] = d;
			m++;
		}
	}
	/*
	//找到!=的最后一个
	for (i = m; i >= 1; i--) {
		if (a[i] != 0) {
			continue;
		}else {
			r = i;
			break;
		}
	}
	*/
	
	r = m;

	printf("n! = ");
	printf("%ld ", a[r]);
	for (i = r - 1; i >= 1; i--) {
		if (a[i] > 99999) {
			printf("%d ", a[i]);
			continue;
		}else if (a[i] > 9999) {
			printf("0%d ", a[i]);
			continue;
		}else if(a[i] > 999) {
			printf("00%d ", a[i]);
			continue;
		}else if (a[i] > 99) {
			printf("000%d ", a[i]);
			continue;
		}else if (a[i] > 9) {
			printf("0000%d ", a[i]);
			continue;
		}else{
			printf("00000%d ", a[i]);
			continue;
		}
		
	}
}

void main() {
	highPrecision();
}

5.构造趣味矩阵

例题1(打印方阵)

二维表(二维数组)的基本常识
	一般“外层循环控制行,内层循环控制列”
	用i代表行下标,用j代表列下标,则:
		主对角线元素:i=j;
		副对角线元素下标下界为1时i+j = n+1;下标下界为0时i+j = n-1
		主上三角元素:i <= j
		主下三角元素:i >= j
		次上三角元素:下标下界为1时i+j <= n+1;下标下界为0时i+j <= n-1
		次下三角元素:下标下界为1时i+j >= n+1;下标下界为0时i+j >= n-1
#include<stdio.h>

void print() {
	int i, j, a[100][100], n;
	scanf("%d", &n);
	for (i = 1; i <= n; i++) {
		for (j = 1; j <= n; j++) {
			if (i == j | i + j == n + 1) a[i][j] = 0;
			if (i + j < n + 1 & i < j) a[i][j] = 1;
			if (i + j < n + 1 & i > j) a[i][j] = 2;
			if (i + j > n + 1 & i > j) a[i][j] = 3;
			if (i + j > n + 1 & i < j) a[i][j] = 4;
		}
	}
	for (i = 1; i <= n; i++) {
		printf("\n");
		for (j = 1; j <= n; j++) {
			printf("%d ", a[i][j]);
		}
	}
}

void main() {
	print();
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值