ITEEDU

自测练习

4.1 填空:

a)清单和表格值存放在——中。

b)数组元素的关系是——和——相同。

c)用于引用数组中特定元素的数字称为数组的——。

d)——用于声明数组长度,使程序伸缩性更强。

c)将数组元素按顺序排列的过程称为数组——。

f)确定数组中是否包含某个键值的过程称为数组——·

g)使用两个下标的数组称为——数组。

4.2 判断下列各题是否正确。如果不正确,请说明原因。

a)数组可以存放许多不同类型的数值。

b)数组下标通常为float数据类型。

c)如果初始化值列表中的初始化值少于数组元素个数,则其余元素自动初始化为初始化值列表中的最后一个值。

d)初始化值列表中的初始化值多于数组元素个数是个错误。

e)将单个数组元素传给函数并修改该元素值,那么在被调用函数执行结束时仍保留修改后的值。

4.3 回答下列关于数组fractions的问题:

a)定义常变量arraySize,初始化为10。

b)声明数组的arraySize元素类型为float,并将元素初始化为0。

c)数组开头第4个元素的名称。

d)引用数组元素4。

e)将数值1.667赋给数组元素9。

f)将3.333赋给数组第7个元素。

g)打印数组元素6和9,小数点后面为两位精度,并显示屏幕输出。

h)用for重复结构打印数组的所有元素。定义整型变量x为循环控制变量。显示输出。

4.4 回答下列关于数组table的问题:

a)声明3行3列的整型数组。假设定义常量变量arraySize为3。

b)数组包含多少元素。

c)用for重复结构初始化数组每个元素为该元素下标的和。假设声明整型变量x和y为循

环控制变量。

d)编写一个程序段,以3行3列的表格形式打印每个数组元素值。假设用下列声明初始化数组:

int   table[arraySize][arraySize] ={ { 1, 8 }, { 2, 4, 6 }, { 5 } };  

并声明整型变量x和y为循环控制变量。显示输出。

4.5 找出下列语句中的错误并说明如何纠正。

a)#include ;
b)arraySize = 10; // arraySize was declared const
c)假设 int b[10]= { O };
for( int i = O;i <= 10;i++ )
b[i] = 1;
d)假设 int a[ 2 ][ 2 ] = {{ l,2 },{ 3,4 } };
a[ 1, 1] = 5;

自测练习答案

4.1 a)数组。b)名称、类型。c)下标。d)常量变量。c)排序。0查找。e)双下标。

4. 2 a)不正确。任何数组只能存放相同类型的值。

b)不正确。数组下标通常为整数或整型表达式。

c)不正确。其余元素自动初始化为0。

d)正确。

e)不正确。数组各个元素通过按值调用传递。如果将整个数组传递给函数,则任何修改将影响原始数组。

4.3

a) const iht arraySize = 10;
b) float fractions[ arraySize ] = { 0 }; 
c) fractions[ 3 ] 
d) fractions[ 4 ] 
e) fractions[ 9 ] = 1.667; 
fractions[ 6 ] - 3.333; 
g) cout << setiosflags ( ios: :fixed I ios: :showpoint )
<< setprecision( 2 ) << fractions[ 6 ] << ''
<< fractions[ 9 ] << endl;

输出:

3.33 1.67

h) for( int x = 0;x < arraySize; x ++)
cout << "fractions[ "<< x << "} =" << fractions[ x ]
<< endl;

输出:

fractions[ 0 ] = 0

fractions[ 1 ] = 0

fractions[ 2 ] = 0

fractions[ 3 ] = 0

fractions[ 4 ] = 0

fractions[ 5 ] = 0

fractious[ 6 ] = 3.333

fractious[ 7 ] = 0

fractions[ 8 ] = 0

fractious[ 9 ] = 1.667

4.4

a) int table[ arraySize ] [ arraySize ];
b) 9个.
c) for (x = 0; x < arraySize; x++ )
for ( y = O; y < arraySize; x++ )
table[ x ] [ y ] = x + y;
d) cout <<" [ 0 ] [ 1 ] [ 2 ]" << endl;
for (int x = O; x < arraySize; x++ ) {
cout << '[ ' << x << "] ";
for (int y = O; y < arraySize; y++ )
cout << setw(3) << table[ x ][ y ] << " ";
cout << endl;

输出:

[ O ] [1] [ 2 ]

[ O ] 1 8 0

[1 ] 2 4 6

[ 2 ] 5 0 0

4.5 a)不正确:#includc预处理指令后面不应有分号。

