算法交作业(一)

首先解释下标题的含义:在网上看了一位大牛写的基础算法相关的博文,感觉自己不是天赋异禀,所以决定自己实现一遍当作交作业。

开篇:

今天这篇博文是关于数组查找的,很简单。

算法是计算机的生命。没有算法,就没有软件,计算机也就成了一个冰冷的机器,没有什么实用价值。很多人认为,算法是数学的内容,学起来特别麻烦。我们不能认为这种观点是错误的。但是我们也知道,软件是一种复合的技术,如果一个人只知道算法,但是不能用编程语言很好地实现,那么再优秀的算法也不能发挥作用。一个人只有有了很好的计算机知识和数学知识,才能在算法的学习上不断进步。不管算法都么简单,都要自己亲手实践,只有不断认识错误、不断发现错误,才能不断提高自己的编程能力,不断提高自己的业务水平。

这里取名一步一步写算法的目的主要有两个:第一,保证我们的算法都是大家可以学得会,看的懂的;第二,保证我们的算法是健壮的、可以测试的。所以在编写的过程中,我们的算法开发过程是伴随着测试用例增加的,没有测试用例保证的代码只是一段无序的字符而已,没有什么价值。

其实任何算法都有自己的应用环境和应用场景,没有算法可以适用于所有的场景。这一点希望大家明白。同时,我们也要清楚复杂的算法都是由普通的算法构成的,没有普通的算法就没有复杂的算法可言,所以复杂变简单,由大化小,这就是算法分治递归的基本思想。

原文地址

上面的内容我感觉写的比较好,所以搬运了。下面正式实现自己的版本。

1.数组查找函数1.0版本:

int Find_Array(int arr[], unsigned length, const int& value){
    int index = 0;
    return index;
}
测试:
#include <iostream>
#include <assert.h>
//存在返回下标,否则返回-1表示查找失败。
int Find_Array(int arr[], unsigned length, const int& value){
    int index = 0;
    return index;
}
static void test1(){
    int arr[10] = { 0 };
    assert(Find_Array(nullptr, 10, 1)==-1);
    assert(Find_Array(arr, 0, 1) == -1);
}
int main(){
    test1();
}
通过测试可以看错程序的不健壮,需要对入口进行修改。

2.0版本:

int Find_Array(int arr[], unsigned length, const int& value){
    if (arr == nullptr || length == 0)
        return -1;
    int index = 0;
    return index;
}
//可以看到我们对入口进了测试。

3.0版本:

int Find_Array(int arr[], std::size_t length, const int& value){
    if (arr == nullptr || length == 0)
        return -1;
    for (std::size_t index = 0; index < length; ++index){
        if (arr[index] == value)
            return index;
        continue;
    }
    return -1;
}
static void test1(){
    int arr[10] = { 1,2};
    assert(Find_Array(nullptr, 10, 1)==-1);
    assert(Find_Array(arr, 10, 1) == 0);
}

4.0优化版本:

1)用指针进行优化:
int Find_Array(int arr[], std::size_t length, const int& value){
    if (arr == nullptr || length == 0)
        return -1;
    for (std::size_t index = 0; index < length; ++index){
        if (*(arr+index)== value)
            return index;
        continue;
    }
    return -1;
}

2)对形参进行优化:

using array = int(&)[10];//数组类型的引用。
int Find_Array(array arr, const int& value){
    if (arr == nullptr)
        return -1;
    for (std::size_t index = 0; index < 10; ++index){
        if (arr[index] == value)
            return index;
        continue;
    }

----------

C++ 11:
using array = int(&)[10];//数组类型的引用。
int Find_Array(array arr, const int& value){
    int index = 0;
    for (const auto& x : arr){
        if (x == value)
            return index;
        ++index;
        continue;
    }
    return -1;
}
void test(){
    int arr[10] = { 1, 2 };
    assert(Find_Array(arr, 10) == -1);
    assert(Find_Array(arr, 2) == 1);
}
//我们省略了数组大小的参数,不过上面的写法存在一定的局限性。

----------

3)模版函数版本:
template<class T>
int Find_Array(const T* const &arr, const std::size_t length, const T& value){
    if (arr == nullptr || length == 0)
        return -1;
    auto beg = arr, end = beg + length;
    while (beg != end)
        if (*beg++ == value)
            return beg - arr-1;
    return -1;
}
void test(){
    int arr[10] = { 1, 2 };
    assert(Find_Array(arr, 10,1) ==0);
    assert(Find_Array(arr, 10,3) == -1);
}

