通信系统仿真

崔春雷

目录

  • 1 第一单元: MATLAB基础
    • 1.1 课程说明与资料
      • 1.1.1 作业参考答案
      • 1.1.2 移动22级作业答案
    • 1.2 MATLAB安装与运行环境
      • 1.2.1 MATLAB介绍
    • 1.3 基本数据类型:数值类型
    • 1.4 基本数据类型:字符类型
    • 1.5 数据类型转换与输出
    • 1.6 数组与矩阵基础
      • 1.6.1 矩阵运算进阶
    • 1.7 数组与矩阵常用函数
    • 1.8 matlab中的逻辑运算
    • 1.9 实验: MATLAB常用数学函数
      • 1.9.1 实验 作业答案
    • 1.10 元胞数组
    • 1.11 结构体数组
      • 1.11.1 结构体进阶
      • 1.11.2 元胞数组与结构体数组对比
      • 1.11.3 map 容器
    • 1.12 附录:MATLAB常用基础命令
    • 1.13 拓展内容:实时脚本
      • 1.13.1 实时脚本示例
    • 1.14 课程作业与答案
      • 1.14.1 《通信系统仿真》期末考试
  • 2 第二单元:Matlab 程序设计
    • 2.1 顺序结构程序
    • 2.2 分支结构—— if语句
    • 2.3 分支结构—— switch语句
    • 2.4 循环结构—— while语句
    • 2.5 循环结构—— for语句
    • 2.6 图像处理基础
    • 2.7 Matlab的函数
      • 2.7.1 函数内容的课外扩展
    • 2.8 本章实验:for循环的应用
      • 2.8.1 素数问题
        • 2.8.1.1 素数的螺旋线排列
      • 2.8.2 3X+1猜想
      • 2.8.3 7 行代码计算 π
    • 2.9 排序算法
      • 2.9.1 冒泡排序
      • 2.9.2 选择排序
      • 2.9.3 插入排序
      • 2.9.4 快速排序
      • 2.9.5 基数排序
      • 2.9.6 计数排序
      • 2.9.7 堆排序
    • 2.10 动态规划算法
      • 2.10.1 动态规划编程实例
      • 2.10.2 动态规划:01背包问题
      • 2.10.3 动态规划常见题目分析
      • 2.10.4 动态规划题目分析2
    • 2.11 常用算法简介
      • 2.11.1 剪枝算法
      • 2.11.2 二分查找
      • 2.11.3 递归算法
      • 2.11.4 回溯算法
        • 2.11.4.1 Leetcode回溯题目合集
        • 2.11.4.2 回溯算法总结
        • 2.11.4.3 回溯法解数独问题
        • 2.11.4.4 DFS与BFS
          • 2.11.4.4.1 DFS/BFS原理
          • 2.11.4.4.2 BFS的应用:Dijkstra算法
      • 2.11.5 n 皇后问题专题
      • 2.11.6 双指针算法
      • 2.11.7 数组模拟链表(约瑟夫环)
      • 2.11.8 Hash(哈希表)
      • 2.11.9 图论与路径规划
        • 2.11.9.1 迪杰斯特拉算法
        • 2.11.9.2 A*算法
          • 2.11.9.2.1 A*算法的MATLAB实现
        • 2.11.9.3 RRT路径规划算法
          • 2.11.9.3.1 RRT算法 MATLAB代码
          • 2.11.9.3.2 参考资料
      • 2.11.10 数据结构
        • 2.11.10.1 数据结构例题
      • 2.11.11 前缀和 差分 双指针
      • 2.11.12 位运算
      • 2.11.13 常用算法代码模板
    • 2.12 练习题库
    • 2.13 code
      • 2.13.1 简易计算器gui代码
      • 2.13.2 五子棋
      • 2.13.3 连连看小游戏
      • 2.13.4 递归算法与汉诺塔
      • 2.13.5 有理数的小数循环节
    • 2.14 MATLAB编程风格
      • 2.14.1 向量化编程专题
  • 3 第三单元:Matlab 图形图像处理
    • 3.1 二维图形绘图基础
    • 3.2 二维图形绘图进阶
    • 3.3 三维图形绘图
      • 3.3.1 MATLAB绘图小结
        • 3.3.1.1 用matlab绘制好看图像
    • 3.4 MATLAB高级绘图
    • 3.5 文件操作
    • 3.6 Matlab图像处理进阶
      • 3.6.1 补充:Matlab图像处理常用函数
      • 3.6.2 RGB/HSV/HSI颜色模型
      • 3.6.3 图片切换动画效果
      • 3.6.4 图像连通域标记
      • 3.6.5 图像旋转与插值
      • 3.6.6 图像的形态学
      • 3.6.7 空间滤波
        • 3.6.7.1 图像中常见的噪声类型与滤波方法
        • 3.6.7.2 matlab中的滤波函数
        • 3.6.7.3 BM3D 去噪算法
        • 3.6.7.4 双边滤波
      • 3.6.8 图像的频域处理
    • 3.7 本章总结
    • 3.8 实验 : matlab 绘图练习1
    • 3.9 实验: matlab 绘图练习2
    • 3.10 实验 :数学函数图像绘制
    • 3.11 实验:绘图综合练习
    • 3.12 实验:曲线拟合
    • 3.13 实验:牛顿法求解方程的根
    • 3.14 实验:信号的傅里叶变换
      • 3.14.1 傅里叶变换、小波变换、希尔伯特变换
      • 3.14.2 新建目录
    • 3.15 课外补充:图像处理基础1
    • 3.16 课外补充:图像处理基础2
    • 3.17 课外补充:图像处理基础3
    • 3.18 课外补充:PYTHON基础
  • 4 第五单元:MATLAB通信仿真
    • 4.1 现代通信系统的介绍
    • 4.2 模拟通信系统的仿真原理
    • 4.3 HDB3编解码的仿真实现
    • 4.4 SIMULINK和其模块简介
    • 4.5 数字通信系统的仿真原理
    • 4.6 模拟通信系统Simulink仿真
    • 4.7 数字通信系统Simulink仿真
    • 4.8 音频信号测处理与仿真
    • 4.9 图像数字水印技术
      • 4.9.1 三角函数到傅里叶变换再到语音识别与数字水印
    • 4.10 信息系统与算法
      • 4.10.1 递归算法
        • 4.10.1.1 递归与堆栈的关系
      • 4.10.2 哈希表
      • 4.10.3 双指针算法
        • 4.10.3.1 双指针算法实战
        • 4.10.3.2 双指针进阶:滑动窗口算法
      • 4.10.4 字符串匹配 KMP算法
        • 4.10.4.1 字符串匹配B-M算法
      • 4.10.5 快速傅里叶变换
      • 4.10.6 回溯算法
      • 4.10.7 动态规划
      • 4.10.8 分治算法
      • 4.10.9 Dijkstra算法
  • 5 第六单元: systemview通信仿真
    • 5.1 SystemView概述
    • 5.2 模拟通信系统 数字系统的仿真分析
    • 5.3 SystemView通信系统仿真进阶
    • 5.4 新建课程目录
  • 6 第四单元:MATLAB高级应用
    • 6.1 符号运算基础
      • 6.1.1 利用Matlab自动推导公式
    • 6.2 Matlab中的数值计算
      • 6.2.1 积分的计算
      • 6.2.2 龙格库塔:常微分方程的数值解法
      • 6.2.3 fmincon函数与非线性方程最小值
    • 6.3 统计、拟合、插值
      • 6.3.1 协方差与相关系数
    • 6.4 GUI设计初步
    • 6.5 matlab GUI界面编程
      • 6.5.1 gui实例
      • 6.5.2 gui编程中常用函数
      • 6.5.3 App Designer入门
    • 6.6 实验:GUI设计图像空间变换系统
    • 6.7 作业:利用GUI设计 计算器、信号发生器等
    • 6.8 MTALB数据导入方法
    • 6.9 课外补充:MATLAB的App会取代GUI吗?
    • 6.10 模拟退火算法matlab实现
    • 6.11 遗传算法的Matlab实现
      • 6.11.1 进化算法(Evolutionary Algorithm)及相关函数介绍
    • 6.12 粒子群算法 matlab实现
      • 6.12.1 粒子群算法及MATLAB实例仿真
    • 6.13 BP网络的应用
    • 6.14 matlab 结构体
    • 6.15 群智能算法合集
  • 7 拓展知识
    • 7.1 什么是算法的时间复杂度?
    • 7.2 Notepad++使用教程
    • 7.3 MATLAB常用函数总结
    • 7.4 MATLAB常用知识点总结
    • 7.5 MATLAB命令大全
    • 7.6 视频:MATLAB官方基础教程
    • 7.7 经典书籍:Matlab2012经典超强教程
    • 7.8 经典书籍:MATLAB揭秘(自学宝典)
    • 7.9 经典资料:MATLAB N个实用技巧
    • 7.10 Matlab编程小技巧
    • 7.11 寻优算法
      • 7.11.1 Dijkstra算法python实现
    • 7.12 PYTHON基础教程
      • 7.12.1 Python进阶
      • 7.12.2 Python小技巧
      • 7.12.3 Python总结
        • 7.12.3.1 Python循环语句总结
        • 7.12.3.2 24个顶级Python库
        • 7.12.3.3 魔法函数
      • 7.12.4 廖雪峰python
      • 7.12.5 正则表达式基础
      • 7.12.6 numpy
        • 7.12.6.1 101道Numpy习题
        • 7.12.6.2 Numpy简要语法教程
        • 7.12.6.3 Numpy实现全连接神经网络 (手写数字识别)
        • 7.12.6.4 图解NumPy
      • 7.12.7 matplotlib
        • 7.12.7.1 matplotlib练习50题
        • 7.12.7.2 Matplotlib速查表
        • 7.12.7.3 Matplotlib 实操指南
      • 7.12.8 Python3 模块 import
      • 7.12.9 Python 小项目
    • 7.13 参考资源:数据结构与算法
      • 7.13.1 十大经典排序算法总结
    • 7.14 机器学习概述
      • 7.14.1 反向传播算法
        • 7.14.1.1 反向传播的数学原理
      • 7.14.2 极大似然估计
        • 7.14.2.1 极大似然估计与最小二乘法
      • 7.14.3 Batch Normalization
        • 7.14.3.1 Batch Normalization&Dropout浅析
        • 7.14.3.2 ​BN层的梯度反向传播计算
        • 7.14.3.3 Batch Size的大小与神经网络的性能
        • 7.14.3.4 标准化和归一化
      • 7.14.4 主成分分析PCA与SVD奇异值分解
        • 7.14.4.1 岭回归 与 PCA
        • 7.14.4.2 PCA原理推导
        • 7.14.4.3 PCA原理新解
        • 7.14.4.4 svd
        • 7.14.4.5 PCA数学原理
      • 7.14.5 正则化
        • 7.14.5.1 L1、L2正则化和过拟合 总结
        • 7.14.5.2 L1 和 L2 正则化的直观解释
      • 7.14.6 SVM
        • 7.14.6.1 从零推导支持向量机(SVM)
        • 7.14.6.2 支持向量机(SVM)介绍
        • 7.14.6.3 SVM推导与实战
        • 7.14.6.4 支持向量机的直观理解
        • 7.14.6.5 浅显易懂的支持向量机SVM
      • 7.14.7 线性回归
      • 7.14.8 逻辑回归
      • 7.14.9 BP算法
        • 7.14.9.1 万能逼近——神经网络拟合任意函数原理
      • 7.14.10 激活与池化
        • 7.14.10.1 激活函数与损失函数 小结
      • 7.14.11 深度学习简述
        • 7.14.11.1 MATLAB2020深度学习实例
      • 7.14.12 损失函数与误差反向传播
        • 7.14.12.1 梯度下降与损失函数
      • 7.14.13 深度学习优化问题
      • 7.14.14 梯度下降法
        • 7.14.14.1 各类梯度下降算法的Python实现
        • 7.14.14.2 梯度下降的直观理解
        • 7.14.14.3 动量、RMSProp、Adam
      • 7.14.15 卷积的概念
        • 7.14.15.1 卷积的矩阵化算法
      • 7.14.16 局部连接
      • 7.14.17 RNN
      • 7.14.18 LSTM
      • 7.14.19 CNN-四大经典CNN技术浅析
      • 7.14.20 熵(Entropy)与交叉熵
      • 7.14.21 softmax函数详解
      • 7.14.22 自编码算法详细理解与代码实现
      • 7.14.23 pytorch
        • 7.14.23.1 ​PyTorch简介
          • 7.14.23.1.1 Pytorch快速入门资料
        • 7.14.23.2 CNN的PyTorch实现
        • 7.14.23.3 pytorch总结
        • 7.14.23.4 PyTorch trick 集锦
        • 7.14.23.5 在PyTorch上加载自定义数据集
        • 7.14.23.6 实战:Pytorch识别验证码
        • 7.14.23.7 实战:Transformer的最简洁pytorch实现
        • 7.14.23.8 使用PyTorch实现神经网络分类
      • 7.14.24 卷积神经网络CNN概述
        • 7.14.24.1 CNN 简易原理
        • 7.14.24.2 卷积神经网络CNN原理详解
        • 7.14.24.3 自己手写一个卷积神经网络
        • 7.14.24.4 CNN反向传播算法
        • 7.14.24.5 卷积计算、作用与思想
        • 7.14.24.6 用卷积神经网络CNN识别手写数字集
        • 7.14.24.7 卷积 池化 参数的计算
        • 7.14.24.8 im2col方法实现卷积算法
        • 7.14.24.9 卷积核的梯度计算
        • 7.14.24.10 卷积层反向传播推导及实现
        • 7.14.24.11 反向传输算法
          • 7.14.24.11.1 resnet残差网络
        • 7.14.24.12 CNN反向传播的MATLAB实现
      • 7.14.25 神经网络的调参技巧
      • 7.14.26 BP神经网络
        • 7.14.26.1 零开始搭建bp神经网络
        • 7.14.26.2 MATLAB自带的bp工具箱
        • 7.14.26.3 神经网络中偏置(bias)的作用
      • 7.14.27 聚类分析 k-means
        • 7.14.27.1 matlab做聚类分析(k-means)
        • 7.14.27.2 聚类模型探讨综述
        • 7.14.27.3 5种经典聚类算法
      • 7.14.28 深度学习的一些概念
      • 7.14.29 人工智能简述:AI的过去和现在
      • 7.14.30 k-NN(k近邻算法)
      • 7.14.31 神经网络中的优化器:BGD、SGD、MBGD、Momentum
      • 7.14.32 卷积神经网络的经典网络总结
        • 7.14.32.1 卷积神经网络中十大拍案叫绝的操作
      • 7.14.33 GAN 对抗样本攻击
      • 7.14.34 蒙特卡洛模拟
      • 7.14.35 dropout与随机部分连接
      • 7.14.36 Jupyter 等 IDE概览
      • 7.14.37 分类算法常用评价指标
      • 7.14.38 Inception 网络与不变性
      • 7.14.39 卷积神经网络的可视化
      • 7.14.40 隐马尔可夫模型HMM
        • 7.14.40.1 马尔科夫链
    • 7.15 MATLAB音频处理
      • 7.15.1 python处理音频信号
    • 7.16 图像处理
      • 7.16.1 图像处理中的指标
    • 7.17 代码集
    • 7.18 论文写作与阅读方法
      • 7.18.1 期刊投稿攻略
      • 7.18.2 论文排版教程
      • 7.18.3 SCI-HUB论文下载技巧
      • 7.18.4 几种论文写作神器,提高写作效率
      • 7.18.5 latex入门
      • 7.18.6 LaTeX教程
    • 7.19 机器学习常用的网站以及资源
      • 7.19.1 很详细的ML&DL学习博客
    • 7.20 SymPy 符号计算基本教程
  • 8 程序设计数学基础
    • 8.1 编程数学基础
      • 8.1.1 概率的历史
      • 8.1.2 概率
        • 8.1.2.1 常见概率分布
          • 8.1.2.1.1 二维正态分布
        • 8.1.2.2 蒙特卡罗方法
        • 8.1.2.3 置信区间
        • 8.1.2.4 协方差与相关系数
      • 8.1.3 矩阵 向量求导法则
      • 8.1.4 雅可比矩阵 海森矩阵
      • 8.1.5 矩阵的几种分解方式
      • 8.1.6 行列式和代数余子式
      • 8.1.7 向量
      • 8.1.8 矩阵的基本运算
      • 8.1.9 矩阵分析
      • 8.1.10 矩阵的LU分解
      • 8.1.11 矩阵奇异值分解(SVD)
        • 8.1.11.1 SVD分解2
        • 8.1.11.2 SVD分解逐步推导
        • 8.1.11.3 奇异值与特征值的意义
      • 8.1.12 随机向量
        • 8.1.12.1 随机过程简述
      • 8.1.13 投影矩阵和最小二乘
      • 8.1.14 知乎数学精选集
        • 8.1.14.1 高数问题集
      • 8.1.15 小波变换
      • 8.1.16 程序设计数学基础1:高等数学
      • 8.1.17 程序设计数学基础2:线性代数
      • 8.1.18 程序设计数学基础3:概率论和数理统计
      • 8.1.19 向量的距离与相似度计算
      • 8.1.20 复数
      • 8.1.21 高等数学——幂级数
      • 8.1.22 无穷小的本质
      • 8.1.23 数列极限和收敛性
      • 8.1.24 不定积分技巧总结
    • 8.2 有趣的数学题目
    • 8.3 高等数学
      • 8.3.1 泰勒级数
  • 9 路径规划与智能算法
    • 9.1 常见路径规划算法简介
    • 9.2 Dijkstra算法详细
  • 10 教学文档
    • 10.1 授课计划
    • 10.2 课程标准