纠正:删除#include预处理指令后面的分号。

b)不正确:用赋值语句对常量变量赋值。

纠正:在const int arraySize 声明中对常量变量赋值。

c)不正确。在数组边界之外引用数组元素(b[10])。

纠正:将控制变量的终值变为9。

d)不正确:数组下标错误。

纠正:将语句变为a[1][1]=5;

练习

4.6填空:

a)C++在——中存放数值清单。

b)数组元素的关系是——。

c)引用数组元素时,括号中包含的位置号称为——。

d)数组p的4个元素名为——、——、——和——。

e)命名数组、指定数组类型和指定数组中的元素个数称为数组——。

f)将数组元素按升序或降序排列的过程称为——。

g)在双下标数组中,习惯上第一个下标表示数组元素的——,第二个下标表示数组元素的——。

h)m x n数组包含——行、——列和——个元素。

i)数组d中行3列5的元素名为——。

4.7 判断下列各题是否正确。如果不正确,请说明原因。

a)要引用数组中的特定位置或元素,我们指定数组名和特定元素的值。

b)数组声明为这个数组保留内存空间。

c)要为整型数组p保留100个位置,声明如下:

p[1OO];

d)将15个元素的数组中的元素初始化为0,C++程序至少要包含一个for循环。

e)求双下标数组元素和,C++程序要包含嵌套for结构。

4.8 编写完成下列任务的C++语句:

a)显示字符数组f第七十元素的值。

b)将数值输入单下标浮点数数组b的元素4。

c)将单下标整型数组e的5个元素各初始化为8。

d)求出浮点数数组c的100个元素之和并打印这些元素。

e)将a数组复制到数组b的开头部分。假设“floata[11],b[34];”

f)确定和打印99个元素的浮点数数组w中的最小值和最大值。

4.9 考虑2 x 3整型数组t,并编写相应的语句。

a)编写t的声明。

b)t有多少行

c)t有多少列

d)t有多少个元素

e)写出t的第2行所有元素名。

f)写出t的第3列所有元素名。

g)将t中行1列2的元素设置为0。

h)将t的每个元素初始化为0,不用重复结构。

i)用嵌套for结构将t的每个元素初始化为0。

j)从终端输入t的元素值。

k)用一系列语句确定和打印数组t的最小值。

l)显示t的第1行元素。

m)显示t的第4列元素。

n)以整齐的表格形式打印数组t,将列下标设为输出首部的一行,行下标放在输出左部的一列。

4.10 用单下标数组解决下列问题。公司按佣金为员工发工资,销售员每周发200美元加上本周总销售额的9%。例如,如果某个销售员本周总销售额为5000美元,则发200+9%× 5000 = 650美元。编写一个程序(用计数器数组)确定工资在下列范围的员工数(假设将每个销售人员的工资取整):

a)$200--$299

b)$300--$399

c)$400—$499

d)$500—$599

e)$600--$699

f)$700--$799

g)$800--$899

h)$900--$999

i)$1000以上

4.11图4.16的冒泡排序方法在大数组中不适用,通过下列简单修改可以提高冒泡排序方法的性能。

a)第一遍之后,最大数总是数组中编号最大的元素,第二遍之后,次大数总是数组中编号次大的元素等等。不用每次都作九次比较,而只要第二遭比较8次,第三遍比较七次等等。

b)数组中的数据可能已经有正确或接近正确的顺序,为什么一定要进行九遍比较呢每遍之后检查是否有所交换。如果没有交换,则数据已经正确排序,程序终止。如果有交换,则至少还要再进行一遍。

4. 12编写一条语句,完成下列单下标数组操作:

a)将整型数组consts的10个元素初始化为0。

b)将整型数组bonus的15个元京分别加10

c)从键盘读取float数组monthlyTemperatures的12个值。

d)用列格式打印整型数组bestScores的5个值。

