C++算法题——知识点
二分查找法(折半查找):
使用二分查找算法,必须保证查找表中存放的是有序序列(升序或者降序)。
二分查找算法的实现思路:
二分查找算法非常简单,下面通过一个实例给大家讲解该算法的实现思路。
例如,在升序的查找表 {10, 14, 19, 26, 27, 31, 33, 35, 42, 44} 中查找元素 33。初始状态下,搜索区域为整个查找表,用 low 记录搜索区域内第一个元素的位置,用 high 记录搜索区域内最后一个元素的位置。 (图1搜索区域是整个查找表)
二分查找算法的查找过程是:
1) 借助 ⌊(low+high)/2⌋ 公式,找到搜索区域内的中间元素。图 1 中,搜索区域内中间元素的位置是 ⌊(1+10)/2⌋=5,因此中间元素是 27,此元素显然不是要找的目标元素。(图 2 中间元素 27 不是目标元素)
整个查找表为升序序列,根据 27<33,可以判定 33 位于 27 右侧的区域,更新搜索区域为元素 27 右侧的区域。(图 3 更新搜索区域为 {31, 33, 35, 42, 44})
2) 图 3 中,搜索区域内中间元素的位置是 ⌊(6+10)/2⌋=8,因此中间元素是 35,此元素不是要找的目标元素。 (图 4 中间元素 35 不是目标元素)
根据 35>33,可以判定 33 位于 35 左侧的区域,更新搜索区域。(图 5 更新搜索区域 {31, 33})
3) 图 5 中,搜索区域内中间元素的位置是 ⌊(6+7)/2⌋=6,因此中间元素是 31,此元素不是要找的目标元素。(图 6 中间元素 31 不是目标元素)
根据 31<33,可以判定 33 位于 31 右侧的区域,更新搜索区域。(图 7 更新搜索区域 {33})
4) 图 7 中,搜索区域内中间元素的位置是 ⌊(7+7)/2⌋=7,因此中间元素是 33,此元素就是要找的目标元素。(图 8 成功找到目标元素)
找到了目标元素 33,二分查找算法执行结束。下面的动画演示了整个二分查找算法的执行过程:(图 9 二分查找算法)
所谓二分查找算法,其实就是不断地将有序查找表“一分为二”,逐渐缩小搜索区域,进而找到目标元素。当查找表中没有目标元素时(比如图 8 中的元素 33 为 32),最终会出现 low>high 的情况,此时就表明查找表中没有目标元素,查找失败。
break和continue的作用和区别:
break和continue都是用来控制循环结构的,主要是停止循环;
但是break是跳出整个循环,continue是跳出当前循环不执行后面的语句,
C++算法题——嵌套循环篇(二)
1.问题描述:
小游戏:猜数字
输入整数n(0<n<100), 想让程序猜到的值 如果程序没有猜中, 则提示太大/太小并让程序接着猜测 程序通过二分法不断缩小猜测范围, 直到猜中n。
例如n = 39
程序第一次猜测50, 判断数值太大
第二次猜测25, 判断数值太小
第三次猜测37 判断数值太小
43 大
40 大
38 小
39 正确
输入: n 表示被猜测值 输出: 每行输出一个整数, 表示程序当前猜测的数字 最终行输出猜测的次数
代码:
//二分查找法
int main(){
//--变量声明--
// 用户输入 让程序猜的数字
int n;
// 程序猜测的次数, 二分猜测法的上下限
int numb = 0, max = 100, min = 0;
//猜测值
int mid=0;
//--接收输入--
cin>>n;
while (mid!=n){
//--数据处理--
/*
猜测值 = (上限 + 下限) /2
如上限100 下限0 猜测值=50
上限100 下限50 猜测值=75
如果猜测值比n小, 则下限 = 猜测值+1
如果猜测值比n大, 则上限 = 猜测值-1
*/
mid=(min+max)/2;
if (mid>n){
max=mid-1;
} else if (mid<n){
min=mid+1;
}
cout<<mid<<endl;
numb++;
}
printf("最终猜测了%d次", numb);
}
2.问题描述:
输入菱形的边长n, 打印一个对应大小的菱形(1<n<100)
思路:
用坐标系的思路
设坐标点(x,y) 当x的绝对值 + y的绝对值 小于n时, 这个坐标点在菱形内
当x的绝对值 + y的绝对值 大于等于n时, 这个坐标点在菱形外
如: (2,2)在菱形内, (3,2)在菱形外, (-4,0)在菱形内, (4,1)在菱形外
代码:
//打印菱形
int main(){
int n;
//--接收输入--
cin>>n;
//--数据处理--
//--输出--
// 当n为5时, 坐标系的上下限分别是-4~4 最大高/宽度为9
for (int i = -n+1; i < n; i++) {
for (int j = -n+1; j < n; j++) {
// i的绝对值+j的绝对值 小于n 则在菱形范围内
if (abs(i) + abs(j) < n) {
printf("*");
}
else {
printf(" ");
}
}
printf("\n");
}
}
C++算法题——数组篇
1.问题描述:
设计一个程序, 输入数据数量N, 以及N个整数Ni. 将该组数据去重后打印 (1<N<100, 0 <= Ni <= MAX_INT) 样例输入: 10 1 3 2 6 2 6 4 8 2 6 样例输出: 1 3 2 6 4 8
思路:
将每个元素都和后面的元素进行判断
如果[i]和[j]值重复, 将[j]的值设为-1. 并且len-- {1,3,2,6,-1,-1,4,8,-1,-1}
都判断一遍后, 将值为-1的元素 用后一个元素值进行覆盖 {1,3,2,6,4,8}
代码:
int main(){
int n,len;
int arr[100];
cin>>n;
len=n;
for (int i = 0; i <n ; ++i) {
cin>>arr[i];
}
for (int j = 0; j <n ; ++j) {
for (int i = j+1; i <n; ++i) {
if (arr[j]==-1) break;
if(arr[i]==arr[j])
{
arr[i]=-1;
len--;
}
}
}
for (int k = 0; k <n ; ++k) {
if (arr[k]==-1){
for (int i = k+1; i <n ; ++i) {
if (arr[i]!=-1){
arr[k]=arr[i];
arr[i]=-1;
break;
}
}
}
}
for (int i = 0; i <len ; ++i) {
cout<<arr[i];
}
}
参考文章:二分查找(折半查找)算法详解