动态内存


动态内存

通过键盘输入二维数组的行和列,动态创建二维数组。实现下列函数功能
(1)动态创建二维数组。

  • unsigned char** new_array2d(unsigned int row, unsigned int column);

(2)释放二维数组。

  • void delete_array2d(unsigned char** array2d, unsigned int row);

(3)为二维数组随机赋值,每一个元素的值范围为 0 ~ 255。

  • void set_array2d(unsigned char** array2d, unsigned int row, unsigned int column);

(4)统计数组中的值分别为 0 ~ 255 的个数。
unsigned int* histgram(unsigned char** array2d, unsigned int row, unsigned int column);//返回unsigned int[256]数组表示统计结果

(5)打印数组。
void print_array1d(unsigned int array[],unsigned int n);//打印一维数组
void print_array2d(unsigned char** array2d, unsigned int row, unsigned int column);//打印二维数组

(6)根据给定的数组的左上角坐标、高、宽,取出子数组,下图所示。
unsigned char** get_sub_array(unsigned char** array2d, unsigned int row_index, unsigned int column_index, unsigned int height, unsigned int width);
在这里插入图片描述
(7)从所创建的二维数组中,按任意取出3x3的子数组,并将子数组的值转换为0-1值,即大于等于128的为1,小于128为0。

  • void gray_to_binary(unsigned char** array2d, unsigned int row, unsigned int column);

(8)对(7)所获得的 3x3 的二维数组,设每一个元素按顺时针顺序标注为a0,a1,a2,a3,a4,a5,a6,a7,a8共9个元素。现作如下处理:
在这里插入图片描述
a)数组四周元素与中间元素作异或运算(两个元素值相同为0,不同为1),即
a0 = a0 ^ a8; a1 = a1 ^ a8;……;a7 = a7 ^ a8;

b)四周元素与中间元素异或运算后,组成下列四种排列
a0,a1,a2,a3,a4,a5,a6,a7
a2,a3,a4,a5,a6,a7,a0,a1
a4,a5,a6,a7,a0,a1,a2,a3
a6,a7,a0,a1,a2,a3,a4,a5
将上面四种排列转换为十进制数,求这个四个十进制数的最小值。

  • unsigned int find_min_value(unsigned char** array2d);

  • 让我们一步一步了解、实现。

分步实现

(1)动态创建二维数组。

  • unsigned char** new_array2d(unsigned int row, unsigned int column);