4.13寻找下列语句中的错误。

 a)假设:char str[5]  ;
            cin >> str;    // User types hello
 b)假设:int a[ 3 ];
        cout << a[ 1 ] << " " << a[ 2 ]  <<" " << a[ 3 ] << endl;
 c) float f[3]  = {  1.1,10.0l,100.001,1000.0001);
 d)假设:double d[ 2 ][ 10 ]  ;
            d [1, 9] = 2.345;

4.14修改图4.17的程序,使函数mode能处理模值的连接。并修改函数median,使偶数个元素的数组中median为两个中间元素的平均值。

4.15用单下标数组解决下列问题。读取20个数,各为10到100之间的值。读取每个数时,只打印不重复的值。“最糟的情况”是20个值都不重复。用最小的数组解决这个问题。

4.16打印3× 5双下标数组sales的元素,表示下列语句中将其设置为0的顺序:

for ( row = 0; row < 3; row++ )for ( column = 0; column < 5; column++ )sales[ row ][ column] = 0;

4.17编写一个程序,模拟投两个骰子。程序用rand函数投第一个骰子,并再次用rand函数投第二个骰子,然后计算两个值的和。说明:由于每个骰子显示1到6的整数值,因此两个骰子的和为2到12,7最常见,1和12最不常见。图4.24显示了36种可能的两个骰子的和。程序将投两个骰子36000次,用单下标数组估算每个和出现的次数,用表格形式打印结果。并确定和是否合理,即有六种方式投出7,因此有六分之一的可能投出7。

4.18 下列程序有什么用

 // ex04 18.cpp
 #include 
 int whatIsThis( int [], int );
 int main{}
 {
    const int arraySize = 10;
    int a[ arraySize ] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } ;
    int result = whatIsThis( a, arraySize );
    cout << "Result is" << result << endl;
    return 0;
 }
 int whatIsThis( int b[], int size )
 {
      return
    else
      return b[ size -1 ] + whatIsThis(b, size -1 );
 }

4.19编写一个程序,运行1000次投骰子游戏,并回答下列问题:

a)第一次、第二次、…、第十二次和第十二次以后赢了几场

b)第一次、第二次、…、第十二次和第十二次以后输了几场

c)赢的机会有多少(投骰子游戏是最公平的游戏之一,为什么),

d)投骰子游戏平均长度是多少,

e)游戏玩得越久,赢的机会是否越多

4.20(航空订票系统)、航空公司购买了一台用于航空订票系统的计算机,要求对新系统编程,对每个航班订座(每班10位)。

程序显示下列菜单选项:Please type 1 for "smoking"和Pleas type 2 for nonsmokijng”。如果输入1,则程序指定吸烟舱位(座位1到5),如果输入2,则程序指定非吸烟舱位(座位6到10)。程序应打印一个登机牌,表示座位号和是否为吸烟舱位。

用一个单下标数组表示飞机的座位图。将数组的所有元素初始化为0,表示所有座位都是空的。订每个座位时,将数组相应元素设置为1,表示该座位已订。

当然,程序不能再订已经订过的座位。吸烟舱位已满时,应询问可否订非吸烟舱位;同样,非吸烟舱位已满时,应询问可否订吸烟舱位。如果同意,再相应订座,否则打印信息”Next fight leaves in 3 hours.”。

4.21下列程序有什么作用

 // ex04_21.cpp
 #include <iostream.h>
 void someFunction( int [], int );
 int main()
 {
   const int arraySize = 10;
   int a[ arraySize ] = { 32, 27, 64, 18, 95, 14, 90, 70, 60, 37 };
   count << "The values in the array are:" << endl;
   someFunction( a, arraySize );
   cout << endl;
   return 0;
 }
 void someFunction( int b[], int size )
 {
    if ( size > 0 ) {
     someFunction{&b[1 ],size -1 );
     cout << b[ 0 ] <<" ";
     }
 }

4.22用双下标数组解决下列问题。公司有4个销售员(1到4),销售五种产品(1到5)。每天每个销售人员要报告每种产品的销售量,报告中包含:

a)销售员号

b)产品号

c)当日总销售额

