小言_互联网的博客

C++程序设计教程(钱能)第二章 学习笔记(续)及第二章习题

518人阅读  评论(0)

C++程序设计教程(钱能)第二章 学习笔记(续)及第二章习题

2.6 转移语句

break语句
break语句用于跳出当前循环。若有多重循环要一并跳出,则要借助于每重循环的额外条件判断或者是goto语句来完成。

continue语句
continue语句用在循环语句中,作为结束本次循环,准备进入下次循环的条件测试。若条件成立则执行continue的语句块,可以转变为若条件不成立则执行无continue的语句块。

goto语句

  • goto语句是低级语言的表征,可在函数体内直来直往。但现代程序设计不能容忍它在过程中任意穿梭而破坏过程体的结构。
  • 没有goto语句,过程体结构更清晰,程序更易读。
  • 若跳过声明和定义语句,则还将造成过程体的逻辑错误,因为后面引用的变量没有经过声明或定义是非法的。
  • C++中只有一个地方还有使用goto的价值:当从多重循环深处直接跳转到最外围循环之外时,如果用break, 就只能一重一重地退,而且还要边退边做记号,若用goto则显得更为直观。
  • 在Java中,为根本性废止goto,提供了“break标记”和“continue标记”的语句,通过给循环添加标记,用break和continue操作,就可以直接跳转到任何一层循环的标记处,或循环外。

【例1】使用goto语句求1 - 100的和。

int sum = 0, i = 1;
Loop:
sum += i;
i++;
if (i <= 100)
goto Loop;
cout << "The sum is " << sum << endl;

【例2】使用goto语句的极端例子:打印输出1 - 100的整数。

int a;
goto Init;
Forward:
a = a + 1;
Print:
cout << a << endl;
goto Down;
Init:
a = 1;
goto Print;
Down:
if (a < 100)
	goto Forward;

【例3】使用break语句跳出二重循环。

bool flag = false;
	for (int i = 1; i < 100; ++i) {
		for (int j = 1; j < 100; ++j) {
			if (i * j == 80) {
				flag = true;
				cout << "跳出第一重循环!" << endl;
				cout << "i = " << i << " ,j = " << j << endl;
				break;
			}
				
		}
		cout << "跳出第二重循环!" << endl;
		if (flag) break;
	}

【例4】使用goto语句跳出多重循环。

for (int i = 1; i < 100; ++i) {
	for (int j = 1; j < 100; ++j) {
		if (i * j == 80) {
			cout << "i = " << i << " ,j = " << j << endl;
			goto End;
		}		
	}
}
End:cout << "已在循环外!" << endl;


2.7 再做循环设计

2.7.1 逻辑判断

对于逻辑判断的问题,一般要考虑全部的可能性,然后从这些可能性中按条件逐一排查,直到最后获得某个结论。

【例】百钱买百鸡的问题:
           雄鸡7元1只,母鸡5元1只,小鸡1元3只。花100元,买100只鸡。若雄鸡,母鸡和小鸡都必须有,则雄鸡、母鸡和小鸡应各买几只?

分析:考虑全部的可能性时,先考虑雄鸡、母鸡和小鸡数的取值范围(也可以从金额着手)。由于各种鸡都必须要有,所以
雄鸡:最高耗用金额100-5-1=94,取7的倍数,得91,故范围是1-13;
母鸡:最高耗用金额100-7-1=92,取5的倍数,得90,故范围是1-18;
小鸡:最高耗用金额100-5-7=88,可买88*3=264只,但由于总鸡数的限制,小鸡数应<=98,故范围是3-96。

程序的表达模式为:
       for(列举所有可能情况){ //可能为多重循环
              if(条件1不满足) continue;
              if(条件2不满足) continue;
               … …
               if(条件n不满足) continue;
               输出结果之一或累计符合所有条件的方案
       }

本问题的条件为:
(1)雄鸡数 + 母鸡数 + 小鸡数 = 100
(2)雄鸡钱 + 母鸡钱 + 小鸡钱 = 100
(3)小鸡数是3的倍数

因此,其反条件值为:
(1)cock + hen +chick - 100 != 0
(2)7*cock + 5*hen + chick/3 - 100 != 0
(3)chick % 3 != 0

【代码1】最初分析的程序

