8.9.4 继承性及其应用
8.9.4.3 利用继承性创建子类的示例
【例 8.9.4 .3-1 】把例 8.9.2-1 构成的队列作为父类,利用继承性,创建 stack 堆栈子类。
(1)建立类目录 @stack ,并使它成为当前目录 (以下指令仅对 5.3 版适用)
mkdir('e:\mat53\work','@stack') % 在 e:\mat53\work 上建子目录 @stack
cd e:\mat53\work\@stack % 是子目录 @stack 成为当前目录
(2)编写堆栈类的构造函数 @stack\stack.m
[@stack\stack.m]
function ST=stack(v)
% 调用格式
% ST=stack 创建一个 " 空 " 堆栈对象 .
% ST=stack(v) 创建包含变量 v 的堆栈对象。
if nargin>1;error( 'Too many arguments.' ); end ;
if nargin==0 % 没有输入宗量情况
Q=queue;
s.value=[]; % value 域被赋“空阵”
s.name= '' ; % name 域不给任何字符
elseif isa(v, 'stack' ); % 输入宗量是同类对象情况
s=v; % 直接把输入量赋给 q
Q=queue(evalin( 'caller' ,inputname(1))); % 生成队列对象
else % 非同类输入宗量情况
s.value=v; % 在 value 域中放置输入对象 v 的内容
s.name=inputname(1); % 在 name 域中放置输入对象名 v 字符
if isempty(s.name) % 假如输入量无名
s.name=[ '(' class(v) ')' ]; % 就采用 v 本身的类名
end
Q=queue(evalin( 'caller' ,inputname(1))); % 生成队列对象
end
ST=class(s, 'stack' ,Q); % 产生继承父类对象 Q 性质的 ST 堆栈子类
【 * 例 8.9.4 .3-2 】本例目的之一是:检查上例构造函数设计的正确性。目的之二是:观察堆栈关于队列的显示,类别判断和为 “空”判断性质的继承。
(1)堆栈对象的创建,及由于继承性,而获得正确显示。
AA=' 继承性 ';
ST=stack(AA)
ST=
AA: 继承性
(2)类别检查
class(ST)
ans =
stack
(3)由于在此设计采用了继承性,所以“是堆栈,就一定是队列”。
isa(ST,'stack')
isa(ST,'queue')
ans =
1
ans =
1
(4)检查对 isempty.m 是被继承
isempty(ST)
ans =
0
【 * 例 8.9.4 .3-3 】本例通过堆栈类对象的“压入”和“弹出”操作,进一步观察继承性。
(1)把元素压入堆栈
BB=1:6;CC=sym('x^2+4*x');
comein(ST,BB,CC)
ST=
[ 1*3 stack ]
(2)显示堆栈中第三元素的内容
display(ST,3)
The content of ST(3)
is a 'sym' object
CC=
x^2+4*x
(3)从堆栈弹出元素
[Name1,Value1,ST_1]=goout(ST)
Name1 =
AA
Value1 =
继承性
ST_1=
[ 1*2 stack ]
Wednesday, May 14, 2008
matlab 从queue 类构建stack类的全过程
Posted by
Cammie
at
8:37 PM
0
comments
Labels: matlab
matlab FIFO 队列 queue 类的全过程
8.9 面向对象编程
8.9.2 面向对象编程应用示例
【例 8.9.2 -1 】本例演示:创建“先进先出” FIFO 队列 queue 类的全过程。在本例中,读者应充分注意:构架域( Fields of a structure array )和定义在其上的方法函数( Method function )之间的关系。
(1)建立类目录 @queue
(2)选择构架数组为 queue 类的数据结构
(3)创建构造函数 queue.m
[@queue\queue.m]
function q=queue(v)
%@QUEUE\QUEUE queue class constructor function
% 调用格式
% q=queue 创建一个 " 空 " 队列对象 .
% q=queue(v) 创建包含变量 v 的队列对象。
superiorto( 'double' , 'sparse' , 'struct' , 'cell' , 'char' , 'inline' , 'sym' );
% 使 queue 对象具有最高优先级 <6>
if nargin>1;error( 'Too many arguments.' ); end ;
if nargin==0 % 没有输入宗量情况
q.value=[]; % value 域被赋“空阵”
q.name= '' ; % name 域不给任何字符
q=class(q, 'queue' ); % 给变量 q 挂上 queue 标签
elseif isa(v, 'queue' ); % 输入宗量是同类对象情况
q=v; % 直接把输入量赋给 q
else % 非同类输入宗量情况
q.value=v; % 在 value 域中放置输入对象 v 的内容
q.name=inputname(1); % 在 name 域中放置输入对象名 v 字符
if isempty(q.name) % 假如输入量无名
q.name=[ '(' class(v) ')' ]; % 就采用 v 本身的类名
end
q=class(q, 'queue' ); % 给变量 q 挂上 queue 标签 <20>
end
(4)为 queue 对象编写显示函数 display.m
[@queue\display.m]
function display(q,ki,kj)
%QUEUE\DISPLAY command window display of a queue object.
% 调用格式
% display(q) 笼统显示整个队列
% display(q,ki) 单下标法显示具体队列元素的内容
% display(q,ki,kj) 双下标法显示具体队列元素的内容
if nargin==0;error( ' 缺少输入宗量,即被显示对象 ! ' ); end
switch nargin
case 1 % 显示整个队列
[m,n]=size(q);
vname=inputname(1); % 被显示对象 q 的名称
if isempty(vname) % 显示对象若无名称
fprintf( 'ans=\n' ); % 按 MATLAB 惯例,屏幕显示 ans 缺省名
elseif fprintf( '%s=\n' ,vname); % 对象有名称时,则屏幕以字符串形式显示名称
end ;
if isempty(q) % 假如被显示对象为“空”
fprintf( ' [ empty ' ) %<17>
fprintf( '%s' ,class(q)) %<18>
fprintf( ' ]\n\n' ); %<19>
elseif m*n==1; % 被显示对象今包含一个“元素”时
fprintf( ' %s: ' ,q.name); % 屏幕先以字符串形式显示所存放对象的名称
disp(q.value); % 紧接着,不换行,显示所存放对象的内容
fprintf( '\n' );
else % 被显示对象今包含多个“元素”时
fprintf( ' [ %d*%d ' ,m,n) % 以下 3 条指令只显示队列“元素”排列 <25>
fprintf( '%s' ,class(q)) %<26>
fprintf( ' ]\n\n' ); %<27>
end
case 2 % 单下标法显示具体队列元素的内容
disp([ 'The content of ' ,inputname(1), '(' ,int2str(ki), ')' ])
disp([ 'is a ''' ,class(q(ki).value), ''' object' ])
fprintf( ' %s=\n' ,q(ki).name);
disp(q(ki).value);
fprintf( '\n' );
case 3 % 双下标法显示具体队列元素的内容
disp([ 'The content of ' ,inputname(1), '(' ,int2str(ki), ',' ,int2str(kj), ')' ])
disp([ 'is a ''' ,class(q(ki,kj).value), ''' object' ])
fprintf( ' %s=\n' ,q(ki,kj).name);
disp(q(ki,kj).value);
fprintf( '\n' );
end
(5)编写重载函数 isempty.m
[@queue\isempty.m]
function f=isempty(q)
%@QUEUE\ISEMPTY True for an empty queue object.
f=0;
[m,n]=size(q);
if m*n==1;
if isempty(q.value) & isempty(q.name) %<6>
f=1;
end ;
end ;
(6)编写“入队”、“离队”函数
[ @queue\comein.m]
function q=comein(p,varargin)
% @QUEUE\COMEIN a variable comes to the end of a queue.
% 调用格式
% comein(p,a,b,...) 使输入宗量 a,b 等排在 p 之后形成新队列,
% 其名沿用 p 位置上的输入队列名 .
% q=comein(p,a,b,...) 使输入宗量 a,b 等排在 p 之后形成新队列 q .
if nargin<2 error( 'comein needs at least two arguments.' ); end ;
if ~isa(p, 'queue' ) error([inputname(1), ' is not a queue' ]); end ;
q0=p;
qzzy=class(p); % 获取第一输入宗量的类别字符串 <10>
for i=1:length(varargin)
temp=varargin{i};
s=eval([qzzy, '(temp)' ]); % 使后来元素成为与第一输入宗量相同的类别 <13>
s.name=inputname(i+1);
if isempty(s.name) % 假如某输入宗量本身无名称
s.name=[ '(' class(temp) ')' ]; % 则把它的类别名作为名称使用
end
if isempty(q0) % 假如前队列是“空”队列
q0=s; % 则直接进入队列
else % 假如前队列非“空”
q0=[q0 s]; % 则新变量排在队尾
end
end
if nargout==0; % 假如没有输出宗量
assignin( 'caller' ,inputname(1),q0); % 新队列沿用第一个输入队列名
evalin( 'caller' ,inputname(1));
else % 假如有输入输出宗量
q=q0; % 新队列名为 q
end
[@queue\goout.m]
function [n,v,q]=goout(p)
% @QUEUE\GOOUT removes the first(the front) element from a queue.
% 调用格式
% goout(p) 从队列 p 中的第一个元素离队 .
% v=goout(p) v 是从 p 队列中移出的那第一个元素的“值”
% [n,v]=goout(p) n,v 分别 是从 p 队列中移出的那第一个元素的“名称”和“值”
% [n,v,q]=goout(p) n,v 分别 是从 p 队列中移出的那第一个元素的“名称”和“值”
% q 是被移去第一个元素后的新队列
if nargin==0 ;error( 'No queue specifide.' ); end ;
if nargout>3;error( 'Too many output arguments.' ); end ;
if nargin>1 error( 'Too many input arguments.' ); end ;
if ~isa(p, 'queue' );error([inputname(1), ' is not a queue.' ]); end ;
if isempty(p)
q1=p;
else
[m,n]=size(p);
v1=p(1).value;n1=p(1).name;
if m*n==1
q1=queue;
else
q1=p(2:end);
end
end
if nargout<3;
assignin( 'caller' ,inputname(1),q1);
end ;
if nargout==0,
evalin( 'caller' ,inputname(1));
end
if nargout>=1;v=v1; end ;
if nargout>=2;n=n1; end ;
if nargout==3;q=q1; end ;
【 * 例 8.9.2 -2 】本例的目的:一,检验例 8.9.2-1 所编写的程序的正确性;二,演示所设计的新类是如何被运作的。
(1)创建一个队列对象,并显示。
qe='Hello! 你好 ! '; % 字符串
Q=queue(qe) % 生成队列对象 Q ,并显示
Q=
qe: Hello! 你好 !
(2)类别检查和是否对象判断
class(Q) % 类别检查
isobject(Q) % 是否对象判断
isa(Q,'queue') % 是否队列判断
ans =
queue
ans =
1
ans =
1
(3)是否“空”队列判断
isempty(Q)
ans =
0
【 * 例 8.9.2 -3 】本例目的:一,演示“入队”、“离队”函数的调用方法;二,演示 @queue\display 显示队列具体元素细节的功能。
(1)利用“入队”函数,使队列变长。
a=[1,2,3;4,5,6];b{1}='This';b{2}=' is ';b{3}='a cell array';
comein(Q,a,b) % 增长队列,并显示整个队列的“宏观”情况
Q=
[ 1*3 queue ]
(2)显示队列 Q 中具体元素的内容
display(Q,2) % 给出 Q 队列第 2 个元素的类别、内容:变量名和值
The content of Q(2)
is a 'double' object
a=
1 2 3
4 5 6
(3)把 Q 队列第 1 个元素和其余部分分离,并生成新队列 QQ
[nn,vv,QQ]=goout(Q)
nn =
qe
vv =
Hello! 你好 !
QQ=
[ 1*2 queue ]
(4)采用双下标法,显示 QQ(1,2) 的内容
display(QQ,1,2)
The content of QQ(1,2)
is a 'cell' object
b=
'This' ' is ' 'a cell array'
【例 8.9.2 -4 】利用指令 methods 可以获知对任何类定义的(在类目录上的)所有方法函数。
methods queue
Methods for class queue:
comein display goout isempty queue
Posted by
Cammie
at
8:35 PM
0
comments
Labels: matlab
Tuesday, November 13, 2007
use 'printf' in matlab
Posted by
Cammie
at
7:34 AM
0
comments
Labels: matlab, programming, source code
random number generator
1. sources
Intro
This tutorial provides a brief introduction to the random number functions that come as part of the C++ standard library, namely rand() and srand().
rand() and RAND_MAX
The C++ standard library includes a pseudo random number generator for generating random numbers. In order to use it we need to include the
Here's a piece of code that will generate a single random number:
#include
#include
using namespace std;
int main()
{
int random_integer = rand();
cout <<>
#include
#include
using namespace std;
int main()
{
cout << "The value of RAND_MAX is " <<>
The pseudo random number generator produces a sequence of numbers that gives the appearance of being random, when in fact the sequence will eventually repeat and is predictable.
We can seed the generator with the srand() function. This will start the generator from a point in the sequence that is dependent on the value we pass as an argument. If we seed the generator once with a variable value, for instance the system time, before our first call of rand() we can generate numbers that are random enough for simple use (though not for serious statistical purposes).
In our earlier example the program would have generated the same number each time we ran it because the generator would have been seeded with the same default value each time. The following code will seed the generator with the system time then output a single random number, which should be different each time we run the program.
#include
#include
#include
using namespace std;
int main()
{
srand((unsigned)time(0));
int random_integer = rand();
cout <<>
Generating a number in a specific range
If we want to produce numbers in a specific range, rather than between 0 and RAND_MAX, we can use the modulo operator. It's not the best way to generate a range but it's the simplest. If we use rand()%n we generate a number from 0 to n-1. By adding an offset to the result we can produce a range that is not zero based. The following code will produce 20 random numbers from 1 to 10:
#include
#include
#include
using namespace std;
int main()
{
srand((unsigned)time(0));
int random_integer;
for(int index=0; index<20; random_integer =" (rand()%10)+1;">
#include
#include
#include
using namespace std;
int main()
{
srand((unsigned)time(0));
int random_integer;
int lowest=1, highest=10;
int range=(highest-lowest)+1;
for(int index=0; index<20; random_integer =" lowest+int(range*rand()/(RAND_MAX">
Conclusion
If you need to use a pseudo random number generator for anything even remotely serious you should avoid the simple generator that comes with your compiler and use something more sophisticated instead. That said, rand() still has its place and you may find it useful.
Posted by
Cammie
at
7:04 AM
0
comments
Labels: algorithm, c++, matlab, programming, source code