在C范围内的值 [英] Range values in C

查看:101
本文介绍了在C范围内的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我想在解决一个问题的 C
我们有10个数字{1,1,8,1,1,3,4,9,5,2}在数组中。我们打​​破阵列分为3 pecies A,B,C。

和wemake下面的步骤操作(pfered创建一个小图,以便您可以更好地undertand我,我$ P $)。 图这里

正如你看到这是不是所有的程序它仅仅是开始。

我创建了一个code,但我得到错误的结果。什么我错过了?

 的#define N 10INT sum_array为(int *数组,诠释第一,诠释去年){
    INT RES = 0;
    的for(int i =第一; I< =最后,我++){
        RES + =阵列[我]
    }
    返回水库;
}
诠释主(){    int数组[N] = {1,1,8,1,1,3,4,9,5,2};
    诠释最小= 0;
    对于(INT A = 1; A< N - 2; A ++){
        INT ProfitA = sum_array(数组,0,A-1);
        INT ProfitB =阵列[A];
        INT ProfitC = sum_array(数组,A + 1,N-1);
        对于(INT B = 1; B< N - 1; b ++){
                //此处的值是当前 - 有效
                INT TEMP =(ProfitA< ProfitB)? ProfitA:ProfitB;
                闵=(ProfitC<临时)? ProfitC:温度;
                //最小=的std ::分钟(的std ::分(ProfitA,ProfitB),ProfitC);
                如果(闽> INT_MAX){
                    最小= INT_MAX;                }                //在这里,他们正在为下一次迭代prepared
                ProfitB = ProfitB +阵列[A + B-1];
                ProfitC = ProfitC - 阵列[A + B];
        }
}
    的printf(%D,最小值);
    返回0;
}

程序的复杂性是Ο(N 的(N + N))= O(N ^ 2)

要发现这里的排列的数量是功能:1 + 0.5 * N *(N-3),其中N是阵列中元件的数目*

下面是伪code中的第一个,虽然该方案。复杂度为O(n ^ 3)

  //初始化,填充工资阵列
N:=长度工资阵
best_min_maximum:=无穷
current_min_maximum:=无穷
best_bound_pos1:= 0
best_bound_pos2:= 0
对于i = 0 ..(N-2):
>>对于j =第(i + 1)..(N-1)
>>>> current_min_maximum = max_bros_profit(工资,I,J)
>>>>如果current_min_maximum< best_min_maximum:
>>>>>> best_min_maximum:= current_min_maximum
>>>>>> best_bound_pos1:= I
>>>>>> best_bound_pos2:= j的max_bros_profit(profit_array,position_of_bound_1,position_of_bound_2)
所以max_bros_profit([8 5 7 9 6 2 1 5],1(==)天之间第一次的空间,从0开始计数,3)除preTED为:
8。 5 | 7。 9 | 6 0.2。 1。 5 - 返回的最大总和[8 5] [7 9] [6 2 1 5] => 14
> ^ - ^ - ^ - ^ - ^ - ^ - ^
> 0,1,2,3,4,5,6


解决方案

这是我服用。它是贪婪算法,与一个最大B范围的开始,然后开始斩去值相继直到结果不能提高。这事呢复杂 O(N)

 的#include<&iostream的GT;
#包括LT&;实用>
#包括LT&;阵列GT;
#包括LT&;&算法GT;
#包括LT&;&了cassert GT;//拆分数组`arr`分为三个部分A,B,C。
//返回指数,B和C的第一单元
//(A的第一个元素显然指数0)
模板< typename的T,::性病::为size_t的len>
::性病::对< ::的std ::为size_t,::性病::为size_t>拆分(T常量(安培; ARR)[长度]){
  断言(LEN→2);
  //初始化A节,B和C的起始指数
  //使得A:{0},B:{1,...,LEN-2},C:{LEN-1}
  ::性病::阵列< ::的std ::为size_t,3> IDX = {0,1,LEN-1};
  //初始化所有部分的preliminary总和
  ::性病::阵列< T,3>总和= {改编[0],ARR [1],ARR [LEN-1]};
  对于(::性病::为size_t我= 2; I< LEN-1 ++ I)
    总结[1] + =改编由[i];
  //将preliminary最大
  T最大= ::性病::最大值({总和[0],总和[1],总和[2]});
  //现在我们迭代,直到B节不为空
  而((IDX [1] +1)下; idx的[2]){
    //我们努力缩小B,我们必须决定是否削减的
    //最左边的元素的一种或C的最右边的元件
    //所以我们找出A和C的总和新会是什么,如果我们
    //这样做了。
    ŧ常量左=(总和[0] + ARR [IDX [1]);
    ŧ常量右=(总和[2] + ARR [IDX [2] -1]);
    //我们总是先填补小部分,因此,如果将
    //小于C,我们切元素关到A.
    如果(左< =右放大器;&安培;左< =最大值){
      //我们只需要更新的款项,以新计算的值。
      //此外,我们必须将B一开始索引
      //元素向右
      总和[0] =左;
      总结[1] - =改编[idx的[1] ++];
      //更新的最大部分总和
      最大= ::性病:: MAX(总和[1],总和[2]); //左不能大于
    }否则如果(右LT;左&功放;&安培;右LT =最大值){
      //类似于其他情况,但在这里我们移动至起始
      //索引的下1到左边,有效地收缩B.
      综上所述[2] =权利;
      总结[1] - =改编[ - idx的[2]];
      //更新的最大部分总和
      最大= ::性病:: MAX(总和[1],总和[0]); //权利不能更大
    }其他中断;
  }
  //最后,一旦我们完成后,我们回到第一个指数
  // B和C,所以调用者知道我们的分区的样子。
  返回::性病:: make_pair(IDX [1],idx的[2]);
}

它返回索引到B范围的开始和索引到C范围的起始

So I want to solve a problem in C We have 10 numbers {1,1,8,1,1,3,4,9,5,2} in an array. We break the array into 3 pecies A, B, C.

And wemake the bellow procedure (I prefered to create a small diagram so you can undertand me better). Diagram here

As you see this isn't all the procedure just the start of it.

I created a code but I getting false results. What have I missed?

#define N 10

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

    int array[N] = {1,1,8,1,1,3,4,9,5,2};
    int Min = 0;
    for (int A = 1; A < N - 2; A++) {
        int ProfitA = sum_array(array, 0 ,  A-1);
        int ProfitB = array[A];
        int ProfitC = sum_array(array,A+1,N-1);
        for (int B = 1; B < N - 1; B++) {
                //here the values are "current" - valid
                int temp = (ProfitA < ProfitB)    ? ProfitA : ProfitB;
                Min =  (ProfitC < temp) ? ProfitC : temp;
                //Min = std::min(std::min(ProfitA,ProfitB),ProfitC);
                if (Min > INT_MAX){
                    Min = INT_MAX;

                }

                //and here they are being prepared for the next iteration
                ProfitB = ProfitB + array[A+B-1];
                ProfitC = ProfitC - array[A+B];
        }
}
    printf("%d", Min);
    return 0;
}