这样,每个销售人员每天要送0到5份报告。假设上个月的这些信息都有,编写一个程序,读取上月销售情况的信息,并按每个销售人员和每种产品进行汇总。所有汇总存放在双下标数组sales中。处理上个月的所有信息后,将结果打印成表格形式,每列表示一个销售员,每行表示一种产品。通过交叉求和求出上月每个销售人员的总销售额和每种

产品的总销售额。表格输出的右边小计行和下边小计列中应打印这些信息。

4.23(龟图)Logo语言在个人计算机用户中非常流行,该语言形成了龟图的概念。假设有个机器海龟,通过C++程序控制在房子中移动。在两个方向之一打开画笔,即向上或向下。

画笔向下时,海龟跟踪移动的形状并留下移动的路径,画笔向上时,海龟自由移动,不写下任何东西。在这个问题中,要模拟梅龟的操作和生成计算机化的草图框。

用20x20数组floor,初始化为0。从数组中读取命令。跟踪任何时候海龟的当前位置和画笔的向上或向下状态。假设诲龟总是从位置0,0开始,画笔向上。程序要处理的海龟命令如下:

-------------------------------------------------
        命令              含义
    -------------------------------------------------
         1                笔向上
         2                笔向7
         9                右转
         4                左转
         5,10            前进10格(或几格)
         6                打印20x20数组
         9                数据结束(标记)
    -------------------------------------------------

假设海龟接近平面中心。下列“程序”绘制和打印12 x 12正方形并让画笔向上:

2
5,12
3
5,12
3
5,12
3
5,12
1
6
9

面笔向下并移动诲龟时,将数组floor的相应元素设置为1。指定命令6(打印)时,只要数组中有1,就显示星号或选择的其他符号,而。则显示空白。编写一个程序,实现这里介绍的龟图功能。编写几个龟图程序,画一些有趣的图形。增加其他命令以增加龟图语言的功能。

4.24(骑士旅行)国际象棋中,最有趣的问题之一是骑士旅行问题,最初是由数学家欧拉提出的。问题如下:能否让骑士在空棋盘上移动,在64个方格中经过且只经过一次下面 要详细介绍这个问题。

骑士的移动按L形路线(一个方向两格,另一垂直方向一格,相当于“马走日”)。这样,从空棋盘中央的方格中,骑士可以有8种不同的移动方向(编号为0到7)

a)在纸上画一个8 x 8棋盘,试用手工移动骑士,在移动的第一个框中标上1、第二个框中标上2、第三个框中标上3等等。事先要估计走多远,总共有64步,能走多远

b)然后要开发一个在棋盘上移动骑士的程序。棋盘用8 x 8的双下标数组board表示。每个格子初始化为0。我们用水平和垂直组件描述8种可能的移动方式。例如,图4.25中0类型的移动是水平右移两格和垂直上移一格。2类型的移动是水平左移一格和垂直上移两格。左移和上移表示为负数。8种移动可以用两个单下标数组horizontal和vertical

描述如下:

horizontal[ O ] = 2
horizontal[ 1 ] = l
horizontal[ 2 ] = -l
horizontal[ 3 ] = -2
horizontal[ 4 ] = -2
horizontal[ 5 ] = -1
horizontal[ 6 ] = l
horizontal[ 7 ] = 2
vertical[ O ] = -l
vertical[ 1 ] = -2
vertical[ 2 ] = -2
vertical[ 3 ] = -l
vertical[ 4 ] = l
vertical[ 5 ] = 2
vertical[ 6 ] = 2
vertical[ 7 ] = 1

让变量currentRow和currentColumn表示骑士当前位置的行和列,要进行moveNumber类型的移动(moveNumber在0到7之间),程序用下列语句:

currentRow += vertical[ moveNumber ];

currentColumn += horizontal[ moveNumber ];

计数器应在1到64之间改变.用来记录每一格中骑士最近一次移动的顺序号。记住,要测试各种可能的移动,确定骑士是否已访问过该格。当然,要测试各种可能的移动,保证骑士不会跳到棋盘以外。现在编写在棋盘上移动骑士的程序。运行程序,看看骑士移动了多少位