课程作业与答案



第一章作业

1.5

作业1:

创建一个计算三角形面积的脚本文件。运行此脚本时,用input函数要求对方输入三角形的三个边长,然后输出三角形面积。

clear

a = input ('请输入三角形第1个边长 a = ');

b = input ('请输入三角形第2个边长 b = ');

c = input ('请输入三角形第3个边长 c = ');

p=(a+b+c)/2;

s=sqrt(p*(p-a)*(p-b)*(p-c));


fprintf('输入的三角形面积为:%.3f  \n',s)



1.7

作业1:编程实现把任何一个输入的2*2的矩阵a变成10*10的矩阵y

要求效果如下:

提示,有两种方法。

方法1采用repmat函数;

方法2采用如下索引方式



% 方法1采用repmat函数;

clear

a=[1,2;3,4]

y=zeros(10)  %初始化y,占一个10*10的位置先

y(1:5,1:5)=repmat(a(1,1),5,5);

y(1:5,6:10)=repmat(a(1,2),5,5);

y(6:10,1:5)=repmat(a(2,1),5,5);

y(6:10,6:10)=repmat(a(2,2),5,5);

y



% 方法2采用如下索引方式

clear

a=[1,2;3,4]

y=ones(10)

y(1:5,1:5)=a(1,1);

y(1:5,6:10)=a(1,2);

y(6:10,1:5)=a(2,1);

y(6:10,6:10)=a(2,2);

y



作业2:

(1)先把A和B按纵向合成为一个6*3的矩阵C,然后再把C的3个列向量串接成一个18*1的列向量D,然后把D再变为一个1*18的行向量E。

(2)把上一步得到的行向量E,采用reshape函数变形为一个2*9的新矩阵F;

(3)采用cat()函数把A和B合并成一个3*3*2的三维数组G。

clear

A=[5 3 5;3 7 4;7 9 8]

B=[2 4 2;6 7 9;8 3 6]

C=[A;B]

D=C(:)

E=D'

F=reshape(E,2,9)

G=cat(3,A,B)


