精华内容
下载资源
问答
  • 数组

    2021-05-20 15:51:17
    数组可能是我们学习的第一个数据结构,虽然它很简单,但是如果从查询和更新的角度思考它,会发现很有意思的东西。 约定 a[i]:普通数组 s[i]:普通数组的前缀和数组 c[i]:普通数组的差分数组 普通数组 对于普通的一组...

    数组

    数组可能是我们学习的第一个数据结构,虽然它很简单,但是如果从查询和更新的角度思考它,会发现很有意思的东西。

    约定

    a[i]:普通数组
    s[i]:普通数组的前缀和数组
    c[i]:普通数组的差分数组

    普通数组

    对于普通的一组有序数据,a[i]存第ii个数据。
    单点查询O(1)O(1)
    区间查询O(n)O(n)
    单点更新O(1)O(1)
    区间更新O(n)O(n)

    差分数组

    c[i] = a[i] - a[i - 1]

    单点查询O(1)O(1)
    区间查询O(n)O(n)

    差分数组可以求出原数组的前缀和,s[i]=j=1i(ij+1)cjs[i] = \sum_{j=1}^{i}(i-j+1) \cdot c_{j},但复杂度O(n)O(n),并不具有优势。

    单点更新O(1)O(1)
    区间更新O(1)O(1) c[a] += k, c[b + 1] -= k(更新区间[a,b][a,b]

    前缀和数组

    a[i] = s[i] - s[i - 1]a[i]相当于是s[i]的差分数组。

    单点查询O(1)O(1)
    区间查询O(1)O(1)
    单点更新O(n)O(n)
    区间更新O(n)O(n)

    总结

    普通数组和前缀和数组各有优劣。普通数组区间操作均为O(n)O(n),单次操作均为O(1)O(1),相比于普通数组,前缀和数组可以快速进行区间查询,复杂度O(1)O(1),但是牺牲了区间更新,复杂度O(n)O(n)

    差分数组性能优秀,只有区间查询复杂度是O(n)O(n),其余均为O(1)O(1),完全优于普通数组。这个特性可以被用于优化树状数组,让树状数组可以同时区间更新,区间查询。

    扩展:二维数组

    1. 普通数组的二维数组还是很普通。
    2. 二维前缀和数组s[i][j]表示k=1il=1ja[k][l]\sum_{k = 1}^{i}\sum_{l = 1}^{j}a[k][l],递推式为s[i][j] = a[i][j] + s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1]
    3. 二维差分数组的定义很不直观,但类比a[i][j]相对于s[i][j],可以得到递推式:c[i][j] = a[i][j] - a[i - 1][j] - a[i][j - 1] + a[i - 1][j - 1]
      从二维差分数组推导二维前缀数组的公式: s[i][j]=k=1il=1ju=1kv=1lc[u][v]s[i][j] = \sum_{k = 1}^{i}\sum_{l = 1}^{j}\sum_{u = 1}^{k}\sum_{v = 1}^{l}c[u][v] (复杂度O(n4)O(n ^ {4}))可以化简成 s[i][j]=k=1il=1j(ik+1)(jl+1)c[k][l]s[i][j] = \sum_{k = 1} ^ {i}\sum_{l = 1}^{j} (i - k + 1)(j - l + 1)c[k][l] (复杂度O(n2)O(n ^ {2})), 用二维树状数组可以进一步达到O(log2n)O(log^{2}n)
    展开全文
  • 输入: 多组输入数据对于每组数据,第一个数为n(1),表示共有n名同学,接下来分别为各位同学的姓名(不超过12个字符,没有空格),学号(int范围内),成绩(0)。接下来一个数m,表示共有m组查询,每行只有一个...
  • 数据结构--数组

    2019-06-14 17:08:44
    第十一章 34 给一个包含 n 个数的整数数组 S,在 S 中找到所有使得和为给定整数 target 的四元组(a, b,c,d)。...例如,对于给定的整数数组 S=[1, 0, -1, 0, -2, 2] 和 target=0. 满足要求的四元组集...

    四数之和 4sum
    第十一章 34

    给一个包含 n 个数的整数数组 S,在 S 中找到所有使得和为给定整数 target 的四元组(a, b,c,d)。
    注意事项:
    四元组(a, b, c, d)中,需要满足 a <= b <= c <= d。
    答案中不可以包含重复的四元组。
    样例:
    例如,对于给定的整数数组 S=[1, 0, -1, 0, -2, 2] 和 target=0. 满足要求的四元组集合为:
    (-1, 0, 0, 1)
    (-2, -1, 1, 2)
    (-2, 0, 0, 2)

    解题思路:

    想参照之前的一题 3Sum 的解法来解决,结果超时了。换个思路,空间换时间。既然有四个数,那就把前两个数之和和后两个数之和分别当做一个数。现在要求的就是在一个列表中哪两个数的和为特定值。可以先遍历一遍列表,存值和它的下标的键值对,第二遍遍历列表寻找(目标值-当前值)是否在之前的键值对中,如果在就是符合的一组解。

    // An highlighted block
    
    class Solution(object):
        def fourSum(self,nums,target):
            if len(nums) < 4:
                return []
            result =set()
            sumsIndexes = {}
            for i in range(len(nums)):
                for j in range(i+1,len(nums)):
                    if nums[i]+nums[j] in sumsIndexes:
                        sumsIndexes[nums[i]+nums[j]].append((i,j))
                    else:
                        sumsIndexes[nums[i]+nums[j]]=[(i,j)]
            for i in range(len(nums)):
                for j in range(i+1,len(nums)):
                    sumNeeded = target-(nums[i]+nums[j])
                    if sumNeeded in sumsIndexes:
                        for index in sumsIndexes[sumNeeded]:
                            if index[0]>j:
                                result.add(tuple(sorted([nums[i],nums[j],nums[index[0]],nums[index[1]]])))
            result = [list(l) for l in result]
            return result
    
    if __name__ =="__main__":
        a=Solution()
        b=[1,0,-1,0,-2,2]
        c = 0
        print(a.fourSum(b,c))
    

    ----2020/3/12

    对一维整型数组a的正确说明是 #define SIZE 10 (换行) int a[SIZE];说法是否正确?

    正确答案: A
    正确
    错误
    解析: #define SIZE 10
    它的作用是指定标识符SIZE 来代替表达式10。

    ----已知二维数组A[1: 4, 1: 6]采用列序为主序方式存储,每个元素占用4个存储单元,并且A[3,4]的存储地址为1234,元素A[1, 1]的存储地址是()

    正确答案: A
    1178
    1190
    1278
    1290
    解析:a11+(3*4+2)*4=1234。这样就可以得到a11

    ----以下定义和初始化的两数组a1和a2,那么下列说法正确的是( )。
    char a1[]= “program”;
    char a2[]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’}
    正确答案: D
    a1和a2完全相同
    a1和a2不同,a1是指针
    a1和a2存储单元的数目相同
    a1和a2不同,a1的存储单元数目多

    解析:sizeof(a1)=8,sizeof(a2)=7,a1存储单元数目多。

    ----c中,二维数组初始化的方法是:int a[3][3]={{1},{2},{3}};说法是否正确?

    正确答案: A
    正确
    错误
    解析:正确的, 最外层的 { … } 会初始化 a[] 即第一维。

    ----已知数组D的定义是int D[4][8];,现在需要把这个数组作为实参传递给一个函数进行处理。下列说明汇总可以作为对应的形参变量说明的是()。
    正确答案: C D
    int D[4][]
    int *s[8]
    int(*s)[8]
    int D[][8]

    解析:int *s[8]; //定义一个指针数组,该数组中每个元素是一个指针,每个指针指向哪里就需要程序中后续再定义了。
    int (*s)[8]; //定义一个数组指针,该指针指向含8个元素的一维数组(数组中每个元素是int型)。

    区分int *p[n]; 和int (*p)[n]; 就要看运算符的优先级了。
    int * p[n]; 中,运算符[ ]优先级高,先与p结合成为一个数组,再由int *说明这是一个整型指针数组。
    int (*p)[n]; 中( )优先级高,首先说明p是一个指针,指向一个整型的一维数组。

    2020/3/13
    ----设有一个长度为n的顺序表,要在第i(从1开始)个元素之前(也就是插入元素作为新表的第i个元素),则移动元素个数为( )。
    正确答案: A
    n-i+1
    n-i
    n-i-1
    i

    解析:1 2 3 4 5
    n = 5
    要在第i=2个元素之前插入
    则n-i=3
    而实际插入位置为:
    1 [ ] 2 3 4 5
    所以是n-i+1

    ----下面哪项不是链表优于数组的特点?
    正确答案: D
    方便删除
    方便插入
    长度可变
    存储空间小
    解析:链表:方便插入和删除,包含数据和指针域,存储空间大。

    ----假设有60行70列的二维数组 a[1 …60, 1…70 ] 以列序为主序顺序存储,其基地址为10000,每个元素占2个存储单元,那么第32行第58列的元素 a[ 32,58 ] 的存储地址为

    正确答案: A
    16902
    16904
    14454
    以上答案均不对

    解析:
    第32行第58列的元素 表示为 a[ 32,58 ] ,但是我们习惯写成a【31】【57】
    二维数组可以表示为A【60】【70】 (60行70列)
    a[ 31,57 ]
    以列序为主: (5760+31) * 2+10000= 16902
    以行序为主: (31
    70+57)*2 +10000= 14454

    ----数组A[0…4,-1…-3,5…7]中含有元素的个数()
    正确答案: B
    55
    45
    36
    16
    解析:三维数组,533=45

    ----2020/3/14

    ----数组Q[n]用来表示一个循环队列,f为当前队列头元素的前一位置,r为队尾元素的位置,假定队列中元素的个数小于n,计算队列中元素的公式为()。

    正确答案: D
    r-f
    (n+f-r)% n
    n+r-f
    (n+r-f)% n

    解析:在这里插入图片描述

    ----数组常用的两种基本操作是( )。
    正确答案: C
    建立与删除
    删除与查找
    查找与修改
    插入与索引

    解析:删除的时间复杂度比较大,链式结构会采用删除。

    ----在前提:var arr=[1,3,2]下,下面哪个操作会返回一个数组,并且不是arr?
    正确答案: C
    arr.push(3)
    arr.reverse()
    [].concat.call(arr,[])
    [].sort.call(arr)

    解析:1.contact函数的功能是:连接两个或多个数组。将返回连接数组后的副本,不影响原来的数组 2.call函数调用一个对象的一个方法,以另一个对象替换当前对象 3.js中的函数其实是对象,函数名是对函数对象的引用。

    ----对有序数组{2、11、15、19、30、32、61、72、88、90、96}进行二分查找,则成功找到15需比较()次
    正确答案: C
    3
    4
    2
    5
    解析:C
    0 1 2 3 4 5 6 7 8 9 10
    2、11、15、19、30、32、61、72、88、90、96
    第一次 index=(0+10)/2=5 对应32 ; 比15大 所以下次范围是 0到4
    第二次 index=(0+4)/2=2 对应15 找到

    展开全文
  • [数据结构]后缀数组

    2015-08-08 15:26:27
    后缀数组是一个处理字符串的有力工具,对于常见的字符串匹配、模式匹配,求子串前缀等问题,后缀数组都有很好的效果。但是好难懂啊。。搜了国家集训队的论文,看了挑战书上的介绍,看了好长时间才稍微有一点感觉。。...

    后缀数组是一个处理字符串的有力工具,对于常见的字符串匹配、模式匹配,求子串前缀等问题,后缀数组都有很好的效果。

    但是好难懂啊。。搜了国家集训队的论文,看了挑战书上的介绍,看了好长时间才稍微有一点感觉。。就20多行的代码看了N久才理解…大概是我太弱了。

    根据论文先来总结一下后缀数组的主要内容吧。

    1、基本定义
    子串:字符串S的子串r[i…j],i≤j,表示r串中从i到j这一段形成的字符串。
    后缀:后缀是指从某个位置i开始到整个串末尾结束的一个特殊子串。
    大小比较:字符串的比较,是指通常所说的字典序比较,比较规则是这样的:

    对于两个字符串u、v,令i从1开始顺次比较u[i]和v[i]
    如果u[i] = v[i] 则令i+1,继续比较
    否则 若u[i] < v[i] 则认为u<v; u[i] > v[i],则认为 u > v。比较结束。
    如果i>min(len(u),len(v))仍然比较不出结果,那就比较uv的长度,长度大的那个字符串就是更大的串。

    后缀数组:后缀数组指的是将某个字符串的所有后缀按字典序排序后得到的数组。不过数组中并不需要直接保存所有的后缀字符串,只要记录对应的起始位置就好了。下文中,我们用S[i…]来表示字符串S从位置i开始的后缀。
    名次数组:名次数组Rank[i]保存的是S[i]在所有后缀中从小到大排列的名字。

    简单地说,后缀数组是“排第几的是谁?”名次数组是“你排第几?”。

    举例:
    这里写图片描述

    大家可以根据这个字符串,自己计算一下Rank。

    后缀数组的计算方法——倍增算法
    假设我们要计算长度为n的字符串S的后缀数组,最朴素的做法就是把所有后缀进行排序,将n个长度为O(n)的字符串进行排序的复杂度为O(n²logn)。而如果灵活运用所有的字符串都是S的后缀这一性质,就可以得到更高效的算法。

    该算法的基本思想是倍增。
    首先计算每个位置开始长度为2的子串的顺序,再利用这个结果计算长度为4的子串顺序,接下来计算长度为8的子串的顺序,不断倍增,直到长度大于等于n,就得到了所有的后缀数组。并且这些子串一定已经比较出了大小,即Rank[]中已经没有相同的值,那么此时的Rank值就是最后的结果。每一次排序都利用上次长度为2^(k-1)的字符串的Rank值,那么长度为2^k的字符串就可以用两个长度为2^(k-1)的字符串的排名作为关键字表示,然后进行排序,就得出了长度为2^k的字符串的Rank值。

    这里写图片描述

    这里写图片描述

    using namespace std;
    const int MAXN = 100000;
    int n,k;
    int Rank[MAXN+1];
    int tmp[MAXN+1];
    
    //比较(rank[i],rank[i+k])和(rank[j],rank[j+k])
    bool compare_sa(int i ,int j)
    {
        if (Rank[i]!= Rank[j]) return Rank[i] < Rank[j];
        else
        {
            int ri = i+k<=n? Rank[i+k] : -1;
            int rj = j+k<=n? Rank[j+k] : -1;
            return ri < rj;
        }
    }
    
    //计算字符串S的后缀数组
    void construct_sa(string S,int *sa)
    {
        n = S.length();
        //rank直接获取字符的编码
        for(int i = 0;i<=n;i++)
        {
            sa[i] = i;
            Rank[i] = i < n ? S[i] : -1;
        }
        //利用对长度为k的排序结果对长度为2k的排序
        for(k = 1; k <= n; k *= 2)
        {
            sort(sa,sa+n+1,compare_sa);
            //先在temp中临时存储新计算的rank,再转存回rank中
            tmp[sa[0]] = 0;
            for(int i = 1 ; i <= n; i++)
                tmp[sa[i]] = tmp[sa[i-1]] + (compare_sa(sa[i-1],sa[i])? 1: 0);
            for(int i = 0 ; i <= n; i++)
                Rank[i] = tmp[i];
        }
    }
    
    展开全文
  • 结构struct动态数组创建与操作

    万次阅读 2012-09-03 21:55:23
    在做hdoj的1009,本来这道题目不是很难,可是对于struct动态数组操作不是很熟,做了很久,在这里记录一下,避免下次继续出错。 FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/...

    在做hdoj的1009,本来这道题目不是很难,可是对于struct动态数组操作不是很熟,做了很久,在这里记录一下,避免下次继续出错。

    FatMouse' Trade

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 25384 Accepted Submission(s): 8029


    Problem Description
    FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean.
    The warehouse has N rooms. The i-th room contains J[i] pounds of JavaBeans and requires F[i] pounds of cat food. FatMouse does not have to trade for all the JavaBeans in the room, instead, he may get J[i]* a% pounds of JavaBeans if he pays F[i]* a% pounds of cat food. Here a is a real number. Now he is assigning this homework to you: tell him the maximum amount of JavaBeans he can obtain.


     

    Input
    The input consists of multiple test cases. Each test case begins with a line containing two non-negative integers M and N. Then N lines follow, each contains two non-negative integers J[i] and F[i] respectively. The last test case is followed by two -1's. All integers are not greater than 1000.


     

    Output
    For each test case, print in a single line a real number accurate up to 3 decimal places, which is the maximum amount of JavaBeans that FatMouse can obtain.


     

    Sample Input
    5 3 7 2 4 3 5 2 20 3 25 18 24 15 15 10 -1 -1


     

    Sample Output
    13.333
    31.500


    代码如下:

    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    
    struct trade{
    	int j;
    	int f;
    };
    
    bool compare(const trade &a, const trade &b){
    	return double(a.j)/double(a.f)>double(b.j)/double(b.f);
    }
    
    void main(){
    	int m,n;
    	double sum;
    	while(1){
    		sum=0.0;
    		scanf("%d %d",&m,&n);
    		if(m==-1)
    			break;
    		trade* array=new trade[n];
    		for(int i=0; i<n; i++){
    			scanf("%d %d",&array[i].j,&array[i].f);
    		}
    		sort(array,array+n,compare);
    		for(int j=0; j<n; j++){
    			if(m<array[j].f){
    				sum+=double(array[j].j)/double(array[j].f)*m;
    				break;
    			}
    			m-=array[j].f;
    			sum+=array[j].j;
    		}
    		printf("%.3f\n",sum);
    		delete []array;
    	}
    }
    


    其中,创建动态struct数组

    struct struct_name * struct_array = new struct_name[struct_array_len];

    输入struct数组元素值,记得不要落下&

    scanf("%d",&struct_array[i].struct_member);

    排序

    sort(struct_array,struct_array+struct_array_len,compare);

    释放

    delete []struct_array;

     

    展开全文
  • 记录对于数据结构的学习,第二天,加油+1 !!! 使用数组模拟队列,实现以下功能: 说明 方法 将数据添加到队列 addQueue() 将数据从队列移除 outQueue() 显示队列所有数据 showQueue() 显示队列的头...
  • 众所周知,在计算机中要对给定的数据集... 例如,对于数据集S{1,2,3,4,5,6},要求S中元素的和,首先要把数据存储到内存中,然后再将内存中的数据相加。  当内存空间中有足够大的连续空间时,可以把数据连续的
  • 05-golang数组

    2020-07-13 20:56:30
    golang数组 数组是golang中的一种数据结构。它是一种元素个数固定(长度固定),元素数据类型相同的集合。长度固定则意味着数组...var s [5]string // 声明一个长度为5,数据类型为string的数组s var m [10]int //声明
  • 块状数组解区间问题

    2019-09-26 07:20:03
    块状数组是一个非常有趣的数据结构,利用分块的思想将再简单不过的数组化腐朽为神奇,sqrt(n)虽不及log(n), 但是性价比还是很好的。 但是需要注意的是块状数组一定要从0开始,这样可以求出i在哪个块中 pos = i / ...
  • 一、定长数组 val nums = new Array[Int](10)//10个整数的数组,所有元素初始化为0 val s = Array("hello",...对于变长数组,Scala中的等效结构是ArrayBuffer import scala.collection.mutable.ArrayBuffer val b = Arr
  • 1. 定长数组 如果需要一个长度不变的数组,可以使用scala中的Array。例如   val nums=new Array[Int](10) ...对于长度需要变化的数组,Java有ArrayList,C++有vector。Scala中数据结构ArrayBuffer
  • 什么是数组数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同。 Java 数组:用来存储固定大小的同类型元素。 一 声明、创建,初始化Java 数组 写在前面:定义Java ...
  • struct 数组初始化问题

    千次阅读 2010-12-10 10:33:00
    对于在头文件中定义的全局结构数组变量,如何对其进行赋值,对于这个问题,经过我的尝试,我发现,只有一种方法:在main函数定义一个新的变量,然后在通过赋值给它,如果直接对其通过 xxx【x】 = { 。。。}的方式...
  • 堆栈的数组实现

    2018-05-05 02:28:39
    堆栈是由同类元素组成的表,其元素的...堆栈是一种先入后出的数据结构。 看以下对于堆栈的操作: class Stack { int top; int [] arr; public Stack() { // 设置栈的大小是10 this(10); } public S...
  • 给定一个数字字符串 S,比如 S = “123456579”,我们可以将它分成斐波那契式的序列 [123, 456, 579]。 形式上,斐波那契式序列是一个非负整数列表 F,且满足: 0 <= F[i] <= 2^31 - 1,(也就是说,每个整数...
  • 约瑟夫问题是数据结构与算法里的经典问题。我用C++数组写了个解答,并且加入了异常处理,来保证程序的正确性和健壮性。本人能力较差,让诸位大牛见笑了,请多多...下面要解决的Josephus问题是:对于任意给定的n,s和...
  • 数组与链表均为线性表,即一个元素的前继或后驱只有一个元素,为数据结构的基础。 其中数组与链表相比,数组具有按索引查询方便的特点,其查询的时间复杂度为o(1),而链表查询时最坏情况时,所查元素位于链表末端...
  • // Study_Program.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include &lt;math.h&gt;...//完全二叉树的最大节点数量...//对于一个数组结构的tree,要先...
  • 不相交集是解决等价问题的一种有效的数据结构,之所以称之为有效是因为,这个数据结构简单(几行代码,一个简单数组就可以搞定),快速(每个操作基本上可以在常数平均时间内搞定)。 首先我们要明白什么叫做等价...
  • 题目传送门赶紧去补一发树状数组,好像这个数据结构在NOIP里考察的频率挺高啊……(一口奶)考虑题目中三元组里的中间项jj,发现需要求出位置和权值都小于jj的个数ll与位置和权值都大于jj的个数rr,根据乘法原理,jj...
  • 在尚未学会用STL之前还是,简单的用用数组模拟下栈(FILO)先进后出的数据结构。这样对于咱们这样的新手而言也是一种不错的过渡~!代码如下~:#include #include int main() { char a[101],s[101]; int i,len,...
  • 后缀树:后缀树是一种数据结构,它支持有效的字符串匹配和查询。一个具有m个词的字符串S的后缀树T,就是一个包含一个根节点的有向树,该树恰好带有m个叶子,这些叶子被赋予从1到m的标号。 每一个内部节点,除了根节点...

空空如也

空空如也

1 2 3 4 5 ... 19
收藏数 375
精华内容 150
关键字:

对于结构数组s