文章目录

  • 例6.7
  • 例5.12 函数版本
  • 利用函数模板计算两个数最大值
  • 例6.11 用递归函数打印一个十进制整数的函数定义及使用
  • 在此基础上进一步扩展,根据输入,打印不同进制的整数
  • 例6.12 设计函数打印n个字符的全排列
  • 例6.13 8皇后问题
  • 例6.14 分书问题
  • 例6.15 快速排序
  • 例6.16 最大连续子序列和
  • 例6.17 硬币找零问题

例6.7

读入一串整型数据,直到输入一个特定值为止,把这些整形数据逆序排列,输出经过重新排列后的数据,要求每个功能都用一个函数实现

思路:根据题意,分解成三个函数,分别是读入一串整数(数组,数组规模,输入结束标记),对这组整数逆序排列(数组,数组规模),输出数组(数组,数组规模),由此确定函数原型

#include <iostream>
using namespace std;#define MAX 10//函数原型声明
int ReadIntegerArray(int array[], int max, int flag);
void ReverseIntegerArray(int array[], int size);
void PrintIntegerArray(int array[], int size);int main(){int IntegerArray[MAX], flag, CurrentSize;cout << "请输入一个结束标记(整数):";cin >> flag;CurrentSize = ReadIntegerArray(IntegerArray, MAX, flag);ReverseIntegerArray(IntegerArray, CurrentSize);PrintIntegerArray(IntegerArray, CurrentSize);return 0;
} /**
接收用户的输入
**/
int ReadIntegerArray(int array[], int max, int flag){int size = 0;cout << "请输入数组元素,以" << flag << "结束:";while(size < max){cin >> array[size];if(array[size] == flag)break;else++size;}return size;
}/**
对数组内容逆序排列
**/void ReverseIntegerArray(int array[], int size){int i, tmp;for(i=0; i<size/2; ++i){tmp = array[i];array[i] = array[size -i -1];array[size -i -1] = tmp;}
}
/**
输出数组
**/ void PrintIntegerArray(int array[], int size){int i;if(size == 0) return;cout << "逆序是:" << endl;for(i=0; i<size; ++i){cout << array[i] << " ";}
}

例5.12 函数版本

要求统计一组正整数的和,这组正整数可以是八进制、十进制、十六进制表示,当时方法是采用字符串保存这组数字,然后从中区分出一个个正整数,代码集中在了mian函数,现在对其进行优化,将相关代码封装成函数,如:把字符串表示的不同基数的正整数转换成一个整型数;把输入的字符串字母转换成大写

#include <iostream>
using namespace std;int convertToInt(char s[], int start);
void convertToUpper(char s[]);int main(){char str[81];int sum = 0, i = 0;cout << "请输入一组整数,用空格分开:";cin.getline(str, 81);convertToUpper(str);while(str[i] == ' ' && str[i] !='\0') //跳过前置空格 ++i;while(str[i] !='\0'){sum += convertToInt(str, i);while(str[i] != ' ' && str[i] != '\0') //跳过刚才已处理的i ++i;while(str[i] == ' ' && str[i] != '\0') //跳过空格 ++i;}cout << "整数和为:" << sum << endl;return 0;
}void convertToUpper(char s[]){for(int i=0;s[i]!='\0';++i){if(s[i]>='a' && s[i]<='z'){s[i] = s[i] - 'a' + 'A';}}
}int convertToInt(char s[], int start){int data = 0, base;if(s[start]!='0')base = 10;else if(s[start+1] == 'X'){base = 16;start += 2;}else{base = 8;++start;}switch(base){case 10:while(s[start]!=' ' && s[start]!='\0'){data = data * 10 + s[start++] - '0';}break;case 8:while(s[start]!=' ' && s[start]!='\0'){data = data * 8 + s[start++] - '0';}break;case 16:while(s[start]!=' ' && s[start]!='\0'){data = data * 16;if(s[start]>='A' && s[start]<='F')data += s[start++] - 'A' + 10;elsedata += s[start++] - '0';}}return data;
} 

利用函数模板计算两个数最大值

#include <iostream>using namespace std;template <class T>
T Max(T a, T b){return a>b ? a : b;
}int main(){cout << "Max(3,5) = " << Max(3,5) <<endl;cout << "Max(3.3,2.5) = " << Max(3.3,2.5) <<endl;cout << "Max('d','r') = " << Max('d','r') <<endl;return 0;
}

汉诺塔问题
将n个盘子从start借助temp移动到finish