①什么是 unsigned char
char:字符型用于储存字符,如英文字母、数字或标点。在 c/c++ 中 char 占一个字节八位。可以表示 -128 ~ 127 的数字。
unsigned:无符号。像 int,char 等数据类型储存数字时会取最后一位二进制码为符号位。无符号类型会将所有二进制码都用来储存数字,其全为正整数。(参考下表

数据类型储存范围
int-2147483648 ~ 2147483647
unsigned int0 ~ 4294967295
char-128 ~ 127
unsigned char0 ~ 255
  • 程序中目的是为了返回一个二级指针数组。

②什么是 new
new 其实就是告诉计算机开辟一段新的空间,但是和一般的声明不同的是,new 开辟的空间在堆上,而一般声明的变量存放在栈上。在局部函数中 new 出一段新的空间,该段空间在局部函数调用结束后仍然能够使用,可以用来向主函数传递参数。

  • 程序中先在堆区 new 一块 row 个 unsigned char* 空间(创建一个指针数组,
  • 后 new 一块 col 个 unsigned char (需要循环 new,为每一个指针后创长度为 col 的数组

③代码实现

unsigned char** new_array_2d(unsigned int row, unsigned int col){
	unsigned char** array_2d;
	//定义二重指针 array_2d 
	array_2d = new unsigned char*[row];
	//在堆区申请 row 个 unsigned char* 型空间 
	for(int i = 0; i < row; i ++){
		array_2d[i] = new unsigned char[col];
	}//在堆区申请 col 个 unsigned char 型空间 
	return array_2d;
	//返回在堆区 new 的二维数组 
}

(2)释放二维数组。

①什么是 delete
delete:用来释放new分配的单个对象指针指向的内存,
delete[]:用来释放new分配的对象数组指针指向的内存。

②代码实现

void delete_array_2d(unsigned char** array_2d, unsigned int row){
	delete[]array_2d;
	//释放 new 分配的对象数组指针 
}

(3)为二维数组随机赋值,每一个元素的值范围为 0 ~ 255。

①rand()函数
在 c 的头文件 #include <stdlib.h> 下
在 c++ 的头文件 #include <cstdlib.> 下(不加 . 打不出来,使用时删除

  • 调用一次 rand() 函数生成一个随机数
  • 样例生成 10 个随机数
#include <iostream>
#include <cstdlib>
using namespace std;
int main(){
	for(int i = 0; i < 10; i ++){
		cout << rand() << " ";
	}
    return 0;
}

②指定范围随机数
我们知道了如何生成随机数,那么如何生成指定范围的随机数呢
例如我们需要多个 123 到 456 之间的随机数
我们可以在获取一个随机数加上 123 后模上 456 即可得出要求范围内的随机数

③rand()函数真的随机吗?time() 函数和 srand() 函数是什么
在单使用 rand() 函数时我们会发现每次运行程序所产生的随机数是相同的,为什么会这样?这就要从 rand() 函数的实现原理来说了

  • rand() 函数的实现原理

rand的内部实现是用线性同余法做的,它不是真的随机数,而是一个伪随机数,是根据一个数(可称为“种子”)为基准以某个递推公式推算出来的一系数,当这系列数很大的时候,就符合正态公布,从而相当于产生了随机数,这不是真正的随机数,当计算机正常开机后,这个种子的值是定了的,除非你破坏了系统,为了改变这个种子的值,C提供了 srand()函数,它的原形是void srand( int a) 功能是初始化随机产生器既rand()函数的初始值,即使把种子的值改成a; 只不过是因为其周期特别长,所以有一定的范围里可看成是随机的,rand()会返回一随机数值,范围在0至RAND_MAX 间。在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。rand ()产生的是假随机数字,每次执行时是相同的。若要不同,以不同的值来初始化它.初始化的函数就是srand()。

所以在这时我们就需要 srand() 和 time() 函数来达到真随机

④代码实现

void randset_array_2d(unsigned char** array_2d, unsigned int row, unsigned int col){
	srand((unsigned int)time(0));//保证是真随机 
	for (int i = 0; i < row; i ++){
		for (int j = 0; j < col; j ++){
			array_2d[i][j] = rand() % 255;//生成指定范围内的随机数 
		}
	}
}

(4)统计数组中的值分别为 0 ~ 255 的个数。

unsigned int* histgram(unsigned char** array_2d, unsigned int row, unsigned int col){
	unsigned int *count = new unsigned int[256];
	for (int i = 0; i < 256; i++){
		count[i] = 0;
	}
	for (int i = 0; i < row; i ++){
	    for (int j = 0; j < col; j ++){
	        count[array_2d[i][j]] += 1;
		}
	}
	return count;
}

(5)打印数组。

打印一维数组

void print_array_1d(unsigned int* array_1d, unsigned int n){
	for (int i = 0; i < n; i ++){
		cout << array_1d[i] << " ";
	}
	cout << "\n";
}

打印二维数组

void print_array_2d(unsigned char** array_2d, unsigned int row, unsigned int col){
	for (int i = 0; i < row; i ++){
		for (int j = 0; j < col; j ++){
			printf("%3u ", array_2d[i][j]);
		}
		cout << "\n";
	}
}

(6)根据给定的数组的左上角坐标、高、宽,取出子数组

unsigned char** get_sub_array(unsigned char** array_2d, unsigned int row_index, unsigned int col_index, unsigned int height, unsigned int width){
	int row = 0, col = 0;
	unsigned char **array = new_array_2d(height, width);
		for (int i = row_index; i < row_index + width; i ++) {
		for (int j = col_index; j < col_index + height; j ++) {
			array[row][col] = array_2d[i][j];
			col ++;
			if (col == width) {
				col = 0;
				row ++;
			}
		}
	}
	return array;
}

(7)从所创建的二维数组中,按任意取出3x3的子数组,并将子数组的值转换为0-1值,大于等于128的为1,小于128为0。

void gray_to_binary(unsigned char** array_2d, unsigned int row, unsigned int col){
	srand((unsigned int)time(0));
	int row_index = rand() % ((int)row - 4);
	int col_index = rand() % ((int)col - 4);
	for(int i = row_index; i < row_index + 3; i++){
		for(int j = col_index; j < col_index + 3; j++){
			array_2d[i][j] >>= 7;
			//向右移七位相当于除上128 
		}
	}
}

(8)对(7)所获得的 3x3 的二维数组,设每一个元素按顺时针顺序标注为a0,a1,a2,a3,a4,a5,a6,a7,a8共9个元素

unsigned int find_min_value(unsigned char** array_2d){
	char n[8];
	for(int i = 0; i < 3; i ++){
		for(int j = 0; j < 3; j ++){
			if (i == 1 && j == 1) continue;
			array_2d[i][j] = array_2d[i][j] ^ array_2d[1][1];
		}
	}
	
	n[0] = array_2d[0][0]; n[1] = array_2d[0][1]; n[2] = array_2d[0][2];
	n[3] = array_2d[1][2]; n[4] = array_2d[2][2]; n[5] = array_2d[2][1];
	n[6] = array_2d[2][0]; n[7] = array_2d[1][0];
	int a = n[7] + n[6] * 2 + n[5] * 4 + n[4] * 8 + n[3] * 16 + n[2] * 32 + n[1] * 64 + n[0] * 128;
	int b = n[1] + n[0] * 2 + n[7] * 4 + n[6] * 8 + n[5] * 16 + n[4] * 32 + n[3] * 64 + n[2] * 128;
	int c = n[3] + n[2] * 2 + n[1] * 4 + n[0] * 8 + n[7] * 16 + n[6] * 32 + n[5] * 64 + n[4] * 128;
	int d = n[5] + n[4] * 2 + n[3] * 4 + n[2] * 8 + n[1] * 16 + n[0] * 32 + n[7] * 64 + n[6] * 128;
	if(a <= b && a <= c && a <= d) return a;
	if(b <= a && b <= c && b <= d) return b;
	if(c <= a && c <= b && c <= d) return c;
	return d;
}

最后代码

#include <bits/stdc++.h>
using namespace std;
unsigned char** new_array_2d(unsigned int, unsigned int);
//动态创建二维数组(长,宽) 
void delete_array_2d(unsigned char**, unsigned int);
//释放二维数组 
void randset_array_2d(unsigned char**, unsigned int, unsigned int);
//为二维数组随机赋值,每一个元素的值范围为 0 ~ 255
unsigned int* histgram(unsigned char**, unsigned int, unsigned int);
void print_array_1d(unsigned int*, unsigned int);
//打印数组 —一维 
void print_array_2d(unsigned char**, unsigned int, unsigned int);
//打印数组 —二维 
unsigned char** get_sub_array(unsigned char**, unsigned int, unsigned int, unsigned int, unsigned int);
//根据给定的数组的左上角坐标、高、宽,取出子数组
void gray_to_binary(unsigned char**, unsigned int, unsigned int);
//从所创建的二维数组中,按任意取出3x3的子数组(例如从位置(1,1)取3x3子数组),并将子数组的值转换为0-1值,即大于等于128的为1,小于128为0。
unsigned int find_min_value(unsigned char**);
//对(7)所获得的 3x3 的二维数组(下图所示),设每一个元素按顺时针顺序标注为a0,a1,a2,a3,a4,a5,a6,a7,a8共9个元素。现作如下处理:
int main(){
	unsigned int row, col;
	cin >> row >> col;//输入长宽 

	unsigned char** array_2d = new_array_2d(row, col);//创建 
	
	randset_array_2d(array_2d, row, col);//随机赋值 
	
	cout << "Oringin array" << endl;//原始阵列 
	print_array_2d(array_2d, row, col);
	//打印数组 —二维 
	
	unsigned int* hist = histgram(array_2d, row, col);
	cout << "Histgram" << endl;//组图 
	print_array_1d(hist, 256);
	unsigned char** sub_array_2d = get_sub_array(array_2d, 1, 1, 3, 3);
	cout << "Sub array" << endl;//子阵列 
	print_array_2d(sub_array_2d, 3, 3);
	gray_to_binary(sub_array_2d, 3, 3);
	cout << "Binary sub array" << endl;//二进制子阵列 
	print_array_2d(sub_array_2d, 3, 3);
	unsigned int min_value = find_min_value(sub_array_2d);
	cout << "The min value is " << min_value << endl;//最小值为 
	
	cout << "Now free memeory" << endl;//现在释放内存 
	delete_array_2d(array_2d, row);
	delete_array_2d(sub_array_2d, 3);
	delete [] hist;
	cin.get();
	return 0;
}

unsigned char** new_array_2d(unsigned int row, unsigned int col){
	unsigned char** array_2d;
	//定义二重指针 array_2d 
	array_2d = new unsigned char*[row];
	//在堆区申请 row 个 unsigned char* 型空间 
	for(int i = 0; i < row; i ++){
		array_2d[i] = new unsigned char[col];
	}//在堆区申请 col 个 unsigned char 型空间 
	return array_2d;
	//返回在堆区 new 的二维数组 
}

void delete_array_2d(unsigned char** array_2d, unsigned int row){
	delete[]array_2d;
	//释放 new 分配的对象数组指针 
}

void randset_array_2d(unsigned char** array_2d, unsigned int row, unsigned int col){
	srand((unsigned int)time(0));//保证是真随机 
	for (int i = 0; i < row; i ++){
		for (int j = 0; j < col; j ++){
			array_2d[i][j] = rand() % 255;
			//生成指定范围内的随机数 
		}
	}
}

unsigned int* histgram(unsigned char** array_2d, unsigned int row, unsigned int col){
	unsigned int *count = new unsigned int[256];
	for(int i = 0; i < 256; i++){
		count[i] = 0;
	}
	for(int i = 0; i < row; i ++){
	    for(int j = 0; j < col; j ++){
	        count[array_2d[i][j]] += 1;
		}
	}
	return count;
}

void print_array_1d(unsigned int* array_1d, unsigned int n){
	for(int i = 0; i < n; i ++){
		cout << array_1d[i] << " ";
	}
	cout << "\n";
}

void print_array_2d(unsigned char** array_2d, unsigned int row, unsigned int col){
	for(int i = 0; i < row; i ++){
		for(int j = 0; j < col; j ++){
			//cout << array_2d[i][j] << " ";
			printf("%u ", array_2d[i][j]);
		}
		cout << "\n";
	}
}

unsigned char** get_sub_array(unsigned char** array_2d, unsigned int row_index, unsigned int col_index, unsigned int height, unsigned int width){
	int row = 0, col = 0;
	unsigned char **array = new_array_2d(height, width);
		for(int i = row_index; i < row_index + width; i ++){
		for(int j = col_index; j < col_index + height; j ++){
			array[row][col] = array_2d[i][j];
			col ++;
			if(col == width){
				col = 0;
				row ++;
			}
		}
	}
	return array;
}

void gray_to_binary(unsigned char** array_2d, unsigned int row, unsigned int col){
	srand((unsigned int)time(0));
	int row_index = rand() % ((int)row - 4);
	int col_index = rand() % ((int)col - 4);
	for(int i = row_index; i < row_index + 3; i++){
		for(int j = col_index; j < col_index + 3; j++){
			array_2d[i][j] >>= 7;
			//向右移七位相当于除上128 
		}
	}
}

unsigned int find_min_value(unsigned char** array_2d){
	char n[8];
	for(int i = 0; i < 3; i ++){
		for(int j = 0; j < 3; j ++){
			if (i == 1 && j == 1) continue;
			array_2d[i][j] = array_2d[i][j] ^ array_2d[1][1];
		}
	}
	
	n[0] = array_2d[0][0]; n[1] = array_2d[0][1]; n[2] = array_2d[0][2];
	n[3] = array_2d[1][2]; n[4] = array_2d[2][2]; n[5] = array_2d[2][1];
	n[6] = array_2d[2][0]; n[7] = array_2d[1][0];
	int a = n[7] + n[6] * 2 + n[5] * 4 + n[4] * 8 + n[3] * 16 + n[2] * 32 + n[1] * 64 + n[0] * 128;
	int b = n[1] + n[0] * 2 + n[7] * 4 + n[6] * 8 + n[5] * 16 + n[4] * 32 + n[3] * 64 + n[2] * 128;
	int c = n[3] + n[2] * 2 + n[1] * 4 + n[0] * 8 + n[7] * 16 + n[6] * 32 + n[5] * 64 + n[4] * 128;
	int d = n[5] + n[4] * 2 + n[3] * 4 + n[2] * 8 + n[1] * 16 + n[0] * 32 + n[7] * 64 + n[6] * 128;
	if(a <= b && a <= c && a <= d) return a;
	if(b <= a && b <= c && b <= d) return b;
	if(c <= a && c <= b && c <= d) return c;
	return d;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值