前面我们大概的已经学习过很多关于循环的知识,这一篇博客我们重点引入一些习题进行分析,涉及到循环的东西,无非就是将变量之间的关系和规律找到,这一解我们就将要仔细的分析每一个题目具体怎么去寻找这种规律。
第一题
打印杨辉三角十行 如下:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
…
这就是我们的输出目的
问题分析
方法一:首先我们观察到这个样子的一个三角结构,好像可以把它放到一个二维数组当中,那些不需要打印的数字,我们都可以将其初始化为0。那么,我们就可以观察到这样一个现象,除了每一行的第一个数字以外,其余的数字均可以这样表示。
a[i][j] = a[i-1][j-1] + a[i-1][j];
而每一行的第一个数据我们都可以使其初始化为1。
最终我们三角化打印这个二维数据即可
i来控制第几行
j来控制每行打印多少个数据。
那么i的取值范围应该是[0,len),j的取值范围应该是[0,i]。
#include<iostream>
using namespace std;
int main(){
int a[10][10] = {0};
for (int i = 0; i < 10; ++i){
for (int j = 0 ; j <= i; ++j){
if(j == 0){
a[i][j] = 1;
}else{
a[i][j] = a[i-1][j-1] + a[i-1][j];
}
}
}
for(int i = 0 ; i < 10; ++i){
for(int j = 0; j <= i ++j){
cout<<a[i][j]<<"\t"
}
cout<<endl;
}
return 0;
}
方法二:我们同样可以这样思考这个问题,通过观察我们很容易看出来,如果想要打印第十行数据的时候,一共需打印十个值,那么我们就可以一开始定义一个长度为10的数组,第一行,打印这个数组的一个元素,第二行打印两个以此类推。
接下来我们观察数组中元素的特点。
{1, 2, 1}---->{1, 3, 3, 1}。
假设i表示第i行的打印,那么我们可以很明显的看出来,每次首先给数组当中新添加的a[i]元素的值就是1,并且除了第0号元素和第i号元素以外,其他元素均满足这样的关系:
a[i] += a[i-1];
所以如果用j的值来实现每一行具体的操作时候,j的取值范围应该是从i-1一直到1。
这里我们为什么不说是从1到i-1呢,仔细思考这样一个问题,当我们把i的值覆盖以后,当我们计算i+1的值时候,用到的i位置的值还是原来的值吗?这也就是我们这样设计的原因,最后把整个数组打印即可。
#include<iostream>
using namespace std;
int main(){
int a[10];
for (int i = 0; i < 10, ++i){
a[i] = 1;
for (int j = i - 1; j > 0; --j){
a[j] += a[j-1];
}
for (int k = 0 ; k <= i; ++k){
cout<<a[k]<<"\t";
}
cout<<endl;
}
return 0;
}
题目二
打印九九乘法表,打印格式如下:
1 * 1 = 1
1 * 2 = 2 2 * 2 = 4
1 * 3 = 3 2 * 3 = 6
…
题目分析
观察乘法表,我们可以很明显看到,每个算式都是由三个数字构成的,i,j和result。每一行当中的i的值都是不变的,并且i的取值范围是[1, 9]。而我们可以很明显的看出来,j的取值范围应该是[1, i]。所以这个题目我们可以很快的给出如下一种解法:
#include<iostream>
using namespace std;
int main(){
for(int i = 1; i < 10; ++i){
for (int j = 1; j <+ i; ++j){
cout<<j<<" * "<<i<<" = "<<j*i<<"\t";
}
cout<<endl;
}
return 0;
}
题目三
打印100位斐波纳契数列,如下:
1, 1, 2, 3 ,5 ,8, …
题目分析
首先我们观察这个数列,前面两位都是固定的数字1,从第三位开始,每个数字都是前面两位之和,题目要求打印一百位的数列,所以我们很自然而然想到了定义的i的取值范围应该是[2 ,100]。
代码如下:
#include<iostream>
using namespace std;
int main(){
int arr[100] = {1, 1};
cout<<a[0]<<"\t";
cout<<a[1]<<"\t";
for (int i = 2; i < 101; ++i) {
arr[i] = arr[i-1] + arr[i-2];
cout<<arr[i]<< "\t";
}
return 0;
}
题目三
打印下列格式的一组数字
1 2 3 4 5 6
12 23 34 45 56
123 234 345 456
1234 2345 3456
12345 23456
123456
题目分析
我们这样分析这个题目,首先观察这6行数,第一行每个都是1位数,到了第6行是6位数。我们抽取其中的一行进行具体的分析
123 234 345。假设i表示每个数字的首位,j表示每个数字的末尾,s表示这是第几行。s取值范围是[1, 6]
那么我们可以明显的得到这样的结论,i的值是从1开始到n - s + 1;
而j的取值范围应该是从i到i+s-1。
所以代码实现如下:
#include<iostream>
using namespace std;
int main(){
for (int s = 1; s <= 6; s++){
for(int i = 1; i <= n-s+1; ++i){
for(int j = i; j <= i+s-1; ++j){
cout<<j;
}
cout<<"\t"
}
cout<<endl;
}
return 0;
}
排序基础之冒泡排序
写出冒泡排序的改良版本,要求当排序完成后,就停止排序而不是做无用功继续遍历,并且要求左右一起进行排序,加快排序进度。
题目分析
题目需要的是冒泡排序的升级版,所以首先我们先写出来普通的冒泡再进行分析
#include<iostream>
using namespace std;
// 改良冒泡排序
void PrintArray(int *arr, int len){
for(int i = 0; i<len;++i){
cout<<*(arr+i)<<" ";
}
cout<<endl;
}
void bubble_sort(int *arr ,int len){
for(int i = 1; i < len; ++i){
for (int j = 0;j < len-i;++j)
if(*(arr+j) > *(arr + j+ 1)) {
int tmp = *(arr +j);
*(arr+j) = *(arr + j + 1);
*(arr +j + 1) = tmp;
}
}
}
int main(){
int arr[] = {45, 56, 12, 34, 89, 90, 100, 23, 56, 78};
int n = sizeof(arr) /sizeof(int);
PrintArray(arr, n);
bubble_sort(arr, n);
PrintArray(arr, n);
return 0;
}
分析代码
题目要求我们改良这个冒泡排序,首先我们考虑这样的一个问题,那就是如何让这个冒泡排序一旦排序完成就不会继续做无用功了。我们需要这样思考这个问题,当排序完成后,继续执行代码,我们的程序会有什么特点,答案是显而易见的,那就是值不会发生交换了,所以从这一点入手,我们很轻松就找到了方法,我们可以给交换时候加一个标记,一旦不再调用,那么就意味着排序完成了。
接着是第二个问题,左右一起排序,那么首先考虑一共要排序len/2次的,并且j的值应该不再从0开始了,应该是从i开始,一直到len-1-i,同时j的值应该是len-1-i,一直到i。
所以代码如下
/*===============================================================
* Copyright (C) 2019 All rights reserved.
*
* 文件名称:08-冒泡排序改良版.cpp
* 创 建 者:Ma Junjie
* 创建日期:2019年07月03日
* 描 述:
*
* 更新日志:
*
================================================================*/
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<time.h>
using namespace std;
void PrintArray(int *arr, int len){
for (int i = 0; i < len; ++i){
cout<<arr[i]<<" ";
}
cout<<endl;
}
void BubbleSort(int *arr, int len){
for (int i = 0; i < len/2; ++i){
bool tag = true;
for(int j = i,k = len-1-i; j < len-i-1, k>i; ++j,--k){
if(arr[j] > arr[j+1]){
tag = false;
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
if(arr[k] < arr[k-1]){
tag = false;
int temp = arr[k];
arr[k] = arr[k-1];
arr[k-1] = temp;
}
}
if(tag){
break;
}
}
}
void InitArray(int *arr, int len){
srand(time(NULL));
for (int i = 0; i < len; i++){
arr[i] = random()%100;
}
}
int main()
{
const int len = 30;
int arr[len];
InitArray(arr, len);
PrintArray(arr, len);
BubbleSort(arr, len);
PrintArray(arr, len);
return 0;
}
排序基础之直接选择排序
编写代码完成直接选择排序,直接选择排序算法思路如下:
从第一个数开始,后面的每个数都开始和第一个数进行比较,那么我们可以很容易就得到,一个最小值,放到第一个位置。一次类推,直到排序完成。
根据算法思路可以知道,i的取值范围应该是从[0, len-1)。j的取值范围应该是[i+1, len)。并且每次都比较i和j的值。
所以代码如下:
#include<iostream>
using namespace std;
void swap(int *a, int *b){
int temp = *a;
*a = *b;
*b = temp;
}
void PrintArray(int *arr, int len){
for(int i = 0; i < len; ++i){
cout<<arr[i]<<" ";
}
cout<<endl;
}
void SelectSorted(int *arr, int len){
for(int i = 0; i< len; ++i){
int index = i;
for (int j = i+1; j < len; ++j){
if(arr[index] > arr[j]){
index = j;
}
}
if (i != index) swap(&arr[i],&arr[index]);
}
}
int main(){
int arr[] = {9, 5,3, 4,8, 6,3, 8, 6,1,2};
int len = sizeof(arr) / sizeof(int);
SelectSorted(arr, len);
PrintArray(arr, len);
return 0;
}
排序基础之插入排序
编写代码实现插入排序,插入排序算法思路如下:从第一个数开始,有序数列逐渐增加1个元素,并且每次增加完毕以后都使其有序。直到有序数列增加到最后一个数列,完成排序。
根据算法设计:
首先如果后面一个数小于前面的话,说明新的元素加入以后整体变得无序了,所以从这个元素开始向前比较,直到找到合适的位置插入。
代码实现如下:
/*===============================================================
* Copyright (C) 2019 All rights reserved.
*
* 文件名称:07-插入排序.cpp
* 创 建 者:Ma Junjie
* 创建日期:2019年07月03日
* 描 述:
*
* 更新日志:
*
================================================================*/
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<time.h>
using namespace std;
void InitArray(int *arr, int len){
srand(time(NULL));
for(int i = 0; i < len; ++i){
arr[i] = random()%100;
}
}
void PrintArray(int *arr, int len){
for (int i = 0; i < len; ++i){
cout<<arr[i]<<" ";
}
cout<<endl;
}
void InsertSort(int *arr, int len) {
for (int i = 0; i < len; ++i) {
if(arr[i] < arr[i-1]){
int j = i - 1;
int temp = arr[i];
do{
arr[j+1] = arr[j];
--j;
}while(j >= 0 && arr[j] > temp);
arr[j+1] = temp;
}
}
}
int main()
{
const int len = 20;
int arr[len];
InitArray(arr, len);
PrintArray(arr, len);
InsertSort(arr, len);
PrintArray(arr, len);
cout<<endl;
return 0;
}