#include <iostream>
using namespace std;void Hanoi(int n, char start, char finish, char temp);
int main(){Hanoi(3,'A','B','C');return 0;
} void Hanoi(int n, char start, char finish, char temp){if(n==1)cout << start << "->" << finish << ' ';else{Hanoi(n-1, start, temp, finish);//从第一根柱子移动到第三根 cout << start << "->" << finish << ' ';Hanoi(n-1, temp, finish, start);//再从第三根柱子移动到第二根 }
}

例6.11 用递归函数打印一个十进制整数的函数定义及使用

先递归到最后打印第一位数字,然后回调,利用%不断打印最后一位

#include <iostream>
using namespace std;void printInt(int num);int main(){int num;cout << "请输入一个整数:" << endl;cin >> num;printInt(num);cout << endl;return 0;} void printInt(int num){if(num < 10){ //递归终止条件 cout << static_cast<char>(num + '0');}else{printInt(num/10);cout << static_cast<char>(num%10 + '0');}
}

在此基础上进一步扩展,根据输入,打印不同进制的整数

#include <iostream>
using namespace std;void printInt(int num, int base);static char DIGIT[17] = "0123456789abcdef";int main(){int num,base;cout << "请输入一个整数:" << endl;cin >> num;cout << "请输入要打印的进制:" << endl;cin >> base;printInt(num, base);cout << endl;return 0;}void printInt(int num, int base){if(num < base)cout << DIGIT[num];else{printInt(num/base, base);cout << DIGIT[num%base];}
}

例6.12 设计函数打印n个字符的全排列

#include <iostream>
#include <string.h>
using namespace std;void PermuteWithFixedPrefix(char str[], int k);void swap(char str[], int k, int i);int main(){int n;cout << "请输入n:";cin >> n;cin.get();char str[n+1];cout << "请输入" << n << "个字符:";cin.getline(str,n+1);cout << "全排列结果为:\n";PermuteWithFixedPrefix(str, 0);return 0;
}void  PermuteWithFixedPrefix(char str[], int k){int i;if(k == strlen(str))cout << str << endl;else{for(i=k; i<strlen(str); ++i){swap(str, k, i);PermuteWithFixedPrefix(str, k+1);swap(str, k, i);}}
}void swap(char str[], int k, int i){int tmp;tmp = str[k];str[k] = str[i];str[i] = tmp;
}

例6.13 8皇后问题

思路:用一个int数组表示第i列放在col[i]行,三个一维布尔数组分别表示第i行能不能放,第i条右高左低的对角线位置能不能放,第i条左高右低的对角线位置能不能放(这个表达出来比较麻烦,需要观察一下),然后递归回溯遍历,从第1列开始放,直到放到最后一列

#include <iostream>
using namespace std;void queen_all(int k);int col[9];
bool row[9], digLeft[17], digRight[17];int main(){int j;for(j=0;j<=8;j++)row[j] = true;for(j=0;j<=16;j++)digLeft[j] = digRight[j] = true;queen_all(1);return 0;
}void queen_all(int k){int i,j;char awn;//是否继续寻找的标记 for(i=1; i<9; i++){if(row[i] && digLeft[k+i-1] && digRight[8+k-i]){col[k] = i; //第k列的皇后放在第i行row[i] = digLeft[k+i-1] = digRight[8+k-i] = false;if(k == 8){ //找到一个可行解 for(j=1;j<=8;j++){cout << "第" << j << "列皇后" << "-" << "第" << col[j] << "行" << '\n';}cout << endl << "是否继续寻找(Q--退出,其他键继续:)";cin >> awn;if(awn == 'Q' || awn == 'q')exit(0);}else{queen_all(k+1);}row[i] = digLeft[k+i-1] = digRight[8+k-i] = true; //回溯 }}
}

例6.14 分书问题

有编号0、1、2、3、4的5本书,准备分给5个人A、B、C、D、E,每个人的阅读兴趣用一个二维数组描述:
like[i][j]=true //i喜欢书j
like[i][j]=false //i不喜欢书j
编写程序,输出所有皆大欢喜的分书方案

#include <iostream>
using namespace std;void trynext(int i);bool like[5][5] = {{false,false,true,true,false},{true,true,false,false,true},{false,true,true,false,true},{false,false,false,true,false},{false,true,false,false,true}
};
int take[5] = {-1,-1,-1,-1,-1};int n=0;int main(){trynext(0); return 0;} void trynext(int i){int j, k;for(j=0; j<5; ++j){if(like[i][j] && take[j]==-1){take[j] = i;if(i==4){n++;cout << "\n第" << n << "种方案:" << endl;cout << "书\t人" << endl;for(k=0;k<5;k++){cout << k << '\t' << char(take[k]+'A') << endl;} }else{trynext(i+1);}take[j]=-1;//回溯 寻找下一方案 }}
}

例6.15 快速排序

#include <iostream>
using namespace std;void quicksort(int a[], int low, int high);int divide(int a[], int low, int high);int main(){int a[] = {5,7,3,0,4,2,1,9,6,8};cout << "排序前:" << "\n";for(int x:a){cout << x << " ";}cout << endl;quicksort(a,0,9);cout << "排序后:" << "\n";for(int x:a){cout << x << " ";}
} void quicksort(int a[], int low, int high){int mid;if(low >= high)return;mid = divide(a,low,high);quicksort(a,low,mid-1);//排左一半 quicksort(a,mid+1,high);//排右一半 }//分段函数,将数组分成两段
int divide(int a[], int low, int high){int k = a[low];while(low != high){while(low<high && a[high]>=k)--high;if(low<high){a[low] = a[high];++low;}while(low<high && a[low]<=k)++low;if(low<high){a[high] = a[low];--high;}}a[low] = k;return low;
}

例6.16 最大连续子序列和

如果所有整数都是负的,最长子序列和返回0

思路:可以利用分治法实现,分三种情况讨论,最大子序列和在左半部分,最大子序列和在右半部分,最大子序列和横跨左右部分,取其中的最大值

#include <iostream>
#include <limits.h>
using namespace std;int NEGMAX = INT_MIN;int maxSum(int a[], int left, int right);int max3(int a, int b, int c);
int main(){int a[] = {4, -3, 5, -2, -1, 2, 6, -2};int res = maxSum(a,0,7);cout << "最长连续子序列和:" << res << endl;
}int maxSum(int a[], int left, int right){int maxLeft,maxRight,center;int leftSum = 0, rightSum = 0;int maxLeftTmp = NEGMAX, maxRightTmp = NEGMAX; //NEGMAX最大负整数if(left == right)return a[left] > 0 ? a[left] : 0;center = (left + right) / 2;maxLeft = maxSum(a, left, center);//计算左半部分最大子序列和maxRight = maxSum(a, center+1, right);//计算右半部分最大子序列和//找从前半部分开始到后半部分结束的最大连续子序列和//从中间开始右到左遍历 for(int i = center; i>=left; --i){leftSum+=a[i];if(leftSum > maxLeftTmp)maxLeftTmp = leftSum;}//从中间下一个开始左到右遍历 for(int i = center+1; i<=right; ++i){rightSum+=a[i];if(rightSum > maxRightTmp)maxRightTmp = rightSum;} return max3(maxLeft, maxRight, maxLeftTmp+maxRightTmp);} int max3(int a,int b,int c){int max;max = a>b?a:b;return (max>c?max:c);
}

例6.17 硬币找零问题

对于一种货币,有面值为C1,C2…Cn(分)的硬币,最少需要多少个硬币来找出K分钱的零钱

动态规划解法:
从1分钱开始不断构建表格,coinsUsed[j]表示找零钱j需要的最小的硬币数,初始化coinsUsed[0]=0,coins[maxChange]是最终答案

#include <iostream>
using namespace std;void makechange(int coins[], int differentCoins, int maxChange, int coinUsed[]);int coinsUsed[10000];
int main(){int coins[] = {1,5,10,21,25};int maxChange;cout << "请输入要找的零钱(单位:分):";cin >> maxChange;makechange(coins,5,maxChange,coinsUsed);cout << "找"<< maxChange << "分零钱的最少硬币数:" << coinsUsed[maxChange] << endl;
}void makechange(int coins[], int differentCoins, int maxChange, int coinUsed[]){coinUsed[0] = 0;for(int cents = 1; cents<= maxChange; cents++){int minCoins = cents;//都用1分找零时硬币数最大 for(int j=1;j<differentCoins;j++){if(coins[j] > cents) //如果coins[j]大于要找的零钱则直接跳过进入下一次循环 continue;//减去当前硬币后零钱需要的最少硬币数+当前硬币if(coinUsed[cents - coins[j]]+1<minCoins){ minCoins = coinUsed[cents - coins[j]] + 1;}}coinUsed[cents] = minCoins;}
}

第六章-过程封装(函数)代码实例(C++蓝豹子)相关推荐

  1. Oracle编程入门经典 第11章 过程、函数和程序包

    目录 11.1          优势和利益... 1 11.2          过程... 1 11.2.1       语法... 2 11.2.2       建立或者替换... 2 11.2 ...

  2. js 音频音乐播放封装函数代码

    js函数代码 /*** 音频到网上找* src:音频链接**/ function playSound(src){var src;var borswer = window.navigator.userA ...

  3. 如何用六个步骤封装Python代码包

    假设你很喜欢用同一段Python代码,里面有几个相关的小型函数,或者是含有几百行代码的中型模块.程序员可能会把它复制到不同的项目或存储库中,或者从特别设置的实用工具代码文件夹中导入这段代码. 这很正常 ...

  4. C++ primer第六章6.4函数的学习 之函数的重载

    6.4 函数的重载 函数的名字相同但是形参的列表不同,将其称之为重载函数 void print(const char *cp); void print(const int *beg,const int ...

  5. C++ primer第六章6.7函数指针

    函数指针 函数指针指向的是函数而不是对象.和其他指针一样,函数指针指向某种特定的类型.函数的类型由他的返回类型和形参类型共同决定,而与函数的名字无关. //比较两个string对象的长度 bool l ...

  6. C++ primer第六章6.5函数的学习 之特殊用途的语言特性

    6.5.1 默认实参 将反复出现的数值称为函数的默认实参,调用含有默认实参的时候可以包含该实参也可以不包含 比如程序打开页面会有一个默认的宽高,如果用户不喜欢也允许用户自由指定与默认数值不同的数值,具 ...

  7. 第六章、Hash函数

    1.Hash函数 1.Hash函数(也称散列函数)是一个将任意长度的消息x序列映射为较短的.固定长度的一个值y的函数. 2.Hash函数的目的是为需要认证的数据产生一个'指纹'. 为了能够实现对数据的 ...

  8. c语言第七章函数实验总结,第六章 实验报告 (函数与宏定义)

    c语言实验报告 实验项目: 1.编写由三角形三边求面积的函数 2.编写求N的阶层 3.求两个整数的最大公约数 4.打印输出的指定图形 5.模块化程序设计 姓名:张顺利实验地点:第一教学楼514教室   ...

  9. SQL/Oracle——第六章 PL/SQL函数(作业3)

    第6章:PL/SQL块 --6-19 beginp3(var_job=>'SALESMAN',i,j,k); end; /declarecursor cur_emp(var_job in var ...

最新文章

  1. 【Ubuntu】apt-get命令小结
  2. 推荐6个绝赞良心工具,总有一些适合你!
  3. python入门需要多久-目前Python学习需要多长时间?老男孩Python入门培训
  4. 硬盘FAT32转NTFN格式的命令
  5. 指令—— 数据绑定指令||数据响应式||双向数据绑定指令
  6. r语言实现岭回归_数据分析中常见的七种回归分析以及R语言实现(五)
  7. scala-wordcount
  8. 无法连接到远程网络连接到服务器失败怎么办,无法远程桌面连接到服务器怎么办(连接失败原因和解决法)...
  9. Jedis连接Redis读写基本操作
  10. 北航|北京航空航天大学|介绍|简介
  11. 安卓udp发包工具_网络发包工具_xcap网络发包工具免费版V1.0.2下载(暂未上线)_预约_飞翔下载...
  12. 怎么接入WAPI网络防止被蹭网
  13. 1的阶乘加到20的阶乘
  14. 远程命令行添加(删除)注册表键值(远程打开)
  15. 插入排序和迭代归并排序以及复杂度分析
  16. 聊聊另外一个Druid(很全)
  17. java里面add报错,java错误
  18. UVM:一个简易验证平台例子
  19. opencv学习_7 (颜色空间)
  20. 【CCF会议期刊推荐】CCF推荐国际学术期刊/会议(人工智能)

热门文章

  1. HarmonyOS流畅度,harmonyos系统
  2. 学以致用--游戏:孢子(Spore) 中 殖民地 最佳布局
  3. 个人向前端知识“复健”
  4. 突然悟到了“追求卓越”的真谛
  5. 软件架构-解密电商系统营销-会员模块业务
  6. flickr_logos_27_dataset下载
  7. SSH Agent Forwarding原理
  8. Git版本控制管理——提交
  9. 重磅!2019「FAT」90位90后杰出从业者榜单揭晓
  10. Oracle 能够tnsping,但程序无法访问