c)编写和运行骑士旅行程序之后,可以进行一些透试,我们要开发一个移动骑士的试探程序(或策略)。试探不一定成功,但认真设计的试探方法能提高成功的机会。可以发现,外层格子比在棋盘中心附近的格子更难移动。事实上,最难访问的是四角的格子。

凭直觉,应先将骑士移到最难到达的格子,在旅行即将结束时再访问最容易到达的格子,这样成功的机率较高。

我们可以开发一个访问性试探,将每格进行访问性分类,然后总是设法把骑士移到最难访问的点。我们在双下标数组accessibility中标上每个格能访问的格数。在空棋盘上,中间格的值为8,四角格的值为2,其他格的值为3、4、6,如下所示:

    2    3    4    4    4    4    3    2
    3    4    6    6    6    6    4    3
    4    6    8    8    8    8    6    4
    4    6    8    8    8    8    6    4
    4    6    8    8    8    8    6    4
    4    6    8    8    8    8    6    4
    3    4    6    6    6    6    4    3
    2    3    4    4    4    4    3    2

现在用访问性试探值编写骑士旅行程序。任何时候,总是设法把骑士移到最难访问的点。对于格子连接的情况,骑士可能移到任一连接的格子。因此,旅行可以从四角开始(说明:骑土在棋盘上移动时,程序随着越来越多的格子被占而减少访问性值。这样,任何时候,棋盘上任一格子上访问性值是该格子能访问的格数)。运行这个程序,能否一一访问棋盘上的格子现在修改程序,从棋盘上任何一格开始运行64次旅行,哪些能全部访问,

d)编写一个骑士旅行程序,在遇到两格或几格连接时,确定选哪一格时先考虑从连接的格子能访问的格子。程序应移到下次移动时访问性值最小的

格子。4.25(骑士旅行:强制方法)练习4.24开发了骑士旅行问题的解决方法,这个方法用“访问性试探”能产生许多解法并可以有效地执行。

随着计算机的运算能力越来越强,可以用更简单的算法解决这个问题,即采用强制算法。

a)用随机数产生程序让骑士在棋盘上按L形走法任意移动。程序一步一步走完这个棋盘。

骑士能走多远

b)通常,上述程序不会走太远。现在修改程序,进行1000次走法。用单下标数组跟踪每次走了几步。程序完成1000次旅行后,以表格形式打印这些信息。最佳结果是什么

c)通常,上述程序能得到较好地走法,但无法走遍棋盘。现在删除次数限制,让程序一直运行,直到找出走遍棋盘的方法(注意,可能要好几个小时才能在强大的计算机上完成)。以表格形式打印这些信息.看看要多少次才能找出走遍棋盘的方法,花多少时间。

d)比较强制算法与前面介绍的访问性试探方法。哪个需要更认真地分析问题,哪个算法更难开发,哪个需要更强大的计算机功能,利用访问性试探能否事先保证找出走遍棋盘的方法,利用强制算法能否事先保证找出走遍棋盘的方法,比较两种方法的利与弊。

4.26(八皇后)国际象棋中的另一个难题是八皇后问题。简单地说,空棋盘上能否放八个皇后,使一个皇后不会“攻击”另一个皇后,即不会有两个皇后在同一行、同一列或同一对角线上。用练习4.24的思路设计懈决八皇后问题的算法(提示:棋盘上的每一格可以指定一个值,表示一个皇后可以“删除”多少个格子,每个角指定数值22,如图4.26)。在64个格子中放上这些“删除”数之后,问题就变成:将下一个皇后放在删除数最少的格子中。

                            * * * * * * * *
                            * *
                            *  *
                            *     *
                            *       *
                            *         *
                            *           *
                            *             *

                       图 4.26 左上角的删除数为22

4.27 (八皇后:强制算法)这个练习要用几个强制算法解决练习4.26介绍的八皇后问题。

a)用练习4.25介绍的随机强制算法解决八皇后问题。

b)用穷举法,即测试八个皇后在棋盘上的各种组合。

c)说明穷举法为什么不适用于骑士旅行问题

d)比较随机强制算法与穷举法。

4.28(骑士旅行:闭合线路)在骑士旅行问题中,骑士经过64格中的每一格一次,且只经过一次。闭合线路就是最后又回到出发的地方。修改练习4.24的骑士旅行程序,测试闭合线路是否走遍了棋盘。