for (int cock = 1; cock <= 13; ++cock) {
	for (int hen = 1; hen <= 18; ++hen) {
		for (int chick = 3; chick <= 96; chick++) {
			if (7 * cock + 5 * hen + chick / 3 - 100) 
				continue;
			if (cock + hen + chick - 100)
				continue;
			if (chick % 3)
				continue;
			cout << "Cocks:" << cock << ",Hens:" << hen << ",Chicks:" << chick << endl;
		}
	}
}

结果:Cocks:3,Hens:10,Chicks:87

【代码2】考虑程序优化,将所有chick用100 - cock - hen代替,省略chick循环。

for (int cock = 1; cock <= 13; ++cock) {
	for (int hen = 1; hen <= 18; ++hen) {
		if (7 * cock + 5 * hen + (100 - cock - hen)/ 3 - 100) 
			continue;
		if ((100 - cock - hen) % 3)
			continue;
		cout << "Cocks:" << cock << ",Hens:" << hen << ",Chicks:" << 100 - cock - hen << endl;			
	}
}

也可按下面的模式:
       for(列举所有可能情况{//可能为多重循环
              if(条件1满足 &&条件2满足 && … &&条件n满足)
              输出结果之一或者累计符合所有条件的方案
       }


【代码3】

for (int cock = 1; cock <= 13; ++cock) {
	for (int hen = 1; hen <= 18; ++hen) {
		if (7 * cock + 5 * hen + (100 - cock - hen) / 3 == 100 && (100 - cock - hen) % 3 == 0)
		cout << "Cocks:" << cock << ",Hens:" << hen << ",Chicks:" << 100 - cock - hen << endl;
	}
}

【代码4】

for (int cock = 1; cock <= 13; ++cock) {
	for (int hen = 1,chick = 99 - cock; hen <= 18; ++hen,--chick) {
		if (7 * cock + 5 * hen + chick/ 3 == 100 && chick % 3 == 0)
			cout << "Cocks:" << cock << ",Hens:" << hen << ",Chicks:" << chick << endl;
	}
}

2.7.2 级数逼近

循环的设计,对于无穷数列求和,逼近到某个近似值的情况。
【例】
              π/4 ≈ 1- 1/3 + 1/5 - 1/7 + …
是求π的数列,将所有不小于10的-6次方的项值加起来,以小数点6位精度方式输出。
分析:
(1)π的值用double表示。
(2)按公式,先求π/4。
(3)数列的通项为(-1)的(n-1)次幂乘以1/(2n-1)。
(4)一种方法是根据循环变量n,求得第n项的值,累计,然后条件判断,若满足结束条件,则退出。循环结束条件为前一个累计和与后一个累计和的差小于10的-6次方。即判断后一项的绝对值小于10的-6次方。

【方法1】根据循环变量求每一项。

//求π方法1
double sum = 0;
double item = 1;
for (int n = 1; abs(item) > 1e-6; ++n) {
	item *= (-1.0) * (2 * n - 3) / (2 * n - 1);
	sum += item;
}
cout << "Pi = " << fixed << sum * 4 << endl;

运行结果:Pi = 3.141595

【方法2】先设定一个初项,然后一边累计,一边根据前一项求下一项,一直累计,直到满足条件为止。

double sum = 0;
double item = 1;
for (int denom = 1, sign = 1; abs(item) > 1e-6; denom += 2, sign *= -1) {
	item = sign / double(denom);
	sum += item;
}
cout << "Pi = " << fixed << sum * 4 << endl;

运行结果:Pi = 3.141595
注意: denom要转换为double类型,若不强转,则整数之间做运算得到的还是整数。强转之后,得到的会是浮点数。

【方法3】用while循环来实现。

double sum = 1;
double item = 1;
int denom = 1, sign = 1;
while (abs(item) > 1e-6) {
	denom += 2;
	sign *= -1;
	item = sign*1.0 / denom;
	sum += item;
}
cout << "Pi = " << fixed << sum * 4 << endl;

运行结果:Pi = 3.141595

【方法4】do - while 循环实现

double sum = 0;
double item = 1;
long denom = -1;
int sign = -1;
do {
	denom += 2;
	sign *= -1;
	item = sign*1.0 / denom;
	sum += item;
} while (abs(item) > 1e-6);
cout << "Pi = " << fixed << sum * 4 << endl;

运行结果:Pi = 3.141595
注意: do-while 循环看上去和while循环结构差不多,但其循环控制思路上差了一个节拍。while循环先计算出 -1/3,do-while循环先计算出1。


2.8 小结

  • 对于if-else语句的对称形式,若分支结构为单纯的赋值和输出,或为简单的求值,均可用条件表达式替代。
  • 整数型条件判断用switch,不要忘了break;范围型或浮点型条件判断用嵌套if。
  • for循环用得最多,它可以描述循环体的起始和结束状态,以及中间步长;while是for的一种特例,在循环不含明确的循环变量时,用while会更简捷;do-while循环很少使用。
  • 不要妄用goto语句,它会造成程序结构混乱。
  • 一般循环控制结构类型:
    (1)字符图形类
    (2)素数判定类
    (3)逻辑判断类
    (4)级数逼近类

练习

       为节省时间,省略题目描述,只给出答案,部分参照本书配套答案。一题有多解时,会列出所有方法,个中优劣,自行体会。(文末附有习题答案链接)

【1】计算级数,总的来说有两种,细分有四种。省略for循环对应的while循环。

方法1:根据前一项算出下一项,即 item *= (-1)*x / i;

double x;
cout << "请输入x:" << endl;
cin >> x;
double sum = 1;
double t = x;
for (int i = 2; abs(t) > 1e-8; i++) {
	sum += t;
	t *= (-1)*x / i;
}
/*
for (int i = 2; abs(t) > 1e-8; t *= (-1)*x/i++) {
		sum += t;
}
*/
cout << fixed << setprecision(8) << sum << endl;
double x;
cout << "请输入x:" << endl;
cin >> x;
double sum = 1;
double item = -1;
for (int i = 1; abs(item) > 1e-8;i++) {
	item *= (-1)*x / i;
	sum += item;
}
cout << fixed << setprecision(8) << sum << endl;

方法2:使用函数,分别计算分子和分母。

double x;
cout << "请输入x:" << endl;
cin >> x;
double sum = 1, item = 1;
for (int i = 1,sign = 1; abs(item) > 1e-8; i++, sign *= -1) {
	item = sign*(pow(x,i)/fac(i));
	sum += item;
}
cout << fixed << setprecision(8) << sum << endl;

int fac(int n) {	
	if (n == 0 || n == 1) 
		return 1;
	else 
		return fac(n - 1)*n;
}

或者使用累乘计算分子和分母。

double x;
cout << "请输入x:" << endl;
cin >> x;
double sum = 1, item = 1, up = 1.0;
int denom = 1, sign = -1;
for (int i = 1; abs(item) > 1e-8; i++) {
	denom *= i;
	up *= x;
	sign *= -1;
	item = sign * 1.0 *(up / denom);
	sum += item;
}
cout << fixed << setprecision(8) << sum << endl;

【2】求1!+2!+3!+...+12! 。
int sum = 0;
int item = 1;
for (int i = 1; i <= 12; i++) {
	item *= i;
	sum += item;
}
cout << "1!+2!+3!+...+12! = " << sum << endl;

或者

int sum = 0;
int item = 1;
for (int i = 1; i <= 12; item *= ++i) {
	sum += item;
}
cout << "1!+2!+3!+...+12! = " << sum << endl;

或者

int sum = 0;
for (int i = 1; i <= 12;i++) {
	int t = 1;
	for (int j = 1; j <= i; j++) {
		t *= j;
	}
	sum += t;
}
cout << "1!+2!+3!+...+12! = " << sum << endl;

【3】编程求所有的水仙花数。

int x, y, z;
for (int i = 100; i <= 999; i++) {
	x = i / 100;
	y = i %100 /10;
	z = i % 10;
	if (pow(x, 3) + pow(y, 3) + pow(z, 3) == i) {
		cout << i << " is a narcissus number."<< endl; 
	}
}

或者

for (int i = 1; i <= 9; i++) {
	for (int j = 0; j <= 9; j++) {
		for (int k = 0; k <= 9; k++) {
			int value = 100 * i + 10 * j + k;
			if (i*i*i + j*j*j + k*k*k == value) {
				cout << value << " is a narcissus number." << endl;
			}
		}
	}
}

运行结果:
153 is a narcissus number.
370 is a narcissus number.
371 is a narcissus number.
407 is a narcissus number.


【4】编号求1000之内的所有“完数”。

int sum;
for (int i = 1; i <= 1000; i++) {
	sum = 0;
	for (int j = 1; j <= i/2; j++) {
		if (i%j == 0)
			sum += j;
	}
	if (sum == i) {
		cout << i << " 是完数。" << endl;
	}
}

或者

int sum;
for (int i = 2; i <= 1000; i++) {
	sum = 1;
	for (int j = 2; j <= i/2; j++) {
		if (i%j == 0)
			sum += j;
	}
	if (sum == i) {
		cout << i << " 是完数。" << endl;
	}
}

运行结果:
6 是完数。
28 是完数。
496 是完数。
注意: 1不是完数,因为完数不包括本身。

【5】编程求所有的3位数素数,且该数是对称的。
方法1:针对100-999之间的三位数,逐个判断是否对称和是否是素数。

for (int i = 100; i <= 999; i++) {
	if ((i/100 ==i % 10)&& isPrime(i))
		cout << i << " 是对称的三位素数。" << endl;
}

bool isPrime(int n) {
	double m = sqrt(n*1.0);
	for (int i = 2; i <= m; i++) {
		if (n %i == 0) 
			return false;
	}
	return true;
}

方法2:在三位对称数的基础上,判断素数。
三位对称数,若为偶数则一定不是素数,所以这里都取奇数。并且判断素数的方法也有所改变,只判断是否是3-算数平方根中奇数的倍数。

for (int i = 1; i <= 9; i += 2) {
	for (int j = 0; j <= 9; j++) {
		int value = 101 * i + 10 * j;
		if(isPrime1(value))
			cout << value << " 是对称的三位素数。" << endl;
	}
}

bool isPrime1(int n) {
	double m = sqrt(n*1.0);
	for (int i = 3; i <= m; i+= 2) {
		if (n %i == 0)
			return false;
	}
	return true;
}

运行结果:
101 是对称的三位素数。
131 是对称的三位素数。
151 是对称的三位素数。
181 是对称的三位素数。
191 是对称的三位素数。
313 是对称的三位素数。
353 是对称的三位素数。
373 是对称的三位素数。
383 是对称的三位素数。
727 是对称的三位素数。
757 是对称的三位素数。
787 是对称的三位素数。
797 是对称的三位素数。
919 是对称的三位素数。
929 是对称的三位素数。

方法3:先求100-999之间的素数,然后判断每个素数是否对称。

for (int i = 100; i <= 999; i++) {
	bool flag = 0;
	for (int j = 2; j <= 33; j++) {
		if (i%j == 0) {
			flag = 1;
			break;
		}
	}
	if (!flag ) {
		if ((i/100) == (i % 10)) 
			cout << i << " 是对称的三位素数。" << endl;
	}
}

注意: flag应放在外循环里面,使每个整数都有一个标志。若放在外面,所有素数共享一个标志,就得不到想要的结果。谨记!!!


【6】猴子吃桃问题。
分析:根据第十天计算第九天剩下的桃子,根据第九天计算第八天剩下 的桃子… … 以此类推,循环9次,就可得到第一天摘下的桃子数。

int day, former,beh =1;
for (day = 9; day >=1 ; day--) {
	former = (beh+1)*2;
	beh = former;
}
cout << "猴子第一天共摘下桃子" << former <<"个。"<< endl;

或者

int peachs = 1;
for (int i = 1; i < 10;i++) {
	peachs = (peachs + 1) * 2;
}
cout << "猴子第一天共摘下桃子" << peachs << "个。" << endl;

运行结果:猴子第一天共摘下桃子1534个。


【7】用循环语句打印如下图案。

         %
        %%%
       %%%%%
      %%%%%%%
     %%%%%%%%%
    %%%%%%%%%%%
   %%%%%%%%%%%%%
  %%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%
  %%%%%%%%%%%%%%%
   %%%%%%%%%%%%%
    %%%%%%%%%%%
     %%%%%%%%%
      %%%%%%%
       %%%%%
        %%%
         %

方法1:把图案看成两部分,并把第11行当做第9行输出显示,并采用string类型进行输出。

for (int i = 1; i <= 10; i++) {
	cout << string(10 - i, ' ');
	cout << string(2*i-1, '%');
	cout << endl;
}
for (int j = 9; j >= 1; j--) {
	cout << string(10 - j, ' ');
	cout << string(2 * j - 1, '%');
	cout << endl;
}

方法2:把图案看成一个整体,计算每行输出的%时,以第10行为分界线,采用不同的公式输出。

for (int i = 1,j = 1; i <= 19; ++i,j = (i<10)?i:20-i) {
	cout << string(10 - j, ' ');
	cout << string(2 * j - 1, '%');
	cout << endl;
}

方法3:循环控制思路同方法2,不过输出采用字符串拼接的形式。

for (int i = 1, j = 1; i <= 19; ++i, j = (i < 10) ? i : 20 - i) {
	cout << string(10 - j, ' ')+string(2 * j - 1, '%')+"\n";
}

方法4:循环控制思路同方法1,不过采用流状态进行输出。

for (int i = 1; i <= 10; i++) {
	cout << setfill(' ') << setw(11 - i) << " "
		<< setfill('%') << setw(2 * i - 1) << "%" << endl;
}
for (int j = 1; j <= 9; j++) {
	cout << setfill(' ') << setw(j+1 ) << " "
		<< setfill('%') << setw(19 - 2 * j) << "%" << endl;
}

注意: 这里string() 与 setfill() 的参数均是字符类型,而不是字符串类
型。并且在方法4中每行都多输出了一个空格,因为setw(0)不起作用。


【8.1】用循环语句打印如下图案。

          #    $
         ##    $$
        ###    $$$
       ####    $$$$
      #####    $$$$$
     ######    $$$$$$
    #######    $$$$$$$
   ########    $$$$$$$$
  #########    $$$$$$$$$
 ##########    $$$$$$$$$$

方法1:

for (int i = 1; i <= 10; i++) {
	cout << string(10 - i, ' ');
	cout << string(i, '#');
	cout << string(3, ' ');
	cout << string(i, '$');
	cout << endl;
}

方法2:

for (int i = 1; i <= 10; i++) {
	cout << setfill(' ') << setw(11 - i) << " "
		 << setfill('#') << setw(i) << "#"
		 << setfill(' ') << setw(4) << " "
		 << setfill('$') << setw(i) << "$" << endl;
}

【8.2】用循环语句打印如下图案。

STSTSTSTSTSTSTSTSTS
 STSTSTSTSTSTSTSTS
  STSTSTSTSTSTSTS
   STSTSTSTSTSTS
    STSTSTSTSTS
     STSTSTSTS
      STSTSTS
       STSTS
        STS
         S

方法1:外循环控制行,内循环控制每行的位数,奇数位输出“S”,偶数位输出“T”。

for (int i = 1; i <= 10; i++) {
	cout << string(i - 1, ' ');
	for (int j = 1; j <= 21 - 2*i; j++)
	{
		cout<< (j % 2 ? 'S' : 'T');		
	}
	cout << endl;
}

方法2:外循环控制行,内循环控制每行的位数,通过位与操作,判断奇偶位。同样地,奇数位输出“S”,偶数位输出“T”。

for (int i = 1; i <= 10; i++) {
	cout << string(i - 1, ' ');
	for (int j = 1; j <= 21 - 2 * i; j++)
	{
		cout << (j&1 ? 'S' : 'T');
	}
	cout << endl;
}

方法3:外循环控制行,内循环控制输出“ST”。

for (int i = 1; i <= 10; i++) {
	cout << string(i - 1, ' ');
	for (int j = 1; j <= 10 - i; j++)
	{
		cout << "ST";
	}
	cout << "S" << endl;
}

【9】编程求解母牛问题。
方法1
分析:第一年,第二年,第三年后均都有1头牛
           第四年 = 第一年 + 第三年
           第五年 = 第二年 + 第四年
           … …
           第n年 = 第n-3年(生下的母牛数) + 第n-1年(老牛数)

int third = 1, first = 1, second = 1;
int n, temp;
cout << "please input a year:\n";
cin >> n;
for (int i = 4; i <= n; i++) {
	temp = first + third;
	first = second;
	second = third;
	third = temp;
}
cout << n << "years later,there are cows:" << third << endl;

方法2
分析: 先手动计算每年的母牛数,然后找规律,采用分段函数来描述
           n ∈ [1,3],    f(x) = 1
           n ∈ [4,6],    f(x) = n-2
           n ∈ [7,∞) ,   f(x) = f(n-1)+f(n-3)

int main(){
	int n;
	cout << "请输入年数:" << endl;
	cin >> n;
	int nums = calculate(n);
	cout << "第"<<n<<"年时共有牛" << nums << "头!" << endl;
}

int calculate(int n) {
	if (n <= 3)
		return 1;		
	else if (n <= 6) {
		return n - 2;
	}
	else {
		return calculate(n - 1) + calculate(n - 3);
	}	
}

为看到全部结果,稍微修改了代码,循环调用函数,从而得到如下运行结果。

第1年时共有牛1头!
第2年时共有牛1头!
第3年时共有牛1头!
第4年时共有牛2头!
第5年时共有牛3头!
第6年时共有牛4头!
第7年时共有牛6头!
第8年时共有牛9头!
第9年时共有牛13头!
第10年时共有牛19头!
第11年时共有牛28头!
第12年时共有牛41头!
第13年时共有牛60头!
第14年时共有牛88头!
第15年时共有牛129头!
第16年时共有牛189头!

【10】求解小球下落问题。
方法1
分析:第几次落地        高度         经过距离
                 1                  100              100
                 2                  50                200
                 3                  25                250
                  … …
          当 i = 11 时,退出循环,此前计算的s为第10次落地时经过的距离,而h是第11次的高度,即第10次落地后的反弹高度。

double s = -100, h = 100;
for (int i = 1; i <= 10; i++) {
	s = s + 2 * h;
	h = h / 2;
}
cout << "球在第10次落地时,共经过距离:" << s << endl;
cout << "球在第10次落地后的反弹高度为:" << h << endl;

方法2:直接从第二次落地开始计算。
       第几次落地        i         当前高度*2         经过距离
               2                1             100                     200
               3                2             50                       250
               4                3             25                       275
               … …
sum初值为100,这个100就是小球从初始位置到落地经过的距离。
因为i与落地次数不是一一对应的,故循环9次。
i=10时,跳出循环,这时的sum就是第10次落地时经过的距离;
而height恰好是第10次的高度,故height/2就是第10次落地后的反弹高度。

double sum = 100, height = 100;
for (int i = 1; i < 10; i++) {
	sum += height;
	height /= 2;
}
cout << "球在第10次落地时,共经过距离" << sum << endl;
cout << "球在第10次落地后的反弹高度为" << height / 2 << "米!" << endl;

运行结果:
球在第10次落地时,共经过距离:299.609
球在第10次落地后的反弹高度为:0.0976563
注意: sum与height是double类型。除第一次外,每次弹起到落地,经过的距离是高度的2倍。


【11】求解100元兑换成10元、5元、1元的不同兑法数。
方法1:三重循环

int n = 0;
for (int i = 1; i <= 9; i++) {
	for (int j = 1; j <= 17; j++) {
		for (int k = 1; k <= 85; k++) {
			if (10 * i + 5 * j + k == 100) {
				n++;		
			}
		}
	}
}
cout << "100元可兑换10元、5元、1元的兑法数是" << n << endl;

方法2:二重循环,省略1元的循环。

int n = 0;
for (int i = 1; i <= 9; i++) {
	for (int j = 1; j <= 17; j++) {			
		if ((100 - 10 * i - 5 * j) >= 1) {				
			n+=1;
		}
	}
}
cout << "100元可兑换10元、5元、1元的兑法数是" << n<< endl;

运行结果:100元可兑换10元、5元、1元的兑法数是81


【12.1】用循环语句打印如下矩阵形式。

1     0   1   2   3   4   5   6
2     1   2   3   4   5   6   0
3     2   3   4   5   6   0   1
4     3   4   5   6   0   1   2
5     4   5   6   0   1   2   3
6     5   6   0   1   2   3   4

方法1

for (int i = 1; i <= 6; i++) {
	cout << i << setfill(' ') << setw(2) << " ";
	for (int j = 1; j <= 7; j++) {
		cout << setfill(' ') << setw(3) << " " << (i + j - 2) % 7;
	}
	cout << endl;
}

方法2

for (int i = 1; i <= 6; i++) {
	cout << i << "    ";
	for (int j = i-1; j < i+6; j++) {
		cout <<j%7<<"  ";
	}
	cout << endl;
}

方法3

for (int i = 1; i <= 6; i++) {
	cout << i << "    ";
	int n = 0;
	for (int j = i-1; j <= 6; j++) {
		cout << j << "   ";
		n++;
	}
	if (n < 7) {
		for (int k = 0; k < 7 - n; k++) {
			cout <<k << "   ";
		}
	}
	cout << endl;
}

【12.2】用循环语句打印如下矩阵形式。

(1,1)  (1,2)  (1,3)  (1,4)  (1,5)  (1,6)  (1,7)
(2,1)  (2,2)  (2,3)  (2,4)  (2,5)  (2,6)  (2,7)
(3,1)  (3,2)  (3,3)  (3,4)  (3,5)  (3,6)  (3,7)
(4,1)  (4,2)  (4,3)  (4,4)  (4,5)  (4,6)  (4,7)
(5,1)  (5,2)  (5,3)  (5,4)  (5,5)  (5,6)  (5,7)
(6,1)  (6,2)  (6,3)  (6,4)  (6,5)  (6,6)  (6,7)
for (int i = 1; i <= 6; i++) {
	for (int j = 1; j <= 7; j++) {
		cout << "(" << i << "," << j << ")" << "  ";
	}
	cout << endl;
}

【13】编程打印九九乘法表

方法1:根据每行非零元素的个数与行号之间的关系,控制输出 。

*    1    2    3    4    5    6    7    8    9
----------------------------------------------
1    1
2    2    4
3    3    6    9
4    4    8   12   16
5    5   10   15   20   25
6    6   12   18   24   30   36
7    7   14   21   28   35   42   49
8    8   16   24   32   40   48   56   64
9    9   18   27   36   45   54   63   72   81
//打印表头样式
cout << "*";
for (int j = 1; j <= 9; j++) {
	cout << setw(5) << setfill(' ') << j;
}
cout << endl;
cout << string(46, '-') << endl;
//下三角式
for (int i = 1; i <= 9; i++) {
	cout << i;
	for (int k = 1; k <= i; k++) {
		cout << setw(5) << setfill(' ') << i*k;
	}
	cout << endl;
}
*    1    2    3    4    5    6    7    8    9
----------------------------------------------
1    1    2    3    4    5    6    7    8    9
2         4    6    8   10   12   14   16   18
3              9   12   15   18   21   24   27
4                  16   20   24   28   32   36
5                       25   30   35   40   45
6                            36   42   48   54
7                                 49   56   63
8                                      64   72
9                                           81
//打印表头样式
cout << "*";
for (int j = 1; j <= 9; j++) {
	cout << setw(5) << setfill(' ') << j;
}
cout << endl;
cout << string(46, '-') << endl;
//上三角式
for (int i = 1; i <= 9; i++) {
	cout << i<<string(5*(i-1),' ');
	for (int k = i; k <= 9; k++) {
		cout << setw(5) << setfill(' ') << i*k;
	}
	cout << endl;
}

方法2:根据三角行列式中非零元素所处位置的行号与列号的关系,控制输出。
下三角式

cout << "*";
for (int i = 1; i <= 9; i++) {
	cout <<string(6,' ') << i;
}
cout << '\n' << string(65, '-') << endl;
for (int j = 1; j <= 9; j++) {
	cout << j;
	for (int k = 1; k <= 9; k++) {
		if (j >= k)
			cout << string(5, ' ')<<setw(2) << j*k;
	}
	cout << endl;
}

上三角式

cout << "*";
for (int i = 1; i <= 9; i++) {
	cout <<string(6,' ') << i;
}
cout << '\n' << string(65, '-') << endl;

for (int j = 1; j <= 9; j++) {
cout << j;
	for (int k = 1; k <= 9; k++) {
		if (j <= k)
			cout << string(5, ' ') << setw(2) << j*k;
		else
			cout << string(5, ' ') << setw(2) << " ";
	}
	cout << endl;
}

总结: 不能读完每章后,再整理笔记,那样工作量太大了。
           一定要读完一小节,就上机操作,及时整理笔记。                                  课后习题中的方法比较多,要花时间细细理解,才能完全掌握。虽然在第二章上花了很长时间,但非常有收获,毕竟实践出真知,理论结合实践才是最好的学习方法!

习题答案链接:https://wenku.baidu.com/view/58cdf3851711cc7930b716dd.html


转载:https://blog.csdn.net/qq_40243430/article/details/101846337
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场