No, C does not have such functionality built in. Moreover, there is no functionality to get the upper boundary of an array once you pass it to a function (so called "decaying to pointers").
There are two standard solutions to this problem:
- Pass a pointer to the first array element and the count of elements, or
- Pass a pointer to the whole array, an index to the initial element, and an index to the last element
The first approach would look like this:
int sum_array(int* array, size_t len) {
int res = 0;
for (size_t i = 0 ; i != len ; i++) {
res += array[i];
}
return res;
}
...
int ProfitA = sum_array(array, A);
int ProfitB = sum_array(array+A, B);
int ProfitC = sum_array(array+A+B, N-A-B);
the second approach would look like this:
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 ProfitA = sum_array(array, 0, A-1);
int ProfitB = sum_array(array, A, A+B-1);
int ProfitC = sum_array(array, A+B, N-1);
Answer from Sergey Kalinichenko on Stack Overflowjava - Fill arrays with ranges of numbers - Stack Overflow
How to create an array and fill it with a specific range of numbers?
arrays - Range values in C - Stack Overflow
java - Pulling a range from an array - Stack Overflow
No, C does not have such functionality built in. Moreover, there is no functionality to get the upper boundary of an array once you pass it to a function (so called "decaying to pointers").
There are two standard solutions to this problem:
- Pass a pointer to the first array element and the count of elements, or
- Pass a pointer to the whole array, an index to the initial element, and an index to the last element
The first approach would look like this:
int sum_array(int* array, size_t len) {
int res = 0;
for (size_t i = 0 ; i != len ; i++) {
res += array[i];
}
return res;
}
...
int ProfitA = sum_array(array, A);
int ProfitB = sum_array(array+A, B);
int ProfitC = sum_array(array+A+B, N-A-B);
the second approach would look like this:
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 ProfitA = sum_array(array, 0, A-1);
int ProfitB = sum_array(array, A, A+B-1);
int ProfitC = sum_array(array, A+B, N-1);
There isn't a way using the style of syntax you used to describe what you're after.
Two obvious ways would be to provide the array and indices range (as lared mentioned) or specify the range using two pointers
int ProfitB = Sum(array + A, array + A+B-1); /* sum array[A] ... array[A+B-1] */
Whichever approach you use, your calling code would need to ensure it provides a valid range.
For those still looking for a solution:
In Java 8 or later, this can be answered trivially using Streams without any loops or additional libraries.
int[] range = IntStream.rangeClosed(1, 10).toArray();
This will produce an array with the integers from 1 to 10.
A more general solution that produces the same result is below. This can be made to produce any sequence by modifying the unary operator.
int[] range = IntStream.iterate(1, n -> n + 1).limit(10).toArray();
Another useful and not widely known Java 8 solution for existing arrays:
int[] array = new int[10];
Arrays.setAll(array, i -> i + 1);
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.
This is your pseudocode in C (just for reference because you tagged your problem with C++ yet want a C only solution). Still, the greedy solution that bitmask provided above is a better O(N) solution; you should try to implement that algorithm instead.
#include <stdio.h>
#include <stdint.h>
#include <limits.h>
#define N 10
int sum_array(int* array, int cnt)
{
int res = 0;
int i;
for ( i = 0; i < cnt ; ++i)
res += array[i];
return res;
}
int main()
{
int array[N] = {1,1,8,1,1,3,4,9,5,2};
int Min = 0;
int bestA = 0, bestB = 0, bestMin = INT_MAX;
int A, B;
int i;
for ( A = 0; A < N - 2; ++A)
{
for ( B = A + 1; B < N - 1; ++B)
{
int ProfitA = sum_array(array, A + 1);
int ProfitB = sum_array(array + A + 1, B - A );
int ProfitC = sum_array(array + B + 1, N - 1 - B );
//here the values are "current" - valid
Min = (ProfitA > ProfitB) ? ProfitA : ProfitB;
Min = (ProfitC > Min) ? ProfitC : Min;
if( Min < bestMin )
bestA = A, bestB = B, bestMin = Min;
#if 0
printf( "%2d,%2d or (%3d,%3d,%3d) ", A, B, ProfitA, ProfitB, ProfitC );
for( i = 0; i < N; ++i )
printf( "%d%c", array[i], ( ( i == A ) || ( i == B ) ) ? '|' : ' ' );
printf( " ==> %d\n", Min);
#endif
}
}
printf("%d @ %d, %d\n", bestMin, bestA, bestB);
return 0;
}
The length of an array in Java is immutable. So, you need to copy the desired part into a new array.
Use copyOfRange method from java.util.Arrays class:
int[] newArray = Arrays.copyOfRange(oldArray, startIndex, endIndex);
startIndex is the initial index of the range to be copied, inclusive.
endIndex is the final index of the range to be copied, exclusive. (This index may lie outside the array)
E.g.:
//index 0 1 2 3 4
int[] arr = {10, 20, 30, 40, 50};
Arrays.copyOfRange(arr, 0, 2); // returns {10, 20}
Arrays.copyOfRange(arr, 1, 4); // returns {20, 30, 40}
Arrays.copyOfRange(arr, 2, arr.length); // returns {30, 40, 50} (length = 5)
You could wrap your array as a list, and request a sublist of it.
MyClass[] array = ...;
List<MyClass> subArray = Arrays.asList(array).subList(index, array.length);
I have a method that is asking me to return all the values within a range and put them into a new array. So...{4, 5, 6, 7, 8} with a range of 5 to 7 would become a new array of {5, 6, 7}. Hopefully that makes sense. I looked into the copyOfRange method but that uses the indexes and I need to use the given numbers from the range. I don't have the actual range numbers so I have to write a method that can account for any given range. Thanks in advance.