相关说明:

1.为什么用size_t?避免数组长度小于0.

2.参数的优化:尽量用const引用进行优化,锱铢必较。

3.测试平台:VS 2013+Win 7.

二次优化版本:

最近学了点标准库的内容,所以用向量和标准版定义的array 类型实现下。

#include <iostream>
#include <assert.h>
#include <vector>
#include <array>
//存在返回下标,否则返回-1表示查找失败。
//vector 版本。
int Find_Array(const std::vector<int>& ivec, const int& value){
    //不使用下标版本,直接使用迭代器。
    auto beg = ivec.begin(), end = ivec.end();
    if (beg == end)
        return -1;
    int index = 0;
    while (beg != end)
        if (*beg++==value)
            return beg - ivec.begin() - 1;
    return -1;
}

void test1(){
    std::vector<int> ivec = { 1, 2, 3 };
    assert(Find_Array(ivec,2)== 1);
    assert(Find_Array(ivec, 10) == -1);
    assert(Find_Array(std::vector<int>(), 10) == -1);

}
//标准库的数组版本。
int Find_Array(const std::array<int,10>& arr, const int& value){
    if (arr.empty())
        return -1;
    int index = 0;
    for (const auto& x : arr){
        if (x == value)
            return index;
        ++index;
        continue;
    }
    return -1;
}
void test2(){
    std::array < int, 10 > arr= {1, 2, 3};
    assert(Find_Array(arr, 2) == 1);
    assert(Find_Array(arr, 10) == -1);
    assert(Find_Array(std::array<int,10>(), 10) == -1);
}
int main(){
    test1();
    test2();
    system("pause");
    return 0;
}
----------
//来个可变参数列表试试。
int Find_Array(const std::initializer_list<int>& i1, const int& value){
    auto beg = i1.begin(), end = i1.end();
    if (beg == end)
        return -1;
    int index = 0;
    while (beg != end)
        if (*beg++ == value)
            return beg - i1.begin() - 1;
    return -1;
}
void test3(){
    assert(Find_Array(std::initializer_list<int>{1, 2, 3}, 1) == 0);
    assert(Find_Array(std::initializer_list<int>(), 10) == -1);
}

Summary:

1.算法的思路非常简单,我只不过闲的无聊重写了一遍。查找涉及到基本操作应该是遍历,计数等操作。

2.学会一步步优化算法。

3.拓宽算法的可用性。

4.保证健壮性。

5.博文参考:原文地址,戳我进去

时间: 2024-10-05 16:44:37

算法交作业(一)的相关文章

算法交作业之最大公约数

