第二周周记——算法篇

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];
    }
}

参考文章:二分查找(折半查找)算法详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值