作业3:(1)创建一个5*10*3的随机整数三维数组,要求所有元素都是1-150之间的整数,且不许重复(提示:使用randperm函数;(2)先求每一面中的最大值最小值,再求整个矩阵的最大值和最小值


clear

x=randperm(150)

y=reshape(x,5,10,3)

y1_max=max(y(:,:,1),[],'all')  

y2_max=max(y(:,:,2),[],'all')

y3_max=max(y(:,:,3),[],'all')


y1_min=min( min(y(:,:,1)) )

y2_min=min( min(y(:,:,2)) )

y3_min=min( min(y(:,:,3)) )


y_max=max(y(:))

y_min=min(y(:))


%以上采用三种方法求最值,细心体会


作业4:(1)创建5*10的符合正态分布(均值为0)的随机矩阵a。(2)分别对a矩阵的方向进行升序排序得到矩阵B,再对B矩阵的列方向降序排序得到矩阵C。(3)求这个C矩阵所有元素之和,以及元素的平均值。

clear

a=randn(5,10)

B=sort(a,2)

c=sort(B,1,'descend')

c_sum=sum(c(:))

c_mean=c_sum/numel(c)    %或者 c_mean=mean(c(:))


作业5:(1)创建5*5的魔方矩阵;(2)对这个矩阵先进行时针90°的旋转,再上下翻转;(3)验证得到的这个新矩阵的,各行之和,列之和,左对角线之和(提示:需要把对角线元素一个个都索引出来,作为一个行向量,再来求和),右对角线之和,看看这些和是否相等?

%参考答案

m0=magic(5)

m1=rot90(m0,-1)

m2=flipud(m1)

dig_l=diag(m2)

dig_r=diag( rot90(m2) )


sum(m2,1)

sum(m2,2)

sum(dig_l)

sum(dig_r)


m0 =

    17    24     1     8    15

    23     5     7    14    16

     4     6    13    20    22

    10    12    19    21     3

    11    18    25     2     9

m1 =

    11    10     4    23    17

    18    12     6     5    24

    25    19    13     7     1

     2    21    20    14     8

     9     3    22    16    15

m2 =

     9      3     22    16    15

     2     21    20    14     8

    25    19    13     7      1

    18    12     6      5     24

    11    10     4     23    17

dig_l =

     9

    21

    13

     5

    17

dig_r =

    15

    14

    13

    12

    11

ans =

    65    65    65    65    65

ans =

    65

    65

    65

    65

    65

ans =

    65

ans =

    65




作业6:生成一个400*400像素的纯色图(颜色调节到自己喜欢的状态)。提示,采用ones()/cat() 等函数生成400*400*3的三维数组,作为RGB三个通道的数据,然后用imshow()函数显示这个数组。

clear

kr=0.78;

kg=0.11;

kb=0.39;

r=ones(400)*kr;

g=ones(400)*kg;

b=ones(400)*kb;

pic=cat(3,r,g,b);

imshow(pic)



1.8

作业1:

(1)创建一个5行4列的元胞数组,要求:第一行是4个字符串,依次为:'姓名','籍贯','学号','电话';第2-5行分别是4个具体同学的实例。

(2)创建好之后,显示输出(celldisp)该元胞数组内容,并画出(cellplot)其结构。

(3)分别对具体某个学生的姓名或者学号、电话等,进行索引。





作业2:

创建一个4行5列的元胞数组,此元胞数组中的每一个单元都是一个字符串(假设为网站中用户注册时分配的初始用户名),此字符串长度为6,这6个字母是从62个字符(26个字母的大小写,加上10个数字字符)中随机选择的。

提示:

>> x='a':1:'z'

x =

    'abcdefghijklmnopqrstuvwxyz'

>> x( [randi(26,1,3)] )

ans =

    'vxd'


或:

x='a':1:'z'

y=x( [randperm(26)] )

y(1:3)

x =

    'abcdefghijklmnopqrstuvwxyz'

y =

    'mnideoywjbukzacsthrpxqvlfg'

ans =

    'mni'



练习1:对随机矩阵a=randn(10,10),如何计算矩阵a中处于-1到+1之间的元素总数目?

%

%方法1

a=randn(10,10)


y=(a>-1)&(a<1)

z=a(y)

numel(z)


%方法2

y=(a>-1)&(a<1)

sum(y(:))


练习2: 模拟50个同学某门课的期末成绩(随机分布在30-100之间),找出不及格的人数,以及占班级总人数的百分比。再把50-59分的分数置为60。


n=50

s=randi([30,100],1,n)


y=s<60

z=sum(y)

z/n


y2=(s>=50)&(s<=59)

s(y2)=60






1.10

作业1:(1)采用随机函数randn()生成一个10*10的随机矩阵A,假设x为A中的任意一个元素,采用逻辑索引等方法找出A中所有满足:-1<x<-0.5,以及0.5<x<1的元素,把这些元素给y。

(2)求出,数组y的元数的总数。

(3)把A中满足(1)中要求的元素替换成0;


作业2:利用蒙特卡洛法计算圆周率

步骤:

(1)先用rand函数生成方形区域内的n个点的所有横坐标组成的数组x(1*n的数组),再生成这n个点的纵坐标组成的数组y1*n的数组并用plot(x,y,'*')画出这n个点的图像;

(2)计算所有的n个点和圆心的距离r(r也是一个1*n的数组);

(3)判断每个点的r与设定的圆的半径r0=1的大小逻辑关系,计算位于圆内的点数m。

(4)利用公式,计算pi的值。


提示:如何确定数组x=rand(1,20)中大于0.8的元素的个数,以及所有大于0.8的元素之和?

x=rand(1,20)

y=(x>0.8)         %大小关系的逻辑判断,得到一个1*20的逻辑数组

y_num=sum(y)  %求这个逻辑数组的和(所有1的和`),既为符号要求的点数

z=x(y)                %使用逻辑数组y索引出x中符合要求的元素,给z

z_num=sum(z)  %算出z中所有元素之和



作业3.设x=randi(10,3,10); y=randi([5,20],5,10);求x与y的交集、并集,并用unique()函数对x和y进行瘦身。





1.11

作业1:通过学习本节的知识,编程生成一个4*4网格的随机彩色图,既共16个单元格(每个单元格子大小为100*100像素)。每次运行代码,都能得到不同颜色分布的随机图案。


参考:3*3时的情况


方法1:

%膨胀法(把小图的每个像素点膨胀后填充到大图的对应区域内)

clear all

k=3;             %设置网格为k*k

n=100;         %设置膨胀倍数n


rgb1=rand(k,k,3);   %原始的k*k像素的3通道小彩图

imshow(rgb1)  


%下面开始膨胀操作。

rgb=zeros( k*n , k*n , 3 );     %初始化rgb三维数组,初始值都设为0


rgb(1:100,1:100,:)   =repmat(rgb1(1,1,:),100,100) ;

rgb(1:100,101:200,:)=repmat(rgb1(1,2,:),100,100) ;

rgb(1:100,201:300,:)=repmat(rgb1(1,3,:),100,100);


rgb(101:200,1:100,:)   =repmat(rgb1(2,1,:),100,100);

rgb(101:200,101:200,:)=repmat(rgb1(2,2,:),100,100);

rgb(101:200,201:300,:)=repmat(rgb1(2,3,:),100,100);


rgb(201:300,1:100,:)   =repmat(rgb1(3,1,:),100,100);

rgb(201:300,101:200,:)=repmat(rgb1(3,2,:),100,100);

rgb(201:300,201:300,:)=repmat(rgb1(3,3,:),100,100);


imshow(rgb)





方法2:

组合法(先生成9个100*100的随机纯色块,然后拼接成一个3*3的九宫格)


clear all

n=100;                       %设置每个基础色块的像素值


o=ones( n , n , 3 );     %初始化rgb三维数组,初始值都设为0


rgb11=o.*rand(1,1,3);  %对每个色块随机染色。

rgb12=o.*rand(1,1,3);

rgb13=o.*rand(1,1,3);


rgb21=o.*rand(1,1,3);

rgb22=o.*rand(1,1,3);

rgb23=o.*rand(1,1,3);


rgb31=o.*rand(1,1,3);

rgb32=o.*rand(1,1,3);

rgb33=o.*rand(1,1,3);


rgb=[rgb11,rgb12,rgb13;rgb21,rgb22,rgb23;rgb31,rgb32,rgb33];


imshow(rgb)



答案:

clear all

n=100;                 %设置每个基础色块的像素值

o=ones( n , n , 3 );   %初始化rgb三维数组,初始值都设为0


rgb11=o.*rand(1,1,3);  %对每个色块随机染色。

rgb12=o.*rand(1,1,3);

rgb13=o.*rand(1,1,3);

rgb14=o.*rand(1,1,3);


rgb21=o.*rand(1,1,3);

rgb22=o.*rand(1,1,3);

rgb23=o.*rand(1,1,3);

rgb24=o.*rand(1,1,3);


rgb31=o.*rand(1,1,3);

rgb32=o.*rand(1,1,3);

rgb33=o.*rand(1,1,3);

rgb34=o.*rand(1,1,3);


rgb41=o.*rand(1,1,3);

rgb42=o.*rand(1,1,3);

rgb43=o.*rand(1,1,3);

rgb44=o.*rand(1,1,3);


rgb=[rgb11,rgb12,rgb13,rgb14;

     rgb21,rgb22,rgb23,rgb24;

     rgb31,rgb32,rgb33,rgb34;

     rgb41,rgb42,rgb43,rgb44];

imshow(rgb)



作业2:(1)采用randi([1,300],[10,15])生成一个10*10的随机整数矩阵A;(2)采用逻辑索引的方法,索引出矩阵A中所有可以被3整除的元素;(3)并计算出上一步索引出的元素的总数;(4)找出A中所有不能被3整除也不能被7整除的元素的总数;(5)把A中所有可以被3整除的元素替换成0。

答案:

%(1)采用randi([1,300],[10,10])生成一个10*10的随机整数矩阵A;

clear

A=randi([1,300],[10,10])


%(2)采用逻辑索引的方法,索引出矩阵A中所有可以被3整除的元素;

y1= (mod(A,3)==0)

z=A(y1)


%(3)并计算出上一步索引出的元素的总数;

numel(z) 


 % (4)找出A中所有不能被3整除也不能被7整除的元素的总数;

y2=(mod(A,3)~=0)&(mod(A,7)~=0)

sum(y2(:))


%(5)把A中所有可以被3整除的元素替换成0。

A(y1)=0





作业3:求任意给定的一个五位正整数的个位、十位、百位,千位、万位。

效果如下:


要求应用两种方法。

方法1,采用num2str函数以及字符数组的方法。

方法2,采用fix()等函数方法。

% 方法1:采用num2str函数以及字符数组的方法。


x=32487;

y=num2str(x)

fprintf('个位数为%s, 十位数为%s, 百位数为%s, 千位数为%s, 万位数为%s,\n',y(5),y(4),y(3),y(2),y(1))



% 方法2:采用fix()等函数方法。

x=32487

y1=fix(x/10000);

y2=fix(x/1000)-y1*10;  %y2=mod(fix(x/1000),10)

y3=fix(x/100)-y1*100-y2*10;

y4=fix(x/10)-y1*1000-y2*100-y3*10;

y5=x-y1*10000-y2*1000-y3*100-y4*10;

fprintf('个位数为%d, 十位数为%d, 百位数为%d, 千位数为%d, 万位数为%d, \n',y5,y4,y3,y2,y1)



% 方法3:采用fix/mod等函数方法。

x=32487

y1=mod(x,10)

y2=mod(fix(x/10),10)

y3=mod(fix(x/100),10)

y4=mod(fix(x/1000),10)

y5=mod(fix(x/10000),10)

fprintf('个位数为%d, 十位数为%d, 百位数为%d, 千位数为%d, 万位数为%d, \n',y1,y2,y3,y4,y5)





 作业4:(1)利用randn()函数生成一个5*10的矩阵A,用ceil处理A得到矩阵x,用 floor处理A得到矩阵y,用round处理A得到矩阵z,用fix处理A得到矩阵t;

(2)计算x+y-(z+t);

A=randn(5,10)

x=ceil(A)

y=floor(A)

z=round(A)

t=fix(A)

x+y-(z+t)




第二章作业



作业1.邮件地址切片器

目的:编写一个脚本,可以从用户给出的邮箱地址中获取用户名和域名。

如果用户输入的邮箱不符合规则,则输出:邮箱格式有误。如果邮箱格式正确,则给出用户名和域名。

效果如下:

(1)如果输入的邮箱(需要单引号引住)格式有误,即:帐号+@+域名,这三者缺少一个,则输出“邮箱格式有误!




(2)如果邮箱格式正确,则输出邮箱的账号和域名。



提示:邮箱地址一般是帐号@域名的格式,就是帐号+@+域名,这三个部分组成。可以使用@作为分隔符,将地址分为分为两个字符串。如果这三个部分,缺少任何一部分,则认为邮箱格式有误。可以使用strfind()等函数,加上if判断,,以及判断数组是否为空的函数isempty( )等.

clear

s=input('请输入你的邮箱(email) :')

L=                %得到字符串s的长度


num_at=      %判断输入的字符串里面的“@”的数量num_at,是否超过了2个


if          %如果“@”超过2个,或者等于0个,或者“@”在开头,或者“@”在末尾

   fprintf('邮箱格式有误!\n' );

else

    s1=    %把账号部分切片出来给s1

    s2=    %把域名部分切片出来给s2

    fprintf('帐号为%s,域名为%s \n',s1,s2);

end



答案:

%方法1

clear

s=input('请输入你的邮箱(email) :')

L= length(s)            %得到字符串s的长度

num_at= sum( s=='@')    %判断输入的字符串里面的“@”的数量num_at


if  num_at>=2|num_at==0|s(1)=='@'|s(end)=='@'   

    %如果“@”超过2个,或者等于0个,或者“@”在开头,或者“@”在末尾

    fprintf('邮箱格式有误!\n' );

else

    k=strfind(s,'@');

    s1=s(1:k-1);

    s2=s(k+1:L);

    fprintf('帐号为%s,域名为%s \n',s1,s2);

end


%方法2

clear

s=input('请输入你的邮箱(email) :')

L=length(s);

k=strfind(s,'@');

num_at=length(k);    %判断输入的字符串里面的“@”是否超过了2个


if isempty(k)|k==1|k==L|num_at>=2

   fprintf('邮箱格式有误!\n' );

else

    s1=s(1:k-1);

    s2=s(k+1:L);

    fprintf('帐号为%s,域名为%s \n',s1,s2);

end







2.3

作业:

设定一个分数标准: 0-59:E级      60-69:D级      70—79:C级     80—89:B级     90-100:A级; 按照这个分数标准对输入的成绩进行等级评判(即,输出这个分数对对应的等级)。

(1)用if语句实现

(2)用switch语句实现


答案:


%用if语句实现

clear

score=37


if score>=90&score<=100

    fprintf('成绩为A级 \n');

elseif score>=80&score<89

    fprintf('成绩为B级 \n');

elseif score>=70&score<79

    fprintf('成绩为C级 \n');

elseif score>=60&score<69

    fprintf('成绩为D级 \n');

else

    fprintf('成绩为E级 \n');

end



%用switch语句实现,方式1

clear

score=97

k=fix(score/10)


switch k

    case {9,10}

        fprintf('成绩为A级 \n');

    case  {8}

        fprintf('成绩为B级 \n');

    case  {7}

        fprintf('成绩为C级 \n');

    case  {6}

        fprintf('成绩为D级 \n');

    otherwise                      % 或者写成 case  {0 1 2 3 4 5}

        fprintf('成绩为E级 \n');

end




%用switch语句实现,方式2

clear

score=97

switch score

    case  num2cell(90:100)

        fprintf('成绩为A级 \n');

        

    case  num2cell(80:89)

        fprintf('成绩为B级 \n');

        

    case  num2cell(70:79)

        fprintf('成绩为C级 \n');

        

    case  num2cell(60:69)

        fprintf('成绩为D级 \n');

        

    otherwise                      % 或者写成 case num2cell(0:59)

        fprintf('成绩为E级 \n');

end



2.4

作业1:制作一个成绩计算程序。

(1)第1步,用input函数,让对方依次输入任意两个0-100之间的数,分别赋给变量X_ps和 X_qm。 其中变量X_ps, X_qm分别表示平时分和期末卷面分,S_zf表示总分。要求判断输入的X_ps和 X_qm是否在0-100之间,如果不在,则输出警告并要求对方重新输入正确的数值.....直到满足两个数都在0-100之间。

(2)第2步,根据上一步得到的平时分和期末分,计算总分S_zf,公式如下:

(3)第3步,采用if或者 switch语句执行以下动作:

当总分S_zf在90-100这个区间时,输出:您的平时分为:***  卷面分为:***   总分为:***  成绩优秀

当总分S_zf在70-89.9这个区间时,输出:您的平时分为:***  卷面分为:***   总分为:***  成绩良好

当总分S_zf在60-69.9这个区间时,输出:您的平时分为:***  卷面分为:***   总分为:***  成绩及格

当总分S_zf在0-59.9这个区间时,输出:  您的平时分为:***  卷面分为:***   总分为:***  等着补考吧。

(提示:需要用到while循环、 if或者 switch分支,fprintf格式输出,数值的大于、小于、与或非等逻辑判断语句。)


clear

while 1 

    X_ps=input('请输入你的平时分:');    

    X_qm=input('请输入你的期末考试分:');

    if  X_ps>100 | X_ps<0 | X_qm>100 | X_qm<0  

        fprintf('输入有误,输入的分数应该在0-100之间.请重新输入 \n')

    else

        break

    end

end


S_zf=0.4*X_ps+0.6*100*(X_qm/100)^0.5;


if   S_zf>=90

      fprintf('您的平时分为:%5.2f  卷面分为:%5.2f    总分为:%5.2f  成绩优秀. \n' ,X_ps,X_qm, S_zf);


elseif  S_zf>=70&S_zf<90

      fprintf('您的平时分为:%5.2f  卷面分为:%5.2f    总分为:%5.2f    成绩良好. \n',X_ps,X_qm, S_zf);


elseif  S_zf>=60&S_zf<70

      fprintf('您的平时分为:%5.2f   卷面分为:%5.2f   总分为:%5.2f   成绩及格. \n',X_ps,X_qm, S_zf);


elseif  S_zf<60

      fprintf('您的平时分为:%5.2f  卷面分为:%5.2f   总分为:%5.2f  等着补考吧. \n',X_ps,X_qm, S_zf);

end



%方法2:采用switch模式

% switch fix(S_zf/10)

%     case {9,10}

%         fprintf('您的平时分为:%5.2f  卷面分为:%5.2f    总分为:%5.2f  成绩优秀. \n' ,X_ps,X_qm, S_zf);

%     case {7,8}

%         fprintf('您的平时分为:%5.2f  卷面分为:%5.2f    总分为:%5.2f    成绩良好. \n',X_ps,X_qm, S_zf);

%     case {6}

%         fprintf('您的平时分为:%5.2f   卷面分为:%5.2f   总分为:%5.2f   成绩及格. \n',X_ps,X_qm, S_zf);

%     otherwise

%         fprintf('您的平时分为:%5.2f  卷面分为:%5.2f   总分为:%5.2f  等着补考吧. \n',X_ps,X_qm, S_zf);

% end




作业2:计算三角形面积

创建一个计算三角形面积的脚本文件。运行此脚本时,用input函数要求对方输入三角形的三个边长,然后输出三角形面积。要求判断输入的三个边长是否满足三角形的基本要求(三角形总是满足任意两边和大于第三边)不满足则要求重新输入。

clear


while 1

       a = input ('请输入三角形第1个边长 a = ');

       b = input ('请输入三角形第2个边长 b = ');

       c = input ('请输入三角形第3个边长 c = ');

       if (a+b)>c&(a+c)>b&(b+c)>a

            fprintf('这是一个合理的三角形\n')

            break

       else

            fprintf('输入的三个边长构不成三角形,请重新输入 \n')

       end

end


p=(a+b+c)/2;

s=sqrt(p*(p-a)*(p-b)*(p-c));


fprintf('输入的三角形周长为:%.3f   , 面积为:%.3f  \n',a+b+c,s)



作业3:对数组x=randi([1,99],5,20),按行查找,把每一行第一个能被7整除的数找出来,输出该数,然后停止查找该行,进入下一行继续查找。

提示:需要用到双重的嵌套(while或for)循环,以及break语句等。。

%方法1:

clear

x=randi([1,99],5,20)

[row,col]=size(x)

taget=7;

for n=1:row

    for m=1:col

        if mod(x(n,m),taget)==0

           fprintf('在第%d行的第%d列,找到首个能被%d整除的数,这个数是%d \n',n,m,taget,x(n,m))

           break

        end

    end

end


%方法2:

clear

x=randi([1,99],5,20)

[row,col]=size(x)

taget=7;

n=1;

m=1;

while n<=row

      while m<=col

          if rem(x(n,m),taget)==0

             fprintf('In row %d ,col %d ,find the number your wanted is %d \n',n,m,x(n,m))  

             break

          end

          m=m+1;

      end

      m=1;

      n=n+1;

end


%方法3:

clear

x=randi([1,99],5,20)

[row,col]=size(x)

taget=7;

n=1;

m=1;

while n<=row

    if rem(x(n,m),taget)==0

        fprintf('In row %d ,col %d ,find the number your wanted is %d \n',n,m,x(n,m))

        n=n+1;

        m=1;

        continue

    end

    m=m+1;

end




作业4:用while循环求解e的值。


任务1:编程计算e的值,要求当最后一项的值1/n!<0.000001时结束计算,并输出此时算出的e值(用vpa函数显示e的精确值)。

任务2 : 如果要计算出e的小数点后10的精确值,如要算到多少项目?

提示1:如果要求计算出的e的值精确到小数点后10位,则其和真实的exp(1)之间的差要小于0.0000000001.

提示2,编程时可能会用到阶乘,MATLAB里阶乘的函数为 factorial( )

当n>=1时,factorial(n) 等价于 prod([1:n])

如12的阶乘:

factorial(12)                 %  12的阶乘已经很大了

ans =

     479001600


%任务1

clear

my_e=0;

n=0;

while (1/factorial(n))>0.000001    

    my_e=my_e+1/factorial(n);    

    n=n+1;   

end

vpa(my_e,10)




%任务2

clear

my_e=0;

n=0;

while abs(my_e-exp(1))>0.00000000001  

       my_e=my_e+1/factorial(n);    

       n=n+1;   

end

fprintf('my_e is:%.15f ,exp(1) is :%.15f ,n is %d \n',my_e,exp(1),n-1)



2.5

作业1:编程输出类似如下的乘法口诀表

  

  答案:

for n=1:9
    for m=1:n
          fprintf('%d * %d =%d     ',n,m,n*m)
    end
    fprintf('\n')
end




作业2:求100-999之间的全部水仙花数。

水仙花数是指:一个三位数,其各位数字立方和等于该数本身。例如:370=33+73+03.这就说明370是一个水仙花数。

方法1:循环


for i=1:9

      for j=0:9

           for k=0:9

                  num=i*100+j*10+k;

                  if i^3+j^3+k^3==num

                      fprintf('找到一个水仙花数,为%d \n',num)

                  end

           end

       end

end




方法2:循环


for n=100:999


      n_str=num2str(n);

      i =str2num(n_str(1));

      j =str2num(n_str(2));

      k=str2num(n_str(3));


      if  i^3+j^3+k^3==n

          fprintf('找到一个水仙花数,为%d \n',n)

       end

end




方法3:向量化编程

x=100:999;

x_1=fix(x/100);

x_2=fix(x/10)-x_1*10;

x_3=fix(x)-x_1*100-x_2*10;

loc=(x==(x_1.^3+x_2.^3+x_3.^3));

x(loc)



作业3:信用卡校验

当你输入信用卡号码的时候,有没有担心输错了而造成损失呢?其实可以不必这么担心,因为并不是一个随便的信用卡号码都是合法的,它必须通过Luhn算法来验证通过。


该校验的过程:

1、从卡号最后一位数字开始,逆向将奇数位(1、3、5等等)相加,得到s1

2、从卡号最后一位数字开始,逆向将偶数位数字,先乘以2(如果乘积为两位数,则将其减去9),再求和,得s2

3、将奇数位总和加上偶数位总和,既s=s1+s2,得出的s应该可以被10整除!如果S不能被10整除,则卡号是错误的。


例如,卡号:5432123456788881

逆向奇数位为 4 2 2 4 6 8 8 1 和 = 35

逆向偶数位乘以2(有些要减去9)的结果:1 6 2 6 1 5 7 7,求和 = 35。

最后 35 + 35 = 70 可以被10整除,则认定校验通过。


请编写一个程序,从标准输入获得卡号,然后判断是否校验通过。

通过显示:“成功”,否则显示“失败”。


比如,输入:356827027232780

程序输出:成功


答案:


x=input('请输入卡号,并以单引号引住这串数字:')

y=x([end:-1:1])  %把字符数组x反向后给y

s_even=0;     %偶数位的和的计数器

s_odd=0;      %奇数位的和的计数器

L=length(x);


for n=1:2:L     %处理奇数位

     t1=str2num(y(n));   %需把字符数组y里面的每个元素转为数字格式

     s_odd=s_odd+t1;

end


for n=2:2:L     %处理偶数位

    t2=str2num(y(n));  %需把字符数组y里面的每个元素转为数字格式

    if t2*2>9   

       k=t2*2-9;

    else

       k=t2*2;

    end

    s_even=s_even+k;

end


total=(s_odd+s_even) 

if  mod(total,10)==0

    fprintf('卡号正确 \n');

else

    fprintf('卡号错误 \n');

end




作业4:计算圆周率

利用下列的公式求圆周率PI的值。至少选择以下公式中的2个编程计算圆周率的值。(注意,如果公式里出现阶乘,不要计算太多项,否则计算时间会过长)

这里给出第一个公式的求解代码:


%代码如下:


clear

t=1/2;

x1=sqrt(t);

y1=sqrt(t+t*x1);

for ii=1:20

     x1=x1*y1;

     y1=sqrt(t+t*y1);

end

p1=2/x1;     %p1为我们用公式计算的圆周率

vpa(p1)        %vpa显示p1的精确值

vpa(pi,50)    %作为对比,用vpa显示真实的π的前50位

计算前20项,已经精确到小数点后12位。



提示:以下公式编程时可能会用到阶乘,MATLAB里阶乘的函数为 factorial( )

factorial(n) 等价于 prod([1:n])

factorial(12)                 %  12的阶乘已经很大了

ans =

     479001600





===============================================



作业5:采用for循环生成如下随机n*m格的彩图

功能1:可以自定义n和m的数量,以及每个格子的像素

功能2:通过循环、pause()函数等技巧,来让如上的随机彩图每隔2秒钟刷新一次,刷新得最终次数自己来确定。需要固定图像,既,需要在imshow后面加hold on命令,以保证每次刷新图像的时候,图像位置固定。

....

imshow(rgb2)

hold on


程序暂停功能——pause()函数使用例子:

x=linspace(0,9,10);

y=sin(x);

for k=1:10

      fprintf('当x=%f ,时,对应的y=%f    ', x(k),y(k) )

      pause()

end


clear all

k=3;             %设置网格为k*k

n=100;         %设置膨胀倍数n

rgb1=rand(k,k,3);           %rgb1的初始化

rgb2=zeros(k*n,k*n,3);   %rgb2的初始化


%下面开始膨胀操作。

for ii=1:k            %ii代表行

     for jj=1:k       %JJ代表列

          rgb2((ii-1)*n+1:ii*n , (jj-1)*n+1:jj*n , : ) = repmat(rgb1(ii , jj , : ) ,n ,n );

      end

end

imshow(rgb2)



答案:


clear all

k1=input('请输入彩图的行数(1-10之间的正整数):')

k2=input('请输入彩图的列数(1-10之间的正整数):')

n=input('请输入每个单元格的像素值(50-100之间的正整数):')

m=input('请输入彩图的刷新次数(1-100之间的正整数):')

for t=1:m                   %刷新m次,每次都重新生成新的随即彩图

     rgb1=rand(k1,k2,3);           %rgb1的初始化

     rgb2=zeros(k1*n,k2*n,3);   %rgb2的初始化

     %下面开始膨胀操作。

    for ii=1:k1             %ii代表行

          for jj=1:k2       %JJ代表列

              rgb2((ii-1)*n+1:ii*n , (jj-1)*n+1:jj*n , : ) = repmat(rgb1(ii , jj , : ) ,n ,n );

          end

    end

    imshow(rgb2)  %显示彩图rgb2

    hold on            %保持彩图窗口不动

    pause(2)           %持续2秒

end





作业1:编程输出类似如下的乘法口诀表

  

 

  答案:

for n=1:9
    for m=1:n
          fprintf('%d * %d =%d     ',n,m,n*m)
    end
    fprintf('\n')
end




作业2:求100-999之间的全部水仙花数。

水仙花数是指:一个三位数,其各位数字立方和等于该数本身。例如:370=33+73+03.这就说明370是一个水仙花数。

答案:


方法1:循环


for i=1:9

      for j=0:9

           for k=0:9

                  num=i*100+j*10+k;

                  if i^3+j^3+k^3==num

                      fprintf('找到一个水仙花数,为%d \n',num)

                  end

           end

       end

end




方法2:循环,使用str2num,num2str..


for n=100:999


      n_str=num2str(n);

      i =str2num(n_str(1));

      j =str2num(n_str(2));

      k=str2num(n_str(3));


      if  i^3+j^3+k^3==n

          fprintf('找到一个水仙花数,为%d \n',n)

       end

end





方法3:向量化编程

x=100:999;

x_1=fix(x/100);

x_2=fix(x/10)-x_1*10;

x_3=fix(x)-x_1*100-x_2*10;

loc=(x==(x_1.^3+x_2.^3+x_3.^3));

x(loc)


方法3:向量化编程--采用mod()函数


x=100:999;

x_1=mod( fix(x/100),10);

x_2=mod( fix(x/10),10);

x_3=mod( x,10);

loc=(x==(x_1.^3+x_2.^3+x_3.^3));

x(loc)





作业3:信用卡校验

当你输入信用卡号码的时候,有没有担心输错了而造成损失呢?其实可以不必这么担心,因为并不是一个随便的信用卡号码都是合法的,它必须通过Luhn算法来验证通过。


该校验的过程:

1、从卡号最后一位数字开始,逆向将奇数位(1、3、5等等)相加,得到s1

2、从卡号最后一位数字开始,逆向将偶数位数字,先乘以2(如果乘积为两位数,则将其减去9),再求和,得s2

3、将奇数位总和加上偶数位总和,既s=s1+s2,得出的s应该可以被10整除!如果S不能被10整除,则卡号是错误的。


例如,卡号:5432123456788881   (其逆向为:1888876543212345)

逆向奇数位为  1 8 8 6 4 2 2 4 ,求和 = 35

逆向偶数位乘以2(有些要减去9)的结果:7 7 5 1 6 2 6 1,求和 = 35。

最后 35 + 35 = 70 可以被10整除,则认定校验通过。


请编写一个程序,从标准输入获得卡号,然后判断是否校验通过。

通过显示:“卡号正确”,否则显示“卡号错误”。


比如,输入:356827027232780

程序输出:卡号正确


提示答案:


x=input('请输入卡号,并以单引号引住这串数字:')

y=x([end:-1:1])  %把字符数组x反向后给y

s_even=0;     %偶数位的和的计数器

s_odd=0;      %奇数位的和的计数器


for n=1:2:L     %处理奇数位

     t1=str2num(y(n));   %需把字符数组y里面的每个元素转为数字格式

     ??

end


for n=2:2:L     %处理偶数位

    t2=str2num(y(n));  %需把字符数组y里面的每个元素转为数字格式

   ??

end


total=(s_odd+s_even) 

if  ??

    fprintf('卡号正确 \n');

else

    fprintf('卡号错误 \n');

end


==================================================================


答案:

x=input('请输入卡号,并以单引号引住这串数字:')  %x='123467863265136'

y=x([end:-1:1])  %把字符数组x反向后给y

s_even=0;     %偶数位的和的计数器

s_odd=0;      %奇数位的和的计数器

L=length(x);


for  n=1:2:L     %处理奇数位

       t1=str2num(y(n));   %需把字符数组y里面的每个元素转为数字格式

       s_odd=s_odd+t1;

end


for n=2:2:L     %处理偶数位

    t2=str2num(y(n));  %需把字符数组y里面的每个元素转为数字格式

    if  t2*2>9   

        k=t2*2-9;

    else

        k=t2*2;

    end

    s_even=s_even+k;

end


total=(s_odd+s_even) 


if   mod(total,10)==0

     fprintf('卡号正确 \n');

else

     fprintf('卡号错误 \n');

end




作业4:计算圆周率

利用下列的公式求圆周率PI的值。至少选择以下公式中的3个编程计算圆周率的值。(注意,如果公式里出现阶乘,不要计算太多项,否则计算时间会过长)

这里给出第一个公式的求解代码:


%代码如下:


clear

t=1/2;

x1=sqrt(t);

y1=sqrt(t+t*x1);

for ii=1:20

     x1=x1*y1;

     y1=sqrt(t+t*y1);

end

p1=2/x1;     %p1为我们用公式计算的圆周率

vpa(p1)        %vpa显示p1的精确值

vpa(pi,50)    %作为对比,用vpa显示真实的π的前50位

计算前20项,已经精确到小数点后12位。



提示:以下公式编程时可能会用到阶乘,MATLAB里阶乘的函数为 factorial( )

factorial(n) 等价于 prod([1:n])

factorial(12)                 %  12的阶乘已经很大了

ans =

     479001600








作业5:采用for循环生成如下随机n*m格的彩图

功能1:可以自定义n和m的数量,以及每个格子的像素

功能2:通过循环、pause()函数等技巧,来让如上的随机彩图每隔2秒钟刷新一次,刷新得最终次数自己来确定。需要固定图像,既,需要在imshow后面加hold on命令,以保证每次刷新图像的时候,图像位置固定。

....

imshow(rgb2)

hold on


程序暂停功能——pause()函数使用例子:

x=linspace(0,9,10);

y=sin(x);

for k=1:10

      fprintf('当x=%f ,时,对应的y=%f    ', x(k),y(k) )

      pause()

end


clear all

k=3;             %设置网格为k*k

n=100;         %设置膨胀倍数n

rgb1=rand(k,k,3);           %rgb1的初始化

rgb2=zeros(k*n,k*n,3);   %rgb2的初始化


%下面开始膨胀操作。

for ii=1:k            %ii代表行

     for jj=1:k       %JJ代表列

          

      end

end

imshow(rgb2)



答案:

clear all

k1=input('请输入彩图的行数(1-10之间的正整数):')

k2=input('请输入彩图的列数(1-10之间的正整数):')

n=input('请输入每个单元格的像素值(50-100之间的正整数):')

m=input('请输入彩图的刷新次数(1-100之间的正整数):')


rgb=zeros(k1*n,k2*n,3);     %rgb的初始化

for t=1:m                   %刷新m次,每次都重新生成新的随即彩图

    for ii=1:k1             %ii代表行

         for jj=1:k2        %JJ代表列    

              rgb((ii-1)*n+1:ii*n , (jj-1)*n+1:jj*n , : ) = ones(n ,n ,3).*rand(1,1,3);

         end

    end

    imshow(rgb)        %显示彩图rgb

    hold on            %保持彩图窗口不动

    pause(2)           %持续2秒  


end




文字谜:山青与水秀x美=秀水与青山

其中“山青与水秀美”为1-9中的其中6个不同的数字,把这个6个数字编程找出来。

%方法1

A=[1:9]

for x1=A

    for x2=setdiff(A,x1)

        for x3=setdiff(A,[x1,x2])

            for x4=setdiff(A,[x1,x2,x3])

                for x5=setdiff(A,[x1,x2,x3,x4])

                    for x6=setdiff(A,[x1,x2,x3,x4,x5])

                        s1=x1*10000+x2*1000+x3*100+x4*10+x5;

                        k=x6;

                        s2=x5*10000+x4*1000+x3*100+x2*10+x1;

                         if  s1*k==s2

                             fprintf('%d*%d = %d  \n',s1,k,s2)

                         end

                    end                  

                end

            end

        end

    end

end


%方法2


for n=12345:50000

    k1=n;

    s=num2str(n);

    k2=str2num(s([end:-1:1]));

    for d=2:9

        if k1*d==k2

            n

            d

            break 

        end

    end

end




作业:图像的马赛克处理

马赛克的原理,就是把一个区域内的所有像素的值统一成一个值,消除像素之间的差异性。

要求:(1)先把一张彩色图片转换成灰度图。(2)把图片的行数和列数截取为100的整数倍,比如:如果图片大小为630*540,则保留为600*500。

(3)把该灰度图按照20*20像素区块进行马赛克化处理。然后显示原图与马赛克化后的对比图。

效果如下图:



clear all;       

pic_rgb=imread('D:\pic1.jpg');    %读入彩色图

w=50                                    %设置每个马赛克块的宽度

[row,col,d]=size(pic_rgb)     %测量彩色图的size

pic_r =pic_rgb(:,:,1);             %抽取R通道的矩阵给变量pic_r 

pic_g=pic_rgb(:,:,2);             %抽取G通道的矩阵给变量pic_b 

pic_b=pic_rgb(:,:,3);             %抽取B通道的矩阵给变量pic_g 


pic_gray=pic_r*0.299 +pic_g*0.587+pic_b*0.114;    %利用心理学公式合成

row_new=fix(row/100)*100;

col_new=fix(col/100)*100;

pic_msk=pic_gray(1:row_new,1:col_new);  %初始化马赛克图,即从灰度图里截取100的整数倍


for n=1:w:row_new

    for m=1:w:col_new

            p_tem=pic_msk(n:n+w-1,m:m+w-1);

            p_tem_mean=uint8(mean(p_tem(:)));

            pic_msk(n:n+w-1,m:m+w-1)=p_tem_mean;

    end

end


subplot(1,2,1), imshow(pic_gray)              

subplot(1,2,2), imshow(pic_msk)






2.6作业:


作业1:设计一个函数,调用此函数可以返回矩阵(或者数组)中最大值以及最小值元素和平均值等。



function  [ma,mi,ma_R,ma_C,mi_R,mi_C,pjz] = mymaxmin(A)

%此函数的功能是找到矩阵中的最大值及最小值,以及这两个最值对应的坐标。

[n,m]=size(A)


........

end



输入参数A为输入的一个矩阵或者数组。

返回参数ma,mi为找到的矩阵A中的最大值与最小值。

返回参数ma,mi,ma_R,ma_C,mi_R,mi_C为最大值与最小值所对应的行号和列号。

返回参数pjz为矩阵A中的平均值。

要求:不能用matlab自带的max/min等现成的函数,要自己用for循环、if判断、>=,等方式寻找最大与最小值。


效果如下:

用正态分布的随机矩阵(20行400列)测试:


自己手写一个求数组最大值的代码,代替matlab自带的max()函数。供参考

x=randi(50,1,15)

ma=-inf

for j=1:1

    for k=1:15

        if x(j,k)>ma

            ma=x(j,k);

        end

    end

end

ma



答案:


function  [ma,mi,ma_R,ma_C,mi_R,mi_C,pjz] = mymaxmin(A)

%此函数的功能是找到矩阵中的最大值及最小值,以及这两个最值对应的坐标。


[m,n]=size(A);

ma=-inf;

mi=inf;

total=0;

for i=1:m

     for j=1:n

         

         if  A(i,j)>ma

             ma=A(i,j);

             ma_R=i;

             ma_C=j;

         end

         

         if  A(i,j)<mi

             mi=A(i,j);

             mi_R=i;

             mi_C=j;

         end

         

         total=total+A(i,j);

     end

end


pjz=total/(m*n);


end





作业2:试着看看能否自己设计一个函数,比如命名为myfind.m, 实现matlab自带的find函数的类似功能?


function  [ A_k A_k_R , A_k_C ] = myfind(A , k , w )

%此函数的功能是找到矩阵A中的大于k(当W=1时),或者小于k(当W=0时)的元素

.......

end



输入参数A为输入的一个矩阵或者数组。

输入参数W只能为1或者0;k=1时找到矩阵A中的大于等于k的所有元素,k=0时找到矩阵A中的小于等于k的所有元素。

返回参数 A_k , A_k_R , A_k_C3个数组,分别记录按照要求找到的元素,以及这些元素对应的行号和列号 。

要求:

(1)不能用matlab自带的find等现成的函数,要自己用for循环、if判断、>=,等方式寻找最大与最小值。

(2)如果对方输入的参数w 不是0或者1,则要求对方重新输入正确的值。

(3)如果没有找人任何符合要求的元素,则打印输出一句话“很抱歉,没有找到符合条件的元素。”


基本测试:






输入参数有误时的测试:





答案:


function  [ A_k , A_k_R , A_k_C ] = myfind(A , k , w )

%此函数的功能是找到矩阵A中的大于k(当W=1时),或者小于k(当W=0时)的元素。


while   ( w~=0)&( w~=1)

        fprintf('输入有误,w的值必须是0或者1 \n');

        w =input('请重新输入 w =');

end


[m,n]=size(A);

A_k=[];


if  w==1

    fprintf('即将为您寻找矩阵%c %c %f  的所有元素。 \n' ,'A' ,'>',k);    

    Num=0;

    for ii=1:m

        for jj=1:n

            

            if  A(ii,jj)>=k

                Num=Num+1;

                A_k(Num)=A(ii,jj);

                A_k_R(Num)=ii;

                A_k_C(Num)=jj;

            end

            

        end

    end

    

end



if w==0

    fprintf('即将为您寻找矩阵%c %c %f  的所有元素。 \n' ,'A' ,'<',k);

    Num=0;

    for ii=1:m

        for jj=1:n

            

            if  A(ii,jj)<=k

                Num=Num+1;

                A_k(Num)=A(ii,jj);

                A_k_R(Num)=ii;

                A_k_C(Num)=jj;

            end      

            

        end

    end

end


end



作业3:编写一个名为is_prim()的函数。调用方式为 y=is_prim(n)

此函数可以实现的功能为:对输入的一个大于1的整数n进行判断其是否是素数,如果是素数则返回y=1,否则返回y=0(并给出原因,比如该数可以分解成某两个大于1的整数的乘积)


function y = is_prime(N)  

%子函数 is_prime(N)用于判断给定的数N是否是素数

%如果给定的N是素数,则返回1,否则返回0

flag=0;                %用flag来记录N的因子的个数,初始值为0

m=fix(sqrt(N));    %寻找N的因子时,只需要试到fix(sqrt(N))

for k=2:m

    if mod(N,k)==0  %如果能被2-m之间的某个数整除,说明找到了一个因子

        flag=flag+1;   %因子记录器加1

        break              %跳出循环,节约时间

    end

end


if flag==0           %如果flag==0 ,说明前面没有找到N的因子,既N是素数,返回1

    y=1;

else

    y=0;

end


end




作业4:编写一个名为函数zxgbs(X1,X2)的函数,

实现求最小公倍数的功能,即调用该函数,输入两个正整数x1,x2,则返回这两个正整数的最小公倍数。如:zxgbs(10,15),则返回y=30;

提示:两个正整数的最小公倍数,等于,这两个正整数的乘积,除以这两个正整数的最大公约数。最大公约数可以使用for循环来寻找


y = zxgbs(10,15)



function  y = zxgbs(x1,x2) 

%函数zxgbs(x1,x2) 用于计算x1和x2的最小公倍数


M=fix(min(x1,x2)/2);       %只需计算到x1和x2中最小那个的一半即可

zdgys=1;                         %最大公约数初始化为1

for k=2:M

    if rem(x1,k)==0&rem(x2,k)==0    %如果k能同时整除x1和x2

        zdgys=k                   %则把最大公约数更新为k

    end

end

y=x1*x2/zdgys;

end





作业5:编写一个彩色图像的马赛克处理函数

调用格式为 p_msk = mymsk( pic , w ) pic为输入的原始彩色图片,W为马赛克的宽度,p_msk为函数处理后输出的马赛克处理后的图片

mymsk函数内部处理过程:

步骤1:把图片的行数和列数截取为100的整数倍,得到pic_new,比如:如果原始图片大小为630*540,则pic_new为600*500。

步骤2:把输入的彩色图片pic_new的r,g,b三个通道抽出,分别给pic_new_r, pic_new_g, pic_new_b,

步骤3:分别把pic_new_r, pic_new_g, pic_new_b这三个灰度图,按照w*w像素区块进行马赛克化处理,得到三个马赛克化后的图

步骤4:再把步骤3得到的三个通道的马赛克图利用cat()函数重新拼接成一个彩色图p_msk


在主程序中调用后的效果如下图:



clear all;       

pic=imread('E:\pic17.jpeg'); %读入彩色图

w=20;                        %设置马赛克宽度参数                

p_msk = mymsk( pic , w);     %调用mymsk()函数,得到马赛克后的图片p_msk

subplot(1,2,1), imshow(pic)  %显示原图与马赛克后的对比图        

subplot(1,2,2), imshow(p_msk)


function   p_msk = mymsk( pic , w ) 

% 该函数可以把一个彩色图片进行马赛克处理

% 调用格式为 p_msk = mymsk( pic , w ) 

% pic为输入的原始彩色图片,W为马赛克的宽度,p_msk为函数处理后输出的马赛克处理后的图片。


[row,col,d]=size(pic);     %测量彩色图的size


row_new=fix(row/100)*100; 

col_new=fix(col/100)*100;

pic_new=pic(1:row_new,1:col_new,:);    %初始化马赛克图,即从灰度图里截取100的整数倍


pic_new_r = pic_new(:,:,1);             %抽取R通道的矩阵给变量pic_r 

pic_new_g = pic_new(:,:,2);             %抽取G通道的矩阵给变量pic_b 

pic_new_b = pic_new(:,:,3);             %抽取B通道的矩阵给变量pic_g 



for n=1:w:row_new

    for m=1:w:col_new

            p_tem_r=pic_new_r(n:n+w-1,m:m+w-1);   %抠出当前处理的20*20的区域给p_tem

            p_tem_mean_r=uint8(mean(p_tem_r(:)));   %求p_tem中的平均值,然后再转换成uint8格式

            pic_new_r(n:n+w-1,m:m+w-1)=p_tem_mean_r;  %把这个平均值重新赋值给当前的20*20区域


            p_tem_g=pic_new_g(n:n+w-1,m:m+w-1);   %抠出当前处理的20*20的区域给p_tem

            p_tem_mean_g=uint8(mean(p_tem_g(:)));   %求p_tem中的平均值,然后再转换成uint8格式

            pic_new_g(n:n+w-1,m:m+w-1)=p_tem_mean_g;  %把这个平均值重新赋值给当前的20*20区域

            

            p_tem_b=pic_new_b(n:n+w-1,m:m+w-1);   %抠出当前处理的20*20的区域给p_tem

            p_tem_mean_b=uint8(mean(p_tem_b(:)));   %求p_tem中的平均值,然后再转换成uint8格式

            pic_new_b(n:n+w-1,m:m+w-1)=p_tem_mean_b;  %把这个平均值重新赋值给当前的20*20区域

    end

end


p_msk=cat(3,pic_new_r,pic_new_g,pic_new_b);

end







作业:素数问题


(1)编写函数求解给定整数N之内的所有素数;

要求:采用主函数与子函数的模式,子函数is_prime(K)用来判断k是否是素数,如果是,则返回1,否则返回0;主函数则用来遍历2-N之间的每一个整数,如果该数是素数则记录到数组中,并且计数器加1,最终函数返回记录了N之内的所有素数的数组,以及素数的个数。

以下为(1)的提示性代码,供参考;

function [prime,num] = prime_N(N)      %主函数prime_N()

%此函数用于找出给定的N之内的所有素数

% 函数[prime,num] = prime_N(N) 中,返回的数组prime记录了N之内的所有素数,

%num记录了N之内的素数的总数。

num=0;           %Num记录发现的素数的个数,初始值为0

%采用for循环,挨个判断2-N之间的每一个数是否为素数。

%判断某个数是否为素数的任务通过调用子函数is_prime() 完成。


end


function y = is_prime(N)                 %子函数is_prime()

%子函数is_prime(N)用于判断给定的数N是否是素数

%如果给定的N是素数,则返回1,否则返回0

flag=0;                %用flag来记录N的因子的个数,初始值为0

m=fix(sqrt(N));    %寻找N的因子时,只需要试到fix(sqrt(N))

%for循环来历遍2-m之间的所有数,如果N能被2-m之间的某个数整除,说明找到了一个因子,则因子记录器flag加1,并跳出循环

%如果flag==0 ,说明前面没有找到N的因子,既N是素数,返回1,否则返回0

end



调用效果如下:



(2)编写脚本文件,通过调用prime_N()函数,找出1000之内的所有孪生素数对,并输出这些孪生素数对。

% 该问的提示性代码:

N=1000;

[prime,num] = prime_N(N) 

total=0;

for k=1:num-1

     if  ??

         total=total+1;

         fprintf('找到一对孪生素数:%d  , %d  \n' ,prime(k), prime(k+1) );

     end

end

fprintf('%d 之内共找到%d对孪生素数 \n' ,N, total );


效果如下:



答案:


%调用代码

N=1000;

[prime,num] = prime_N(N) 

total=0;


for k=1:num-1

     if  prime(k+1)-prime(k)==2

         total=total+1;

         fprintf('找到一对孪生素数:%d  , %d  \n' ,prime(k), prime(k+1) );

     end

end


fprintf('%d 之内共找到%d对孪生素数 \n' ,N, total );


=======================================================


%函数代码

function [prime,num] = prime_N(N)   %主函数

%此函数用于找出给定的N之内的所有素数

% 函数[prime,num] = prime_N(N) 中,返回的数组prime记录了N之内的所有素数,

%num记录了N之内的素数的总数。

while N<2|mod(N,1)~=0                 %用于保证输入的参数N必为大于1的正整数

         N=input('请输入一个大于等于2的正整数')

end   

num=0;                      %Num记录发现的素数的个数,初始值为0

for k=2:N

    if  is_prime(k)==1   %调用子函数prime_pd(k),来判断k是否为素数

        num=num+1;      %如果是素数,则计数器加1

        prime(num)=k;     %并把素数k存到数组 prime中

    end

end


end


function y = is_prime(N)  

%子函数 is_prime(N)用于判断给定的数N是否是素数

%如果给定的N是素数,则返回1,否则返回0

flag=0;                %用flag来记录N的因子的个数,初始值为0

m=fix(sqrt(N));    %寻找N的因子时,只需要试到fix(sqrt(N))

for k=2:m

    if mod(N,k)==0  %如果能被2-m之间的某个数整除,说明找到了一个因子

        flag=flag+1;   %因子记录器加1

        break              %跳出循环,节约时间

    end

end


if flag==0           %如果flag==0 ,说明前面没有找到N的因子,既N是素数,返回1

    y=1;

else

    y=0;

end


end




3X+1猜想:

%版权:gdcp_ccl_20210601


clear all

N=input('input=');   %比如6171

N=abs( fix(N) );     %或者: N=uint32(N) ;  防止有人输入的数有小数点,或者是负数。 

m=[];        %用数组m来存储3x+1序列中的各个数

k=1;          %k表示数组m的下标,初始值为1

m(k)=N;    %显然,数组m中的第一个元素为N


%生成3x+1序列

while m(k)~=1           %如果数组m中当前元素不为1,则继续,否则停止计算

    if  mod(m(k),2)~=0  %如果当前元素为奇数,则乘三加一

        m(k+1)=3*m(k)+1;

    else                           %如果当前元素为偶数,则除2

        m(k+1)=m(k)/2;

    end

    k=k+1;                    %下标加1,把下一个元素当成“当前”元素。

end



%计算3x+1序列中的长度,最大值,最大值和输入值之间的比例

L=numel(m);

m_max=max(m);

Ratio=m_max/N;


%输出3x+1序列,每行10个

for k=1:L

    fprintf('%8d',m(k))

    if mod(k,10)==0           %每输出10个,回车一次

       fprintf('\n')

    end

end


fprintf('\n')

%输出3x+1序列的相关参数

fprintf('数字%d的3x+1序列长度 = %d \n', N,L );

fprintf('数字%d的3x+1序列中的最大值 = %d \n', N,m_max );

fprintf('数字%d的3x+1序列中的最大值与初始值的比值为 = %d \n', N,Ratio );


plot(m,'*-')           %画出该数字的3x+1序列的图




作业4:编写一个中值滤波函数:zzlb() , 用于滤除图像的椒盐噪声


%以下代码为提示性代码:


function  pic_new=zzlb(pic_old)             


% 本函数可以对充满椒盐噪声的图像进行滤波,返回滤除椒盐噪声后的干净图像

%函数pic_new=zzlb(pic_old)中,输入参数pic_old为含有椒盐噪声的原始图像(uint8格式)

%函数返回值pic_new则为消除了椒盐噪声后的干净图像

[n,m,d]=size(pic_old)     %获取图像pic_old的维度


%判断d等1还是等于3?如果等于1,则pic_old为灰度图,执行以下操作


%对pic_old进行边界填充,得到膨胀了一圈的图像pic2(n+2行,m+2列


%采用双层for循环,对pic2进行中值滤波,得到滤波后的干净图像pic3


%把pic3瘦一圈,变成n行m列后,赋值给pic_new


for i=2:n+1

      for j=2:m+1

..........

..........

..........


%如果d=3,则表示pic_old为彩色图,这时,需要对RBG每一个通道都进行上述类似的中值滤波,

%得到3个滤波后的2维数组,再合并成一个3维数组,即彩色的pic_new

..........

..........

..........


end



========================================




答案:


function p_new = zzlb(p_noise)

% 本函数可以对充满椒盐噪声的图像进行滤波,返回滤除椒盐噪声后的干净图像

%函数pic_new=zzlb(p_noise)中,输入参数p_noise为含有椒盐噪声的原始图像(uint8格式)

%函数返回值pic_new则为消除了椒盐噪声后的干净图像

%版权:gdcp_ccl_2021_05_25


p_new =p_noise;  %p_noise用于被观察,修改则在p_new上进行,两者功能分开

[row,col,d]=size(p_noise);      %测量输入图像的尺寸  


if d==1

%对原始图像p_noise边界填充生成胖一圈的图像p,在p上进行历遍操作

    p=[ p_noise(1,1)    ,   p_noise(1,:)    ,   p_noise(1,col);

          p_noise(:,1)     ,   p_noise          ,   p_noise(:,col);

          p_noise(row,1),   p_noise(row,:) , p_noise(row,col)]; 


 

    for n=2:row+1       %在新图p的2到row+1行,2到col+1列的区域历遍(即原图范围)

        for m=2:col+1

            if  p(n,m)==255|p(n,m)==0   %如果当前点为极端值(0或255)

                tem=p(n-1:n+1,m-1:m+1);    %以当前点为中心,构建一个3*3的临时矩阵

                md=median(tem(:));              %找出这个矩阵所有元素的中位数

                p_new(n-1,m-1)=md;        %则用刚才找到的中位数代替该极端值

            end

        end

    end

 


end


if d==3               %如果是rgb彩图,则拆解成三个通道,对每个通道分别进行中值滤波

    p_new(:,:,1) = zzlb(p_noise(:,:,1));   %红通道递归调用zzlv函数,进行降噪

    p_new(:,:,2) = zzlb(p_noise(:,:,2));   %绿通道递归调用zzlv函数,进行降噪

    p_new(:,:,3) = zzlb(p_noise(:,:,3));   %蓝通道递归调用zzlv函数,进行降噪

end


end




调用和使用上述函数,示例:

p_noise=imread('D:\matlab2021\pic\yujinxiang_rgb_saltpepper.png');

p_new = zzlb(p_noise);

subplot(1,2,1),imshow(p_noise);

subplot(1,2,2),imshow(p_new);




如果不扩边,则答案:

%调用代码

p_noise=imread('C:\Users\Administrator\Desktop\p2.png');   %读入带噪点的图像,作为矩阵给p_noise

p_new = zzlb(p_noise);                   %用zzlb函数处理带噪声的图像p_noise,生成干净的图像给p_new

subplot(1,2,1),imshow(p_noise);     %子图1,显示原始的带噪声的图像p_noise

subplot(1,2,2),imshow(p_new);       %子图2,显示干净的图像p_new


========================================================


%函数代码

function p_new = zzlb(p_noise)

% 本函数可以对充满椒盐噪声的图像进行滤波,返回滤除椒盐噪声后的干净图像

%函数pic_new=zzlb(p_noise)中,输入参数p_noise为含有椒盐噪声的原始图像(uint8格式)

%函数返回值pic_new则为消除了椒盐噪声后的干净图像


p_new =p_noise;     %p_noise用于被观察,修改则在p_new上进行,两者功能分开

[row,col,d]=size(p_noise);      %测量图像的尺寸  


if d==1    %灰度图时的处理方式

    for n=2:row-1       %在p_noise的2到row-1行、2到col-1列的区域历遍

        for m=2:col-1

            if  p_noise(n,m)==255|p_noise(n,m)==0   %如果当前点为极端值(0或255),既噪声。

                  tem=p_noise(n-1:n+1,m-1:m+1);       %以当前点为中心,构建一个3*3的临时矩阵

                  md=median(tem(:));                %找出这个矩阵所有元素的中位数   

                  p_new(n,m)=md;                     %则用刚才找到的中位数代替该极端值

              end

        end

    end

end


if d==3               %如果是rgb彩图,则拆解成三个通道,对每个通道分别进行中值滤波

    p_new(:,:,1) = zzlb(p_noise(:,:,1));   %红通道递归调用zzlv函数,进行降噪

    p_new(:,:,2) = zzlb(p_noise(:,:,2));   %绿通道递归调用zzlv函数,进行降噪

    p_new(:,:,3) = zzlb(p_noise(:,:,3));   %蓝通道递归调用zzlv函数,进行降噪

end


end





作业所用含椒盐噪声图像如下:









3X+1猜想:

%版权:gdcp_ccl_20210601


clear all

N=17         %比如17

m=[];         %用数组m来存储3x+1序列中的各个数

k=1;           %k表示数组m的下标,初始值为1

m(k)=N;     %显然,数组m中的第一个元素为N


%生成3x+1序列

while m(k)~=1           %如果数组m中当前元素不为1,则继续,否则停止计算

    if  mod(m(k),2)~=0  %如果当前元素为奇数,则乘三加一

        m(k+1)=3*m(k)+1;

    else                           %如果当前元素为偶数,则除2

        m(k+1)=m(k)/2;

    end

    k=k+1;                    %下标加1,把下一个元素当成“当前”元素。

end


%计算3x+1序列中的长度,最大值,最大值和输入值之间的比例

L=numel(m);

m_max=max(m);

Ratio=m_max/N;


%输出3x+1序列,每行10个

fprintf('数字%d的3X+1序列如下: \n ',N)


for k=1:L

    fprintf('%8d',m(k))

    if mod(k,10)==0           %每输出10个,回车一次

       fprintf('\n ')

    end

end


fprintf('\n')


%输出3x+1序列的相关参数

fprintf('数字%d的3x+1序列长度 = %d \n ', N,L );

fprintf('数字%d的3x+1序列中的最大值 = %d \n ', N,m_max );

fprintf('数字%d的3x+1序列中的最大值与初始值的比值为 = %d \n ', N,Ratio );


plot(m,'*-')           %画出该数字的3x+1序列的图










第三章作业



第四章作业