Complexity of program is Ο(n (n+n))=O(n^2 )

To find the number of permutations here is the function : 1+0.5*N*(N-3) where N is the number of elements in the array.*

Here is the first though of the program in pseudocode. Complexity O(n^3)

   //initialization, fills salary array 
n:= length of salary array 
best_min_maximum:=infinity 
current_min_maximum:=infinity 
best_bound_pos1 :=0 
best_bound_pos2 :=0 
for i = 0 .. (n-2): 
>> for j = (i+1) .. (n-1) 
>>>> current_min_maximum = max_bros_profit(salary, i, j) 
>>>> if current_min_maximum < best_min_maximum: 
>>>>>> best_min_maximum:=current_min_maximum 
>>>>>> best_bound_pos1 :=i 
>>>>>> best_bound_pos2 :=j 

max_bros_profit(profit_array, position_of_bound_1, position_of_bound_2) 
so max_bros_profit([8 5 7 9 6 2 1 5], 1(==1st space between days, counted from 0) , 3) is interpreted as: 
8 . 5 | 7 . 9 | 6 .2 . 1 . 5 - which returns max sum of [8 5] [7 9] [6 2 1 5] => 14 
> ^ - ^ - ^ - ^ - ^ - ^ - ^ 
> 0 , 1 , 2 , 3 , 4 , 5 , 6 

解决方案

This is my take. It is a greedy algorithm that starts with a maximal B range and then starts chopping off values one after another until the result cannot be improved. It hast complexity O(n).

#include <iostream>
#include <utility>
#include <array>
#include <algorithm>
#include <cassert>

// Splits an array `arr` into three sections A,B,C.
// Returns the indices to the first element of B and C.
//    (the first element of A obviously has index 0)
template <typename T, ::std::size_t len>
::std::pair<::std::size_t,::std::size_t> split(T const (& arr)[len]) {
  assert(len > 2);
  // initialise the starting indices of section A, B, and C
  //   such that A: {0}, B: {1,...,len-2}, C: {len-1}
  ::std::array<::std::size_t,3> idx = {0,1,len-1};
  // initialise the preliminary sum of all sections
  ::std::array<T,3> sum = {arr[0],arr[1],arr[len-1]};
  for (::std::size_t i = 2; i < len-1; ++i)
    sum[1] += arr[i];
  // the preliminary maximum
  T max = ::std::max({ sum[0], sum[1], sum[2] });
  // now we iterate until section B is not empty
  while ((idx[1]+1) < idx[2]) {
    // in our effort to shrink B, we must decide whether to cut of the
    //   left-most element to A or the right-most element to C.
    //   So we figure out what the new sum of A and C would be if we
    //   did so.
    T const left = (sum[0] + arr[idx[1]]);
    T const right = (sum[2] + arr[idx[2]-1]);
    // We always fill the smaller section first, so if A would be
    //    smaller than C, we slice an element off to A.
    if (left <= right && left <= max) {
      // We only have to update the sums to the newly computed value.
      // Also we have to move the starting index of B one
      //    element to the right
      sum[0] = left;
      sum[1] -= arr[idx[1]++];
      // update the maximum section sum
      max = ::std::max(sum[1],sum[2]); // left cannot be greater
    } else if (right < left && right <= max) {
      // Similar to the other case, but here we move the starting
      //    index of C one to the left, effectively shrinking B.
      sum[2] = right;
      sum[1] -= arr[--idx[2]];
      // update the maximum section sum
      max = ::std::max(sum[1],sum[0]); // right cannot be greater
    } else break;
  }
  // Finally, once we're done, we return the first index to
  //    B and to C, so the caller knows how our partitioning looks like.
  return ::std::make_pair(idx[1],idx[2]);
}

It returns the index to the start of the B range and the index to the start of the C range.

这篇关于在C范围内的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