从集合中查找两个不同数字的总和,最接近查询编号

时间:2015-11-24 03:37:53

标签: c algorithm

我正在尝试解决以下问题:

  

输入:

     

输入包含多个案例。每个案例以整数n(1 <1)开始。   n 1000),表示该组中有多少个数字   整数。接下来n行包含n个数字。当然只有一个   一行中的数字。下一行包含正整数m   给出查询的数量,0&lt; m&lt; 25.接下来的m行包含一个   查询的整数,每行一个。输入由案例终止   其n = 0.当然,这种情况不需要处理。

           

输出:

     

输出应按下面的示例进行组织。对于每一个   查询输出一行给出查询值和最接近的总和   样本中的格式。输入将是没有关系的   发生。

我的代码:

#include <stdio.h>
//Prototype
void input_output(int n, int m);
int main (){

    int n=0; //Keep track of how many set of integers
    int m=0; //number of queries

    input_output(n, m);



    return 0;
}

//Prototype for the following function
int closest_sum(int n, int integers[], int query);

/* input_output: Output the correct data given by specific input
   intput: (int)number of integers, (int) number of queribes
   output: print out the correct cases without any return values*/
void input_output(int n, int m){
    //Counter for looping integers and queries arrays;
    int counter_n,counter_m;
    int case_val = 1; //Keep track of the case number
    scanf("%d", &n);
    while(n!=0){
        printf("Case %d:\n", case_val);
        int integers[n]; //store value of integers
        for(counter_n = 0; counter_n < n; counter_n++){
            scanf("%d", &integers[counter_n]);
        }
        scanf("%d", &m);
        int queries[m];// store queries' value
        for(counter_m = 0; counter_m < m; counter_m++){
            scanf("%d", &queries[counter_m]);
            int closest=closest_sum(n, integers, queries[counter_m]);
            printf("Closest sum to %d is %d.\n", queries[counter_m], closest);
        }
        scanf("%d", &n);
    }
}

/* closest_sum: return a closest sum to the query base on the integers input
   intput: (int)integers input data array
   output: none(only return the value of the closest sum*/
int closest_sum(int n, int integers[], int query){
    //Store the difference of different sum related to query
    //Only at the start it will have negative number to show that it is first time
    int current_diff = -1;
    int current = integers[0];//Set a template number

    //Counter for outer and inner loop, add each element
    int outside,inside;

    //Loop for outer index
    for (outside = 0; outside < n; outside++){
        //Loop for outer index(note that inside equals to outside to avoid depucate sum
        for(inside=outside; inside < n-1; inside++){
            //Store new possiable variable for new sum
            int new_num = integers[outside]+integers[inside+1];
            //Check which one is greater between query and new number(Avoid Negative number)
            //If the difference between new_num and query is less than current
            //Set current to new number
            int different = 0;//stores the differents of two number
            if (new_num<query){
                different = query-new_num;
            }else{
                different = new_num-query;
            }
            //If the function just started to process assign current diff to the first different
            if (current_diff == -1){
                current_diff = different;
            }

            //Set current to new_num
            if(different<=current_diff){
                current=new_num;
                current_diff = different;
            }
        }
    }
    return current;
}

示例输入:

  

5
  3
  12个
  17个
  33个
  34个
  3
  1
  51个
  30个
  3
  1
  2
  3
  3
  1
  2
  3
  3
  1
  2
  3
  3
  4
  5
  6
  0

示例输出:

  

案例1:
  最接近的1是15.
  最接近51的是51   最接近30的是29.

     

案例2:
  最接近的1是3.
  最接近的2是3.
  最接近的3是3.

     

案例3:
  最接近的4是4.
  最接近的5是5.
  最接近的6是5.

虽然我的代码工作正常,但我认为还有一些缺失。首先,我的代码由于某种原因而具有高复杂性,并且编译时需要一段时间。有人可以给我一些改进我的代码的建议吗?感谢。

(此外,使用while循环始终要求用户输入是个好主意吗?)

1 个答案:

答案 0 :(得分:2)

  1. 首先,将n个整数输入到数组中。
  2. O(n.log(n))时间内对其进行排序。
  3. 现在,对于m的每个查询,请执行以下操作:

    /*     arr => array holds sorted values    */
    
    int low  = 0;               // Lower Index of an array
    int high = length;          // Upper Index of an array
    
    int query_value;            // Input from the user
    int near_value;             // Near Value to be calculated
    int difference = INT_MAX;   // difference between near_value and query_value
    int temp;
    
    while(low < high) {
        temp = arr[low] + arr[high];
    
        if(temp == query_value) {
            near_value = query_value;
            break;
        } else if(temp < query_value) {
            if(abs(temp - query_value) < difference) {
                difference = abs(temp - query_value);
                near_value = temp;
            }
    
            low++;
        } else {
            if(abs(temp - query_value) < difference) {
                difference = abs(temp - query_value);
                near_value = temp;
            }
    
            high--;
        }
    }
    
    print near_value;          // Print the near_value calculated
    
  4. 现在,让我们谈谈时间复杂性。因为,我们首先对数组进行排序,然后对于每个m查询,我们在near_value线性时间内计算其O(n)

    因此,净时间复杂度为: O(n.log(n)+ n.m)(注意:不包括轮数)。