精华内容
下载资源
问答
  • 《大数据和人工智能交流》头条号向广大初学者新增C 、Java 、Python 、Scala、javascript 等目前流行的计算机、大数据编程语言,希望大家以后关注本头条号更多的... 以下能正确定义二维数组并正确赋初值的是:A、 ...

    《大数据和人工智能交流》头条号向广大初学者新增C 、Java 、Python 、Scala、javascript 等目前流行的计算机、大数据编程语言,希望大家以后关注本头条号更多的内容。

    一、选择题

    1、执行完以下代码int[] x=new int[25];下面那个正确:

    A. x[24]为0

    B、 x[24]未定义

    C、 x[25]为0

    D、x[0]为空

    2. 以下能正确定义二维数组并正确赋初值的是:

    A、 int n=5,b[n][n]

    B、 int a[ ] [ ]

    C、 int c[ ][ ]=new int({1,2},{3,4});

    D、 int d[ ][ ]={{1,2,3},{4,5}};

    3.下面哪些选项声明了一个数组并用5个数对数组进行初始化?

    A Array a=new Array(5);

    B int [] a={23,22,23,21,19};

    C int [] array;

    D int array[]=new int[5];

    F int [5] array;

    4.对于数组元素默认的初始化,下面哪些选项是正确的?

    A int为1;

    B Strng 为"" null " "

    C char为' '

    D float为0.0

    F boolean为true

    5. 下面说法正确的是?

    class Test

    {

    static int len[]=new int[10];

    public static void main(String args[])

    {

    System.out.println(len[2]);

    }

    }

    A、 编译错误

    B、 编译通过但是运行出错

    C、 输出0

    D、 输出null

    6、 下列数组的声明有哪些是对的?

    A、 int[] a;

    B、 int a[] = new int[3];

    C、 int[] a;

    a = {1,2,3,4,5};

    D、 int[] a = new int[3]{1,2,3};

    7、下面错误的初始化语句是?

    A、 char str[]="hello"

    B、 char str[100]="hello"

    C、 char str[]={'h','e','l','l','o'}

    D、 char str[]={'hello'}

    8、下面程序运行的结果为

    public static void main(String args[])

    {

    int a[][]={{1,2,3},{4,5,6}};

    System.out.println(a[1][1]);

    }

    9、下面不是创建数组的正确语句是?

    A、 float f[][]=new float[6][6];

    B、 float f[]=new float[6];

    C、 float f[][]=new float[][6];

    D、 float [][]f=new float[6][];

    二、填空题

    1.定义一个String类型的二维数组,并为数组赋空串

    String a[ ][ ]=new String[2][ 3];

    for(int i=0;i

    {

    for(j=0;_a[i].length_______;j++)

    {

    a[i][j]= _""_____;

    }

    }

    2.对数组每个元素赋值,然后按逆序输出

    public class test{

    public static void main(String[] args){

    int i;

    int a[]=new int[5];

    for(i=0;i<5;i++)

    a[i]=i;

    for(________;______;______)

    System.out.println("a["+i+"]="+a[i]);

    }

    }

    3.数组复制,用源数组的后5项中的前4项覆盖目的数组后4项

    public class test{

    public static void main(String[] args){

    int[] src={1,2,3,4,5,6};

    int[] dest={11,12,13,14,15,16,17};

    System.arrayCopy(____________);

    for(int i=0;i

    System.out.println("dest["+i+"]="+dest[i]);

    }

    }

    三、分析运行结果

    1.分析运行结果

    public class test{

    public static void main(String[] args){

    String s=new String("hello");

    String t=new String("hello");

    char c[]={'h','e','l','l','o'};

    System.out.println(s==t);

    String u=new String(c);

    System.out.println(t.equals(u));

    }

    }

    2. 分析运行结果

    class Example{

    public static void main(String args[]){

    StringBuffer sb1=new StringBuffer("Amit");

    StringBuffer sb2=new StringBuffer("Amit");

    System.out.println(sb1==sb2);

    System.out.println(sb1.equals(sb2));

    }

    }

    3分析运行结果

    public class test{

    public static void main(String args[]){

    Boolean a[]=new Boolean[4];

    int i=1;

    System.out.println(a[i]);

    }

    }

    4.分析运行结果,当输入java test 1 2 3

    public class test{

    public static void main(String args[]){

    System.out.println(args[2]);

    }

    }

    5.下列程序运行的结果为?

    import java.util.Arrays;

    public class Test

    {

    public static void main(String args[])

    {

    int a[]={1,13,26,8,9};

    int b[]={-12,56,77};

    a=b;

    Arrays.sort(a);

    for(int i=0;i

    {

    System.out.println(a[i]);

    }

    for(int i=0;i

    {

    System.out.println(b[i]);

    }

    }

    }

    6.下列程序是否有错,如果有错如何修改?

    public class Test

    {

    public static void main(String args[])

    {

    String s1[]=null;

    String s2[]={null,null,null};

    String s3[]=new String[3];

    System.out.println(s1[0]);

    System.out.println(s2[0]);

    System.out.println(s3[0]);

    }

    }

    四、编程实现

    1、使用冒泡排序算法对数组int[] arr = { 10, 2, 34, 5, 12, 8, 43 };进行排序

    2、有5个学生的Java成绩如下:29、89、56、78、89、12、67、90。利用数组求出分数最低的学员

    3、从终端输入5个字符,利用数组设计个程序使其倒序输出

    4、有一个数组为int a[]={12,56,78,23,67,88,90};设计个程序来查找数组的元素,如果找到则提示

    "已经找到该元素",并给出所在位置,如果没找到则提示"没有此元素"

    五、回答问题

    1、有如下数组定义,下列程序运行结果为?

    public static void main(String args[])

    {

    char c[]=new char[3];

    int arr[]=new int[3];

    double d[]=new double[3];

    float f[]=new float[3];

    String s[]=new String[3];

    System.out.println(c[1]);

    System.out.println(arr[1]);

    System.out.println(d[1]);

    System.out.println(f[1]);

    System.out.println(s[1]);

    }

    2、一位数组和二维数组数组如何实现遍历?

    3、如何解决ArrayIndexOutOfBoundsException异常?

    4、下列声明有错吗?

    (1) int a[3];

    (2) int b[]=new int[]{1,2,3}

    (3) int c[3][2]={{1,2},{2,3},{3,4}};

    5、下列程序运行有异常吗?如果有如何修正?

    public static void main(String args[])

    {

    char c[]="ABCDEF".toCharArray();

    int i=0;

    while(c[i+1]!='0')

    {

    System.out.println(c[i++]);

    }

    }

    088ba1c1dc6b2bf570bf95068f90c879.png

    《大数据和人工智能交流》的宗旨

    1、将大数据和人工智能的专业数学:概率数理统计、线性代数、决策论、优化论、博弈论等数学模型变得通俗易懂。

    2、将大数据和人工智能的专业涉及到的数据结构和算法:分类、聚类 、回归算法、概率等算法变得通俗易懂。

    3、最新的高科技动态:数据采集方面的智能传感器技术;医疗大数据智能决策分析;物联网智慧城市等等。

    根据初学者需要会有C语言、Java语言、Python语言、Scala函数式等目前主流计算机语言。

    根据读者的需要有和人工智能相关的计算机科学与技术、电子技术、芯片技术等基础学科通俗易懂的文章。

    展开全文
  • 通过之前的讲解,我了解了数组的定义,数组的性质,一些重要的知识点我们再回顾一下:a) 在数组的录入时需要三键输入。b) 数组公式可以同时进行多个计算,可返回一个或多个结果。c) 多单元格数组公式需选择多个...

    f5c7e36d395757daa20be938c4069ae0.png

    大家好,今天我们继续讲解VBA数组与字典解决方案的第12讲,从这讲开始我们开始讲数组的运算了。通过之前的讲解,我了解了数组的定义,数组的性质,一些重要的知识点我们再回顾一下:

    a) 在数组的录入时需要三键输入。

    b) 数组公式可以同时进行多个计算,可返回一个或多个结果。

    c) 多单元格数组公式需选择多个单元格进行输入,编辑修改时不可以只改变其中一部分。

    d) 数组公式具有集合性和制约性。

    从今日开始我们讲解数组的运算规则,通过讲解,读者要掌握各种数组的运算规律。今日讲的是行列数相同数组的运算。

    一:如下图,这是横向的一维数组的计算,结果是{=B1:F1+B3:F3}

    0c0df4deb4bfd3913d21dcea6d93fa1b.png

    数组1+数组2,这是一个多单元格的数组公式,第一个数组的第一个元素与第二个数组的第一个元素相加,结果作为数组公式结果的第一个元素,然后第一个数组的第二个元素与第二个数组的第二个元素相加,结果作为数组公式结果的第二个元素,接着是第三个元素……直到第N个。

    二 纵向一维数组的运算:

    数组1*数组2,这也是一个多单元格的数组公式,计算{=A9:A13*C9:C13},第一个数组的第一个元素与第二个数组的第一个元素相乘,结果作为数组公式结果的第一个元素,然后第一个数组的第二个元素与第二个数组的第二个元素相乘,结果作为数组公式结果的第二个元素,接着是第三个元素……直到第N个。

    0074fc49e201eeb76fc5e0cc41372773.png

    三:二维数组与二维数组进行计算,下面将计算{=I2:J6-L2:M6}的结果

    e6609f81f4d1246d2c9a50a8c62afbbf.png

    运算后将生成一个新的二维数组的多单元格数组公式。同样的计算过程,第一个数组的第一行的第一个元素与第二个数组的第一行的第一个元素相减,第一个数组的第一行的第二个元素与第二个数组的第一行的第二个元素相减,结果为数组公式的结果的数组的第一行的第二个元素,接着是第三个……直到第N个。

    综述上面的结果:行列数相同数组的运算规律很简单,两个同行同列的数组计算是对应元素间进行运算,并返回同样大小的数组。

    正如穿鞋要穿合脚的才走得了路一样,在公式或函数中使用数组时,运算对象或参数的数组维数要匹配,否则计算会出错。教室里,第一排的有18个同学,第二排有19个同学,老师说:“第一排和第二排的同学交换作业,互相检查。”第二排的第19个同学和谁交换?这就是数组的不匹配。数组不匹配时,工作就不能完成了。上面的解释也是数组制约性的一种。

    今日内容回向:

    1 行列数相同数组的运算规律是什么?

    2 上面内容中就是讲的是数组的制约性,如何理解?

    展开全文
  • 1008 数组右移问题每日编程中遇到任何疑问、意见、建议请公众号留言或直接撩Q474356284(备注每日编程)一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥...输入格式:每个输入...
    1008 数组右移问题

    每日编程中遇到任何疑问、意见、建议请公众号留言或直接撩Q474356284(备注每日编程)

    一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(0)个位置,即将A中的数据由(AAA)变换为(AAAAA)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

    输入格式:

    每个输入包含一个测试用例,第1行输入N(1N100)和M(0);第2行输入N个整数,之间用空格分隔。

    输出格式:

    在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。

    输入样例:

    6 2
    1 2 3 4 5 6

    输出样例:

    5 6 1 2 3 4
    938d7b8995d2009316002c2ff4a8ac5f.gif
    解决方法:

    (1)算法的基本思想:

    更改打印次序。先打印倒数m个元素,再打印从1到倒数第m个元素。

    (2)代码实现:

    #include 
    #include 

    //灰灰考研
    int main () {
        int i;
        int n;
        int m;
        char ch = ' '// 打印控制变量, 默认空格
        int arr[100];  // 下标0, 不存数据

        scanf("%d", &n);
        scanf("%d", &m);
        m = m % n; // 确保 m // 给数组赋值for (i=1; i<=n; i++) {scanf("%d", &arr[i]);
        }// 接下来分两次, 分别控制打印顺序// 第1次打印, 从倒数第m个数开始for (i=n-m+1; i<=n; i++) {printf("%d ", arr[i]);
        }// // 第2次打印, 从1到倒数第m个数for (i=1; i<=n-m; i++) {if (i == (n - m)) {
                ch = '\n';
            }printf("%d%c", arr[i], ch);
        }return 0;
    }
    明日预告:1009 说反话

    给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。

    输入格式:

    测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。

    输出格式:

    每个测试用例的输出占一行,输出倒序后的句子。

    输入样例:

    Hello World Here I Come

    输出样例:

    Come I Here World Hello
    63ad5be2ee7f9773bfd74c0a4b06e9d8.png

    01b9333cad738a1a91077847d100e762.png

    展开全文
  • 如何数组和标记关联 0101 这样的数据一眼望上去第一反应就是二进制啊 对于 arr 来说,有 4 个元素,对应的选择方式就是从 0000( N = 0 )到 1111( N = 4 )的所有可能。 而 1111 就是 15 的二进制,也就是说这所有...

    编者按:本文由前端狂想录公众号授权奇舞周刊转载。

    故事的背景

    这是一个呆萌炫酷吊炸天的前端算法题,曾经乃至现在也是叱咤风云在各个面试场景中。

    可以这样说,有 90% 以上的前端工程师不会做这个题目。

    这道题涉及的知识点很多,虽然网上也有相关的解答文章,但是在算法小分队的讨论和分析中,一致认为网上的文章太旧了,而且最多就是贴贴代码,写写注释,并没有具体的分析。

    暴风雨前的宁静

    我们看一下题目:

    从一个数组中找出 N 个数,其和为 M 的所有可能。

    大家可以中断 5 分钟想一下,不管想什么,反正先看着题目想 5 分钟。

    想完了吗?

    是不是感受到了一股杀气,好像知道些,但是又无从下手的那种胜利的感觉,嗯...?

    机智(鸡贼)的我,选择先把题目留在这儿,我们先去探讨一下算法。

    为什么算法就可以无法无天?

    关于上面这个无解的问题,我们默默不说话。现在,我们来思考几个简单点的哲学问题:

    什么是算法?

    算法的作用和目的是什么?

    如何设计我们的算法?

    算法的复杂度该如何表示?

    如何测试和优化我们的算法?

    嗯?我怎么感觉死循环了呢?无限递归且没有终止条件?

    6592d54be3f045db7a5fbce041f1b835.gif

    什么是算法

    《算法导论》一书将算法( algorithm )描述为定义良好的计算过程,它取一个或一组值作为输入,并产生一个或一组值作为输出。

    e610600c1960fa200b339805db5b9280.png

    计算的组成

    计算机主要的单元包括:I/OCPU 、内存等,这里我们要介绍的是CPU

    CPU 负责的功能主要就是解释和执行程序,它能认识的就是一堆 01 组成的机器码。

    我们敲下的每一行代码最终都被编译成机器码,然后将机器码交给 CPU 执行。

    想一想上面的话,我们可以知道:

    我们所知的程序,其实就是指令和数据的集合,而算法的本质就是执行设计好的指令集,从输入到产生输出的过程。

    算法是抽象的概念,但越是抽象的东西,其越具有清晰的特征。特征如下:

    1. 确定性: 算法的每一个步骤都是明确的、可行的、结果可预期的

    2. 有穷性: 算法要有一个终止条件

    3. 输入和输出: 算法是用来解决问题的,少不了输入和输出

    大多数人只看见了树,却未见森林

    看到这,你可能有疑问,为什么要这样说呢?且听我娓娓道来:

    列举一些大家可能知道的一些词吧:

    递归法、贪婪法、分治法、动态规划法、线性规划法、搜索和枚举法(包括穷尽枚举)、极大极小值法、 Alpha-beta 、剪枝等等。

    看到上面这些稀罕词,很多人认为这就是算法了,但其实这只是算法设计范式中,一些前人总结出来的模式而已。

    我们可以将这种算法层面的模式和平常我们说的设计模式进行对比。

    对比后,会发现,这就是一种算法抽象的最佳实践范式。其实我们写的任何一个代码片段(包含输入和输出),都可以认为是算法的子集,甚至程序也只是算法的一种存在形式而已。

    之前看到有人把程序比做水流,从源头顺流而下(顺序执行),也可以分流而下(分支、并发),还可以起个漩涡(递归),其实这些也都只是算法中具体的实现或者组织方式而已。

    算法的领域极其广阔,不要把思维仅仅局限在计算机领域中。

    对于计算机行业人员来说,算法就是内功。就好比乾坤大挪移,学成之后,天下武功皆能快速掌握。

    算法设计

    这一块儿其实是很庞大的知识体系,需要苦练内功根基。下面简要介绍下算法设计方面的知识。

    顺序执行、循环和分支跳转是程序设计的三大基本结构。

    算法也是程序,千姿百态的算法也是由这三大基础结构构成的。

    算法和数据结构关系紧密,数据结构是算法设计的基础。

    如果对诸如哈希表、队列、树、图等数据结构有深刻的认识,那在算法设计上将会事半功倍。

    上面提到的知识,主要的目的是抛砖引玉。算法的设计与分析是无上神功的心法口诀和入门要领。无论多么精妙绝伦的算法实现,都是由一些最基础的模型和范式组装起来的。

    关于算法设计,这里给大家推荐一门课程,很不错,小伙伴可以看看:

    算法设计与分析-Design and Analysis of Algorithms(https://zh.coursera.org/learn/algorithms)

    TIPS: 小伙伴如果有好的资源,也可以留言 mark 哦。

    最 NICE 的解法

    降维分析,化繁为简

    现在,到了最关键的时刻。我们回到题目中,开始设计我们的算法。

    题干信息很简单,核心问题在于:

    如何从数组中选取 N 个数进行求和运算。

    如何做,这里我们通常且正确的做法,是对问题进行降维分析,并且化繁为简。

    下面开始降维分析,化繁为简:

    假如 N = 2 ,也就是找出数组中两个数的和为 M 的话,你会怎么做?可能你会想到每次从数组中弹出一个数,然后与余下的每个数进行相加,最后做判断。

    那么问题来了,当 N = 3 呢,N = 10 呢,会发现运算量越来越大,之前的方式已经不可行了。

    不妨换一种思路:

    数组中选取不固定数值 N ,我们可以尝试着使用标记的方式,我们把 1 表示成选取状态, 把 0 表示成未选取状态。

    假设数组 const arr=[1,2,3,4] ,对应着每个元素都有标记 0 或者 1 。如果 N=4 ,也就是在这个数组中,需要选择 4 个元素,那么对应的标记就只有一种可能 1111 ,如果 N=3 ,那就有 4 种可能,分别是 111011011011 以及 0111 (也就是 C4取3->4 ) 种可能。

    开始抽象

    通过上面的层层叙述,我们现在的问题可以抽象为:

    标记中有几个 1 就是代表选取了几个数,然后再去遍历这些 1 所有可能存在的排列方式,最后做一个判断,这个判断就是:每一种排列方式,都代表着数组中不同位置的被选中的数的组合,所以这里就是将选中的这些数字,进行求和运算,然后判断求出的和是不是等于 M

    于是,问题开始变得简单了。

    如何将数组和标记关联

    0101 这样的数据一眼望上去第一反应就是二进制啊

    对于 arr 来说,有 4 个元素,对应的选择方式就是从 0000( N = 0 )到 1111( N = 4 )的所有可能。

    1111 就是 15 的二进制,也就是说这所有的可能其实对应的就是 0 - 15 中所有数对应的二进制。

    这里的问题最终变成了如何从数组长度 4 推导出 0 - 15

    这里采用了位运算--左移运算, 1 << 4 的结果是 16

    所以我们可以建立这样一个迭代:

    const arr = [1, 2, 3, 4]

    let len = arr.length, bit = 1 << len

    // 这里忽略了 0 的情况(N = 0),取值就是 1 - 15

    for(let i = 1; i < bit; i++) {

      // ...

    }

    如何从 1110 标记中取出 1 的个数

    最简单的方式:

    const n = num => num.toString(2).replace(/0/g, '').length

    这其实也是一道算法常考题,因为位运算是不需要编译的,肯定速度最快。

    PS: 如果不理解位运算为何会提高性能的同学,可以自行搜索一下位运算。简单点说就是:位运算直接用二进制进行表示,省去了中间过程的各种复杂转换,提高了速度。

    我们尝试使用 & 运算来解决这个问题

    首先我们肯定知道 1 & 1 = 1; 1 & 0 = 0 这些结论的。所以我们从 15 & 14 => 14 可以推导出 1111 & 1110 => 1110 ,为什么可以这样推导呢,因为 15 的二进制就是 111114 同理。

    我们可以看到,通过上面的操作消掉了最后的 1

    所以我们可以建立一个迭代,通过统计消除的次数,就能确定最终有几个 1 了。

    代码如下:

    const n = num => {

      let count = 0

      while(num) {

        num &= (num - 1)

        count++

      }

      return count

    }

    计算和等于 M

    现在我们已经可以把所有的选取可能转变为遍历一个数组,然后通过迭代数组中的每个数对应的二进制,有几个 1 来确定选取元素的个数。

    那么,现在需要的最后一层判断就是选取的这些数字和必须等于 M

    这里其实就是建立一个映射:

    1110[1, 2, 3, 4] 的映射,就代表选取了 2, 3, 4,然后判断 2 + 3 + 4M

    这里可以这样看:1110 中的左边第一个 1 对应着数组 [1, 2, 3, 4] 中的 4

    现在有一个问题,该如何建立这个映射关系呢?

    我们知道前者 1110 其实就是对应的外层遍历中的 i = 14 的情况。

    再看看数组[1, 2, 3, 4] ,我们可以将元素及其位置分别映射为 1000 0100 0010 0001

    实现方式也是通过位运算--左位移来实现:

    1 << inxinx 为数组的下标。

    位掩码介绍

    位掩码 不熟悉的童鞋会有点晕,这里简单科普下:

    实质上,这里的 1 << j ,是指使用 1 的移位来生成其中仅设置第 j 位的位掩码。

    比如:14 的二进制表示为 1110,其代表(从右往左)选取了第 2 , 3 , 4 位。

    那么(下面故意写成上下对应的方式):

    // demo1

      1110

    &

      0001

    =

      0000

    // demo2

      1110

    &

      0010

    =

      0010

    PS: 通过上面代码,我们可以看到上下对应的 01 在进行 & 运算以后,得出的结果和在 js 中进行相同条件下 & 运算的结果相同。

    所以:

    1 << 0 // 1 -> 0001

    1 << 1 // 2 -> 0010

    1 << 2 // 4 -> 0100

    1 << 3 // 8 -> 1000

    // 说白了,就是把左边的值变成二进制形式,然后左移或者右移,超出补0

    // 所以, 1110 对应着 第一位没有选取,那么 1110 & 0001(设置为第一位的位掩码) = 0,如果 i & (1 << inx) !== 0 代表该位被选取了

    for(let j = 0; j < arr.length; j++){

      if((& (1 << j) !== 0) {

        // 代表这个数被选取了,我们做累加求和就行

      }

    }

    所以综上所述,最终代码实现如下:

    // 参数依次为目标数组、选取元素数目、目标和

    const search = (arr, count, sum) => {

      // 计算某选择情况下有几个 `1`,也就是选择元素的个数

      const n = num => {

        let count = 0

        while(num) {

          num &= (num - 1)

          count++

        }

        return count

      }

      let len = arr.length, bit = 1 << len, res = []

      // 遍历所有的选择情况

      for(let i = 1; i < bit; i++){

        // 满足选择的元素个数 === count

        if(n(i) === count){

          let s = 0, temp = []

          // 每一种满足个数为 N 的选择情况下,继续判断是否满足 和为 M

          for(let j = 0; j < len; j++){

            // 建立映射,找出选择位上的元素

            if((& 1 << j) !== 0) {

              s += arr[j]

              temp.push(arr[j])

            }

          }

          // 如果这种选择情况满足和为 M

          if(=== sum) {

            res.push(temp)

          }

        }

      }

      return res

    }

    如何测试

    这其实也是可以单独写一篇文章的知识点。

    测试的种类、方式多种多样,我们将自己想象成一个 TroubleMaker ,各种为难自己写的算法,然后不断优化自己的代码,这个过程也是有趣极了。

    首先二话不说,照着心里一开始就想的最简单的方式撸一个测试用例。

    代码如下:

    // 写一个很大的数组进行测试

    const arr = Array.from({length: 10000000}, (item, index) => index)

    // 测试不同选取容量

    const mocks = sum => [3, 300, 3000, 30000, 300000, 3000000].map(item => ({count: item, sum }))

    let res = []

    mocks(3000).forEach((count, sum) => {

      const start = window.performance.now()

      search(arr, count, sum)

      const end = window.performance.now()

      res.push(end - start)

    })

    然后结果如下图:

    7f51bb75700ab82a54f0dadea7560d76.png

    发现造了一个长度为 1000 万的数组,找 6 个数,居然只要 0.014 秒。什么鬼,这么快的么,开挂了吧。不行,感觉这不靠谱,还是从长计议,写一个专业的测试案例比较好,请继续往下看。

    我们主要从两个方向下手:

    第一个方向:全方位攻击

    其实就是抠脑袋想出一万种情况去折腾自己的代码,也就是所谓的 地毯式测试案例轰炸。

    完整代码如下:

    // 比如针对上面的算法,可以这样写

    export const assert = (desc, condition) => {

      condition = typeof condition === "function" ? condition() : condition;

      console.info(`[Test] %c${desc}`, "color: orange");

      if (!condition) {

        throw new Error(`[Error] %c${desc} failed.`, "color: pink");

      }

      console.info(`[Success] %c${desc} success.`, "color: #198");

    };

    const mock_a = Array.from({ length: 4 }, (item, index) => index);

    const mock_b = Array.from({ length: 6 }, (item, index) => index - 3);

    const mock_c = Array.from({ length: 4 }, () => 0);

    assert(`正整数情况测试`, () => {

      const res = search(mock_a, 2, 3);

      const lengthTest = res.length === 2;

      const resTest = JSON.stringify(res) === JSON.stringify([[1, 2], [0, 3]]);

      return lengthTest && resTest;

    });

    assert(`负数情况测试`, () => {

      const res = search(mock_b, 2, 0);

      const lengthTest = res.length === 2;

      const resTest = JSON.stringify(res) === JSON.stringify([[-1, 1], [-2, 2]]);

      return lengthTest && resTest;

    });

    // ...

    codesandbox 完整代码地址(https://codesandbox.io/s/38pn0jvmr1)

    codesandbox 的运行控制台下,可以看到测试结果如下图所示:

    13fb61c5792ad8c5c6f61950161225e0.png

    会发现,这里把很多测试场景都覆盖了,这样的好处就是让自己的代码能够更鲁棒、更安全。

    当然,上面的 case 还可以再极端点,从而可以驱使代码变得更加鲁棒。

    极端的场景带来的优化如下:

    第一个极端:增加小数的情况。因为精度误差的问题,这里就可以将代码继续优化,以支持小数情况。

    第二个极端:增加公差参数的情况。不用绝对相等来取数,可以通过公差来增加灵活性。

    第二个方向:性能测试和持续优化

    关注的第二个点在于性能测试,为什么呢?

    如果要将自己的算法付诸生产,除需要稳定的功能表现之外,还要有足够让人信服的性能。毕竟,性能高的代码是我们普遍的追求。

    这里分享一下有用的技巧:

    通过 window.performance.now() ,或者 console.time() ,我们可以简单快捷的获取到程序执行的时间。

    在写这样的测试案例的时候,有几个原则,分别是:

    只关注自己的测试内容。

    保持干净

    考虑极端情况(比如数组很大很大)

    将多次测试结果进行对比分析

    当然你也可以使用类似 jsperf 之类的工具,然后一点一点的去扣这些优化点,来持续打磨自己的代码。

    这里提一下,虽然通过测试数据的反馈,可以调整你的算法。但是不要为了性能盲目的进行优化,性能优化其实就是找一个平衡点,原则是足够用就好。

    具体怎么做呢?对于上面的算法,我们如果采用空间换时间的优化方式,可以在计算 1 的个数的 n 函数上做一些优化 ,比如加个缓存。

    然后对比性能,如下图所示::

    8b6c2b63e28bb720c4756dadbc2a88c3.png

    完整的测试案例地址(https://jsperf.com/acm-perf/1)

    测试性能对比

    说到测试性能对比,这里主要收集一些实现方式,比如基于 jsperf 做一些对比。

    如果有其他的实现方式,欢迎小伙伴留言补充。

    jsperf 测试性能结果,如下图所示::

    95b0135e3adf2c646b361eaffa0f328a.png

    完整的测试案例地址(https://jsperf.com/acm-r/1)

    总结

    这道题很有难度,用到的知识也很多,认真想一想,一定能有很多收获的,这道算题的解决,大致用到了以下这些知识:

    1. 二进制以及位运算的知识

    2. 剪枝的思想

    3. 如何全方位、地毯式、走极端、多方面的对一个算法进行性能测试

    4. 算法思想,算法设计相关的简要知识

    5. 如何将极其抽象的问题进行降维分析,化繁为简

    番外篇--复杂度

    算法复杂度

    这涉及到大 O 判断法。(算法业内一般不叫大 O ,叫 big O 连起来读,比如 B沟N )

    这部分内容大家自行维基搜索吧,很详细的。下面我们提一下,离我们工作很近的一种复杂度的计算法则。

    如何判断业务代码的复杂度

    对前端来说,大 O 判断法不能太适用,其实还有一种很有趣的判断复杂度的方法,它叫做 Tom McCabe 方法。

    该方法很简单,通过计算函数中 决策点 的数量来衡量复杂度。下面是一种计算决策点(结合前端)的方法:

    1. 1 开始,一直往下通过函数

    2. 一旦遇到 if while for else 或者带有循环的高阶函数,比如 forEach map 等就加 1

    3. case 语句中的每一种情况都加 1

    比如下面代码:

    function fun(arr, n) {

      let len = arr.length

      for (let i = 0; i < len; i++) {

        if (arr[i] == n) {

            // todo...

        } else {

            // todo...

        }

      }

    }

    按照 Tom McCabe 方法来计算复杂度,那么这个 fun 函数的决策点数量是 3 。知道决策点数量后,怎么知道其度量结果呢?这里有一个数值区间判断:

    数量区间度量结果
    0-5这个函数可能还不错
    6-10得想办法简化这个函数了
    10+把这个函数的某一部分拆分成另一个函数并调用他

    从上面的判断依据可以看出,我上面写的代码,数量是 3 ,可以称为函数还不错。我个人觉得这个判断方法还是很科学和简单的,可以作为平时写代码时判断函数需不需要重构的一个考虑点,毕竟一个函数,一眼扫去,决策点数量大致就知道是多少了,很好计算。

    感谢付出的小伙伴

    非常感谢前端算法小分队的成员一起努力攻克了这个题目。

    特此感谢:

    本文第一作者:小金刚(大佬)

    github 地址:https://github.com/cbbfcd

    掘金地址:https://juejin.im/user/593df367128fe1006aecb3cf

    文章排版和内容深度完善:源码终结者

    github 地址:https://github.com/godkun

    参与审校和核对:Ninja

    github 地址:https://github.com/jiameng123

    其他小伙伴的贡献:前端狂想录算法小分队整体成员

    编者:此外还有一篇《改进,从一个数组中找出 N 个数,其和为 M 的所有可能》(https://juejin.im/post/5c81fee66fb9a049b82b4128),采用的是二进制正序表示法,各位同学可以对照看一下。

    关于奇舞周刊

    《奇舞周刊》是360公司专业前端团队「奇舞团」运营的前端技术社区。关注公众号后,直接发送链接到后台即可给我们投稿。

    4b846ac5cc4c8770cae2faa57bd058e7.png

    展开全文
  • printf("完成输入信息请以回车键结束 \n"); printf("-------------------------------------------------------------------------- \n"); for(i=0;i;i++) { printf("请输入航班号: \n"); scanf("%d",&s[i].num); ...
  • 素材直接来源:大鱼机器人说到指针,估计还是有...在讲指针之前,我们先来了解下变量在「内存」中是如何存放的。在程序中定义一个变量,那么在程序编译的过程中,系统会根据你定义变量的类型来分配「相应尺寸」的内...
  • 数组C++中相同元素的集合,实现一个变量存储多个元素的目的。 案例描述 期末考试结束,王老师想知道这次考试中成绩优秀的同学有多少人(考试成绩大于或等于90表示成绩优秀),请你编程帮助王老师来计算出成绩优秀...
  • 以上代码,build之后能够生成excel.tlh等的文件,就可以使用一些智能指针,本人实现了运用这个智能指针计算输入数组元素个数的简单的函数,如: double __stdcall RowsCount(Excel::RangePtr &pRange) { int rows =...
  • cout“数组元素个数=”< cin>>n; APP(ary,n); Sort(ary,n); for(i=0;i { a[j]=ary[i]; b[j]=1; while(ary[i]==ary[i+1]) { b[j]=b[j]+1; i++; } j++; } cout(j–;j>=0;j–) cout(“pause”); }
  •   相信大家在做许多OJ题目时,遇到往vector数组输入不确定行和列的数组,那么该如何处理呢? 1、一维数组的不确定输入   这里我们通过cin.get(),这个函数来进行判断,判断输入的是否为回车(也就是换行符),...
  • C++在字符数组输入空格的方法

    千次阅读 2013-08-04 20:38:41
    那么,如何C++在字符数组输入空格呢,在此小结一下: 1、cin.get()  用法1: cin.get(字符变量名)可以用来接收字符  #include  using namespace std;  main ()  {  char ch;  ch=cin....
  • 感谢@ShaderJoy大佬对本文提供的支持如何传输一个超大数组给着色器程序?在 OpenGL ES 图形图像处理中,会经常遇到一种情况:如何将一个超大的数组传给着色器程序?目前常用的有三种方式:使用将数组加载到 2D 纹理...
  • 作者最近发现了如何输入的字符串数组遇到自己想遇到哪个值就停止的方法,一起来康康吧。 #include<iostream> using namespace std; int main() { char a[100]={0}; int count=0; char c; do { a[count]...
  • 最近在做题的时候在处理输入时遇到一个令人头疼的问题,今天解决了和大家分享一下:比如题目要求的输入为一行数,数与数之间用空格间隔开,数的个数未知,数也有正有负:11 -2 65 7那么如何把这个输入保存到数组a中...
  • 以上代码,build之后能够生成excel.tlh等的文件,就可以使用一些智能指针,本人实现了运用这个智能指针计算输入数组元素个数的简单的函数,如: double __stdcall ArraySum(Excel::RangePtr &pRange) { ...
  • #实例化一个整数数组的长度2输入=()#给数组赋值(输入不支持迭代)输入11[0]=[1][2]= 3 = 2输入输入[3]= 4 = c_char_p #字节(aaaa级、编码=\u2026定义cpp文件来实现算法的逻辑,因为编译器会重命名c++函数在编译时,所以...
  • 另外,关于将未知长度的字符串输入数组,还有什么好办法吗? ``` int main() { int time; scanf("%d", &time); int count=0; while(count ) { string str; char temp; int i; while((temp=cin.get())!=...
  • //输入数组元素数目 p = new Student[count];//定义动态数组 for ( i = 0; i ; i++) { //学号 string id; //姓名 string Name; //性别 string Sex; //年龄 string Age; //省份 ...
  • 如下是我编写的高斯顺序消元法程序,input函数是我自定义的,希望输入一个矩阵,然后给Gauss和zg matrix函数调用,但是输入的矩阵不知如何传递过去。 #include <stdio.h> //包含输入输出函数 #include <stdlib.h>//...
  • 给一个整数数组,如何输入任意个整数 以空格区别,以回车结束,开始时不需要输入要输入整数的个数
  • 要求:在屏幕中,输入一行数字,以空格分隔,其中每个数字的长度不一定一样,要求将这些数字分别存放到数组中。例如:输入:1 123 1234 22 345 25 5对应的数组的值应该为a[0]=1,a[1]=123,a[2]=1234,a[3]=22,a[4]=345...
  • 那么如何把Excel中的单元里的数据当作数组输入呢?这个方法有一个快捷方式,即选定一个单元格区域,在“编辑栏”里输入“=”+数据或“=”+公式。按Shift+Ctrl+Enter组合键。此时,查看编辑栏里的值会多出一个{...
  • 数组C++语言重要的数据结构,对它的一些基本操作要熟练掌握。今天,我们就来讨论,如何数组中插入元素? 案例 题目描述 在一个数组的第x个位置插入一个新的数y。 输入 有四行 第一行有一个整数n ( 5 <= n <...
  • 文章目录英文版(只能输入英文)中文版(只能输入中文) 英文版(只能输入英文) 代码如下: #include <iostream> #include <cstdio> #include <cstring> using namespace std; int main() { ...
  • 题目描述: 一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右...如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法? 输入格式: 每个输入包含一个测试用例,第1行输...
  • 数组C++语言重要的数据结构,对它的一些基本操作要熟练掌握。今天,我们就来讨论,如何实现数组元素的查找? 案例描述 给你m个整数,查找其中有无值为n的数,有则输出该数第一次出现的位置,没有则输出-1。 输入 第...
  • 数组C++语言重要的数据结构,对它的一些基本操作要熟练掌握。今天,我们就来讨论,数组元素的逆序问题? 案例 题目描述 给你m个整数,将其逆序输出。 输入 第一行一个整数m(3 <= m <= 100 ):数组中数的...
  • # include # include # include using namespace std ; int main ( ) { vector < string > ...每次输入字符串敲一下回车,继续输入下一个字符串,输入完毕后,ctrl+z,结束。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 546
精华内容 218
关键字:

c++如何输入数组

c++ 订阅