4.29(Eratosthenes筛选法)质数是只能被1和本身整除的数。Eratesthenos筛选法是一种寻找质数的方法,这个方法如下所示:

a)生成一个数组,将所有元素初始化为1(真)。下标为质数的数组元素保持1,所有其他数组元素最终设置为o。

b)从数组下标1开始(下标1为质数),每次找到数值为1的数组元素时,对数组余下部分循环,将下标为该下标倍数的元素设置为0。对于数组下标2,数组中下标为2的倍数的所有元素(除2本身,如4、6、8、10等等)都设置为0;对于数组下标3,数组中下标为3的倍数的所有元素(除3本身,如1、6、9、12、15等等)都设置为0,依次类推。

这个过程完成之后,如果数组元素还是1,则下标为质数。这些下标可以打印出来。编写一个程序,用1000个元素的数组确定和打印1到999之间的素数,忽略数组中的元素0。

4.30(桶排序)桶排序从要排序的单下标正整数的数组开始,并有一个双下标整数数组,行下标为0到9,列下标为。到n-1,其中n为要排序数组中的数值个数。每一行双下标整数数组称为一个桶。编写一个bucketSorL函数,取整数数组和数组长度参数,并进行下列操作:

a)将单下标数组的每个值放到桶数组的行中(根据该值的个位)。例如,97放在第7行,3放在第3行,100放在第0行,称为“分布传递”。

b)一行一行地对桶数组进行循环,将值复制回原数组,称为“收集传递”。上述值在单下标数组中的新顺序为100、3、97。

c)对十位、百位、千位等重复上述过程。

第二遍,100放在第0行,3放在第0行(因为3没有十位),97放在第9行。经过收集传递之后,上述值在单下标数组中的新顺序为100、3、97。第三遍,将100放在第1行,3和97放在第行0行。经过收集传递之后,上述值在单下标数组中的新顺序为所要的排序结果。

注意,双下标桶数组的长度是要排序的整数数组长度的10倍。这种排序方法提供比冒泡排序更好的性能,但要求更多的内存。冒泡排序方法只要多一个数据元素的空间。这就是用空间交换时间的范例:桶排序方法比冒泡排序更快,但使用更多内存。这个存储桶排序方法要求每遍都将所有数据复制回原数组中。另一种方法是生成第二个双下标数组,在两个桶数组之间重复交换数据。

递归练习

4.3l(选择排序)选择排序查找数组中的最小元素。然后将最小元素与数组中第一个元素交换。从第二个数组元素开始的子数组重复这个过程。每一次都把一个元素放到正确的位置。这种排序与冒泡排序相似,对于n个元素的数组,要n-l遍,对每个子数组,要用n-1次比较以求得最小值。处理包含一个元素的子数组时,数组已经排序完毕。编写递归函数selectionSort,完成这个算法。

4.32(回文)回文就是正读反读都一样的字符串,例如“radar",“able was i ere i saw elba”和"a man a plan a canal panama"(如果忽略空格)。编写递归函数testPalindrome,在数组中的字符串为回文时返回true,否则返回false。函数忽略字符串中的空格和标点符号。

4.33(线性查找)修改图4.19.用递归函数linearsearch对数组进行线性查找,函数应收到整型数组和数组长度参数。如果找到查找健,则返回数组下标,否则返回-1。

4.34(折半查找)修改图4.20,用递归函数binarySearch对数组进行折半查找。函数应收到整型数组和开始下标与结束下标参数。如果找到查找键,则返回数组下标,否则返回-1。

4.35(八皇后)修改练习4.26的八皇后程序,用递归方法解决问题。

4.36 (打印数组)编写递归函数pritArray,取数组和长度参数,不返回任何内容。函数在收到长度为0的数组时停止处理并返回。

4.37(逆向打印字符串)编写函数stringReverse,取包含字符串的字符数组参数,逆向打印字符串且不返回任何内容。函数在收到null终止符时停止处理并返回。

4.38(寻找数组中的最小值)编写递归程序recursiveMinimum,取数组和长度参数并返回数组中的最小元素,当函数在收到长度为1的数组时停止处理并返回。