今天写一下最大公约数算法,英文简称为Gcd算法. 1.递归解法: /*书上并没有给出递归的解法,可能是觉得这个解法不是很完美,但是给出来就当学习下递归.*/ int Gcd(unsigned num1, unsigned num2){ if (num1 == 0 || num2 == 0)//算法基于欧几里德的算法. return (num1 > num2) ? num1 : num2; return Gcd(num2, num1%num2); } //代码写的很短小,但是效率可能不是很高 //

算法交作业之查找

前言: 刚刚写了一篇发泄文,果不其然,心里面舒服很多.既然心情舒畅了,那就继续写下去吧. 假定: 我们假定查找的数据唯一存在,数组中没有重复的数据存在. 普通查找: 适用情景: 无特征,需要遍历整个范围才可以确定. #include <iostream> #include <assert.h> //普通的查找算法. template<unsigned n> int Find_Array(const int(&arr)[n], const int& val

算法交作业之最大子序列问题

最近看<数据结构与算法分析>一书,书中提供的一些算法太棒了,忍不住动手实现了下.有错误请指出,谢谢. 最大子序列问题求解: 1.第一种解法: int MaxSubSequence(const int array[], int length){ if (length < 0) //数组长度不可以为0. return 0; int MaxSum = 0,ThisSum; for (int i = 0; i < length; ++i){ for (int j = i; j < l

算法交作业之循环和递归(二)

说明: 循环是学习编程过程中的不可或缺的一部分.同时递归同循环有着千丝万缕的关系. 求和函数示例: //求0到n的和.求和失败返回-1.否则返回结果. #include <iostream> //最常见的循环写法. long long Sum(unsigned int&& n){ long long sum = 0; for (unsigned index = 1; index <n+1; ++index) sum += index; return sum; } //递归

图同构哈希算法实现 (作业)

*/--> 图同构哈希算法实现 (作业) Table of Contents 代码 例子 1 例子 2 例子 3 例子 4 例子 5 例子 6 例子 7 不是同构 例子 8 不是同构 例子 9 不是同构 例子 10 不是同构 测试数据和测试图片参考地址 Hash 函数除了做为 Hash 表的辅助工具,在单独使用的时候可以实现判断两个数据是否相同或等价 代码 // CreateTime: 2015-05-15 21:24:47 #include <iostream> #include &l

BZOJ 3379: [Usaco2004 Open]Turning in Homework 交作业

Description 贝茜有C(1≤C≤1000)门科目的作业要上交,之后她要去坐巴士和奶牛同学回家. 每门科目的老师所在的教室排列在一条长为H(1≤H≤1000)的走廊上,他们只在课后接收作业.交作业不需要时间.贝茜现在在位置0,她会告诉你每个教室所在的位置,以及走廊出口的位置.她每走1个单位的路程,就要用1秒.她希望你计算最快多久以后她能交完作业并到达出口. Input 第1行输入三个整数C,H,B,B是出口的位置.之后C行每行输入两个整数,分别表示一个老师所在的教室和他的下课时间. Ou

ThinkPHP5作业管理系统中处理学生未交作业与已交作业信息

在作业管理系统中,学生登陆到个人中心后可以通过左侧的菜单查看自己已经提交的作业和未提交作业.那么在系统中如何实现这些数据的查询的呢?首先我们需要弄清楚学生(Student).班级(class).作业提交表(Submit)这三个表之间的关系. 每个学生都属于一个班级 班级里的每个学生都会被布置同样的作业 学生提交作业后会在作业提交表中添加响应的记录,如学生的ID,作业的ID,提交的内容等. 可以按照以下步骤获取学生已交作业和未交作业 获取学生所在班级的所有作业 //获取学生所在班级的所有作业  p

七月在线算法班作业

第一讲作业 管枫 昨天 星期六 22:51 数学分析教程,常庚哲,史济怀 p142:2,3,7,8; p143:3,4,6; p148:2,3,6; p176:8,11; p210:4,5; p211:6 在下述网站中找到今天所讲内容对应的章节并选择阅读, Index_1  lec(4,5,6,7,8) Index_2 ,lec(14,15) 请阅读下面两个我在七月问答里面的帖子. 一个贝叶斯后验估计的例子:老贝和老贫在赌场的故事 一个关于EM 算法的介绍:EM的思路,无奈和巧合 第二讲作业 管

[迷宫中的算法实践]关于一个数据结构与算法实践作业的总结

最近听闻数据结构与算法实践课的老师又出了和上年一样的选题,不禁想起了去年自己完成作业时的点点滴滴,遗憾当时没有写博客的习惯,之前的一些心得这一年实践的过去也逐渐淡忘了,突然就有了总结一下的想法,希望能有新的收获吧. 由于当时也没注意保存,软件完成过程中的一些文档早已丢失了,幸运的是Winform版源码还在,Unity3D版程序也还幸存,虽然由于时间紧张只完成了大概框架,但美观程度也远非Winform可以相比的,先上几张软件图吧: 生成算法 软件实现了普利姆算法.递归回溯算法.递归分割算法和深度遍