使程序在C中运行为线性

时间:2015-02-11 15:50:30

标签: c

基于cumulative sum query的以下问题,我创建了解决方案。但是在线性复杂度为O(N)的C中解决问题的还有其他方法吗?

问题描述:

  

William Macfarlane想看一个阵列。

     

您将获得N个数字和Q个查询的列表。每个查询都是   由两个数字i和j指定;每个查询的答案都是总和   范围[i,j](包括)之间的每个数字。

     

注意:使用基于0的索引指定查询范围。

     

输入

     

第一行包含N,即列表中的整数数(N <=   100,000)。下一行包含保证适合的N个数字   在整数内。列表后面是数字Q(Q <= 10,000)。该   下一个Q行每个包含两个数字i和j,用于指定查询   你必须回答(0&lt; = i,j&lt; = N-1)。输出

     

输出

     

对于每个查询,在其自己的行中输出该查询的答案   订购查询。

以下是解决方案:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

struct node {
    int first;
    int last;
};

int sum_array(int *array, int first, int last) {
    int sum = 0;
    for (int i = first; i <= last; i++) {
        sum += array[i];
    }

    return sum;
}

int main() {
    FILE* input = fopen("share.in","r");

    int N = 0;
    fscanf(input,"%d",&N);

    int *array = (int*)malloc(N * sizeof(int));

    for (int i = 0; i < N; i++) {
        fscanf(input,"%d",&array[i]);
    }

    int Q = 0;
    fscanf(input,"%d",&Q);

    struct node query[Q];

    for (int i=0; i < Q; i++) {
        fscanf(input,"%d",&query[i].first); 
        fscanf(input,"%d",&query[i].last); 
    }

    fclose(input);

    int sum = 0;
    for ( int i = 0; i < Q ; i++) {
        int first = query[i].first;
        int last = query[i].last;

        sum = sum_array(array,first,last);

        printf("Number of queries : %d , sum is %d\n",i ,sum);
    }

    free(array); 
    return 0;
}

更新

答案是好的。但出于某种原因我无法使其发挥作用

所以这里是重写的代码,如果有人能解释我做错了什么,我会很开心!请记住,我们希望范围为 [first,last]

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

struct node {
    int first;
    int last;
};

int sum_array(int *array, int first, int last) {
    int sum = 0;
    for (int i = first; i <= last; i++) {
        sum += array[i];
    }

    return sum;
}

int main() {
    FILE* input = fopen("share.in","r");

    int N = 0;
    fscanf(input,"%d",&N);

    int *array = (int*)malloc(N * sizeof(int));
    int *integralArray = (int*)malloc(N * sizeof(int));    

    for (int i = 0; i < N; i++) {
        fscanf(input,"%d",&array[i]);
        integralArray[i] = array[i] + ((i > 0) ? array[i-1] : 0);
    }

    int Q = 0;
    fscanf(input,"%d",&Q);

    struct node query[Q];

    for (int i=0; i < Q; i++) {
        fscanf(input,"%d",&query[i].first); 
        fscanf(input,"%d",&query[i].last); 
    }

    fclose(input);

    int sum = 0;
    for (int i = 0; i < Q ; i++) {
        int first = query[i].first;
        int last = query[i].last;

        sum = integralArray[last] - integralArray[first - 1];

        printf("Number of queries : %d , sum is %d\n",i ,sum);
    }

    free(array); 
    return 0;
}

1 个答案:

答案 0 :(得分:2)

你将形成整数数组。修改为:

int *array = (int*)malloc(N * sizeof(int));
int *integralArray = (int*)malloc(N * sizeof(int));

for (int i = 0; i < N; i++) {
    fscanf(input,"%d",&array[i]);
    integralArray[i] = array[i] + ((i > 0) ? integralArray[i-1] : 0);
}

因此integralArray[i]处的元素是array中从0i的所有元素的总和。

然后,要获得从ab的总和,其中a > bintegralArray[b]是从0b的总和, integralArray[a]是从0a的总和,因此您只需计算integralArray[b] - integralArray[a]即可获得ab的总和。直观地,integralArray[b]包含您想要的数字,但也包括a之前的数字。你不想要那些,所以你再把它们拿掉。

适当地包含或排除a处的号码和b处的号码。给定的数字将包括b处的数字,但不包括a处的数字。您可以将integralArray调整为更早(integralArray[b]是从0到b-1的总和)或调整您的指数。

相关问题