getting the minimum for arrays and for statments? - c++

I sorta need help getting the minimum I keep getting thirteen can some
one help me out? The issue I believe is I'm not showing the formula for low n line I'm confused I have tried to switch out the values for the array and I can't figure it out just if someone could explain to m please.
#include <iostream>
using namespace std;
int getHighest(int numArray[], int numElements);
int getLowest(int numArray[], int numelements);
int main()
{
int numbers[4] = { 13, 2, 40, 25 };
cout << "The highest number in the array is " << getHighest(numbers, 4) << "." << endl;
cout << "The lowest number in the array is "<< getLowest(numbers,0) << "." << endl;
return 0;
}
int getHighest(int numArray[], int numElements)
{
int high = numArray[0];
for (int sub = 1; sub < numElements; sub += 1)
if (numArray[sub] > high)
high = numArray[sub];
return high;
}
int getLowest(int numArray[], int numElements)
{
int low = numArray[0];
for (int sub = 0; sub >= numElements; sub--)
if (numArray[sub]< low)
low = numArray[sub];
return low;
}

Concerning getLowest():
There is actually no need to iterate backwards. It could be done like in getHighest(). However, say this is a requirement for teaching…
The test array is
int numbers[4] = { 13, 2, 40, 25 };
// indices: 0 1 2 3
// number of elements: 4
A loop to iterate backwards has to start with index numElements - 1 (3 in this case) and to stop at index 0.
for (int sub = numElements - 1; sub >= 0; sub--)
Nevertheless, this will check the last element which is already assigned before the loop. (getHighest() starts the loop with the 2nd element for this reason: for (int sub = 1;…) Thus, this can be corrected to:
for (int sub = numElements - 2; sub >= 0; sub--)

This is the corrected example:
int getLowest(int numArray[], int numElements)
{
int low = numArray[0];
for (int sub = 1; sub < numElements; ++sub)
{
//std::cout<<"checking: "<<numArray[sub]<<"with"<<low<<std::endl;
if (numArray[sub]< low){
low = numArray[sub];
}
}
return low;
}
The complete working example is here
Also note in your given example you have made a mistake at:
cout << "The lowest number in the array is "<< getLowest(numbers,0) << "." << endl;
Instead of passing 0 as the second argument you should pass 4 as i did here.
Another mistake was the initial value of varaible sub in the for loop. You started with sub = 0 instead of sub = numelements - 1.
That is the for loop should have looked like:
//note in the next line we have sub >=1 instead of sub>=0 becuase you have already stored numArray[0] in variable low
for (int sub = numElements -1; sub >=1; --sub)
{
...other code here
}

Related

How to find all possible combinations of adding two variables, each attached to a multiplier, summing up to a given number (cin)?

In my situation, a lorry has a capacity of 30, while a van has a capacity of 10. I need to find the number of vans/lorries needed to transport a given amount of cargo, say 100. I need to find all possible combinations of lorries + vans that will add up to 100.
The basic math calculation would be: (30*lorrycount) + (10*vancount) = n, where n is number of cargo.
Output Example
Cargo to be transported: 100
Number of Lorry: 0 3 2 1
Number of Van: 10 1 4 7
For example, the 2nd combination is 3 lorries, 1 van. Considering that lorries have capacity = 30 and van capacity = 10, (30*3)+(10*1) = 100 = n.
For now, we only have this code, which finds literally all combinations of numbers that add up to given number n, without considering the formula given above.
#include <iostream>
#include <vector>
using namespace std;
void findCombinationsUtil(int arr[], int index,
int num, int reducedNum)
{
int lorry_capacity = 30;
int van_capacity = 10;
// Base condition
if (reducedNum < 0)
return;
// If combination is found, print it
if (reducedNum == 0)
{
for (int i = 0; i < index; i++)
cout << arr[i] << " ";
cout << endl;
return;
}
// Find the previous number stored in arr[]
// It helps in maintaining increasing order
int prev = (index == 0) ? 1 : arr[index - 1];
// note loop starts from previous number
// i.e. at array location index - 1
for (int k = prev; k <= num; k++)
{
// next element of array is k
arr[index] = k;
// call recursively with reduced number
findCombinationsUtil(arr, index + 1, num,
reducedNum - k);
}
}
void findCombinations(int n)
{
// array to store the combinations
// It can contain max n elements
std::vector<int> arr(n); // allocate n elements
//find all combinations
findCombinationsUtil(&*arr.begin(), 0, n, n);
}
int main()
{
int n;
cout << "Enter the amount of cargo you want to transport: ";
cin >> n;
cout << endl;
//const int n = 10;
findCombinations(n);
return 0;
}
Do let me know if you have any solution to this, thank you.
An iterative way of finding all possible combinations
#include <iostream>
#include <vector>
int main()
{
int cw = 100;
int lw = 30, vw = 10;
int maxl = cw/lw; // maximum no. of lorries that can be there
std::vector<std::pair<int,int>> solutions;
// for the inclusive range of 0 to maxl, find the corresponding no. of vans for each variant of no of lorries
for(int l = 0; l<= maxl; ++l){
bool is_integer = (cw - l*lw)%vw == 0; // only if this is true, then there is an integer which satisfies for given l
if(is_integer){
int v = (cw-l*lw)/vw; // no of vans
solutions.push_back(std::make_pair(l,v));
}
}
for( auto& solution : solutions){
std::cout<<solution.first<<" lorries and "<< solution.second<<" vans" <<std::endl;
}
return 0;
}
We will create a recursive function that walks a global capacities array left to right and tries to load cargo into the various vehicle types. We keep track of how much we still have to load and pass that on to any recursive call. If we reach the end of the array, we produce a solution only if the remaining cargo is zero.
std::vector<int> capacities = { 30, 10 };
using Solution = std::vector<int>;
using Solutions = std::vector<Solution>;
void tryLoad(int remaining_cargo, int vehicle_index, Solution so_far, std::back_insert_iterator<Solutions>& solutions) {
if (vehicle_index == capacities.size()) {
if (remaining_cargo == 0) // we have a solution
*solutions++ = so_far;
return;
}
int capacity = capacities[vehicle_index];
for (int vehicles = 0; vehicles <= remaining_cargo / capacity; vehicles++) {
Solution new_solution = so_far;
new_solution.push_back(vehicles);
tryLoad(remaining_cargo - vehicles * capacity, vehicle_index + 1, new_solution, solutions);
}
}
Calling this as follows should produce the desired output in all_solutions:
Solutions all_solutions;
auto inserter = std::back_inserter(all_solutions)
tryLoad(100, 0, Solution{}, inserter);

Trying to copy elements from one array to another using only pointers

My professor wants me to only use pointers, no subscripts are permitted in any function
I'm suppose to let the user input two size and elements into two separate arrays and then make a union function which finds all elements that are the same (no duplicate values in either array)
All I want to do is move my array elements from the first array to the union array but I just get random numbers when I execute the program
void get_union(short *set1,short size1,short *set2,short size2,short *union_array,short size_union) // look at call statement to assist incompleting this statement
{
short *end1=(set1+size1), //*end2=(set1+size1+size2);
for( ;set1<end1;set1++)
{
union_array=set1;
cout<<"Union array value number "<<count++<<" "<<*union_array++<<endl;
}
}
and also I tried memcpy but I have never used it before especially not with pointers
memcpy(union_array,set1,sizeof(union_array));
Here's my first two functions that lets the user input data, and then displays it.
void inputData(short *data, short size) // function to enter data into the array
{
short count=1;
short *end=(data+size);
for( ;data<end;data++)
{
cout<<"Enter Number "<<count++<<" : ";
cin>>*data;
cout<<endl;
}
}
and
void displayData(short *data, short size) // function to display data in an array
{
short count;
short *end=(data+size);
for( ;data<end;data++)
{
cout<<"Number "<<count++<<" : "<<*data<<endl;
}
}
This is what I get when I run the program. The whole thing runs through but the union array gets random numbers
enter the number of values to store in the data set 1
or zero to terminate the program
3
Enter Number 1 : 2
Enter Number 2 : 4
Enter Number 3 : 6
there are 3 values in the array set1
Number 0 : 2
Number 1 : 4
Number 2 : 6
enter the number of values to store in the data set 2
3
Enter Number 1 : 10
Enter Number 2 : 11
Enter Number 3 : 12
there are 3 values in the array set2
Number 0 : 10
Number 1 : 11
Number 2 : 12
Union array value number 1 -5245
the union array contains 0 values
the intersection array contains -1 values
I'm not sure about your question, but let me try to help you:
All I want to do is move my array elements from the first array to the union array but I just get random numbers when I execute the program
using namespace std;
void get_union(short *set1,short size1,short *union_array,short size_union) {
for (; size1; --size1) {
*union_array++ = *set1++;
}
}
int main () {
short set1[] = {1, 0, 15, 35, 200, 12};
size_t size = sizeof(set1) / sizeof(*set1);
short union_arr[size];
get_union(set1, size, union_arr, size);
for (size_t i = 0; i < size; i++) {
cout << union_arr[i] << " ";
}
cout << endl;
return 0;
}
make a union function which finds all elements that are the same (no duplicate values in either array)
size_t get_union(short *set1, unsigned size1, short *set2, unsigned size2, short *union_array, unsigned size_union) {
size_t count = 0;
// TODO:: Make sure that the arrays are already sort
// todo:: or use the following two commands:
qsort(set1, size1, sizeof(*set1), [](const void * a, const void * b) -> int{
return ( *(short*)a - *(short*)b );
});
qsort(set2, size2, sizeof(*set2), [](const void * a, const void * b) -> int{
return ( *(short*)a - *(short*)b );
});
while (size1 && size2) {
if (*set1 > *set2) {
++set2;
--size2;
} else if (*set1 < *set2) {
++set1;
--size1;
} else {
*union_array++ = *set1++;
--size1;
++set2;
--size2;
++count;
}
}
return count;
}
int main () {
short set1[] = {1, 0, 15, 35, 200, 12};
short set2[] = {50, 0, 15, 0, 200, 12};
size_t size = sizeof(set1) / sizeof(*set1);
short union_arr[size];
size_t count;
count = get_union(set1, size, set2, size, union_arr, size);
cout << count << endl;
for (size_t i = 0; i < count; i++) {
cout << union_arr[i] << " ";
}
cout << endl;
return 0;
}
Btw, it is C question more then C++ one.. In C++ you can simply use vectors, and make the code as simple as you can (and the union array will be axactly with the minimum size). Pointers in C++ are more relevant in different situations, when you dealing with speed situations and APIs..
What he wants from us it to write a function that compares two arrays (set1 and set2 that I had) and puts all numbers that occur in either. so if there are 0 elements in the first array and 5 in the other, then the union array should have 5 elements
size_t get_unique_union(short *arr, size_t size, short *target) {
size_t target_bigger = 0;
short *curr, *curr_test;
//size_t dup = 0; (1)
if (!size) {
return target_bigger;
}
curr = arr + 1; // Current place in the array.
curr_test = curr; // Current place with the offset of the duplicate elements.
while (curr_test < arr + size) {
while (curr_test < arr + size && *arr == *curr_test) {
curr_test++;
//dup++; // | (1) Update global size. see comment.
}
*curr++ = *curr_test++;
}
size -= curr_test - curr; // Update global size | (1) size -= dup;
if (curr == curr_test) { // If it is a unique appearance (If there were no founded duplicates).
*target = *arr; // Set target in the current place the appearance.
target_bigger = 1; // Mention that in the next recursive calling,
// it will be called from the next place in the unique array.
}
for (size_t i = 0; i < size; i++) { // Display the current checked array (Without the doubles of the current appearance).
cout << arr[i] << " ";
}
cout << endl;
return target_bigger + get_unique_union(arr + 1, size - 1, target + target_bigger); // Recursive call with the next element in the array.
}
size_t get_union(short *set1, unsigned size1, short *set2, unsigned size2, short *uniq_arr) {
size_t global_size = size1 + size2;
size_t uniq_size = 0;
short union_array[global_size];
for (size_t i = 0; i < size1; i++) {
union_array[i] = set1[i];
}
for (size_t i = 0; i < size2; i++) {
union_array[i + size1] = set2[i];
}
for (size_t i = 0; i < global_size; i++) {
cout << union_array[i] << " ";
}
cout << endl;
return get_unique_union(union_array, global_size, uniq_arr);
}
int main () {
short set1[] = {12, 0, 2, 1, 12, 12, 6, 8};
short set2[] = {3, 0, 300, 12, 12, 12};
size_t size1 = sizeof(set1) / sizeof(*set1);
size_t size2 = sizeof(set2) / sizeof(*set2);
short union_arr[size1 + size2];
size_t count;
count = get_union(set1, size1, set2, size2, union_arr);
cout << "Results:" << endl;
cout << "Count: " << count << endl;
cout << "Arr: [";
for (size_t i = 0; i < count; i++) {
cout << union_arr[i] << ((i < count - 1) ? ", " : "");
}
cout << "]" << endl;
return 0;
}
This code even take care of cases that there are duplicates in the same array. It combines the arrays to the same big array, remove duplicates, and insert only the elements that have no duplicates at all.
Pay attention that the function "get_unique_union" is recursive, and returns the count of the unique elements, and not the unique union array's real size.
The code format is C one, and not C++ (it works on C++, has been written in cpp file and compiled with g++ compiler. But in C++ it would be write with vectors, and it would save more useless place in the unique union array).

How to find local maximums in data set using C++?

I am using an arduino to read a sensor which stores 256 values into an array. I am trying to find local max's but some values being stored have repeating values to the left and right of itself causing the value to print multiple times. Is there a way to take all true values meaning they are a max value and store them in another array to process and reduce the repeated values to just 1 value...
OR is there a way to send the max values to another array where the repeated values get reduced to just 1? OR
IE:
Array1[] = {1,2,3,4,4,4,3,2,7,8,9,10}
max = 4 at index 3
max = 4 at index 4
max = 4 at index 5
since 4 is a peak point but repeats how can I reduce it so that the array looks like
Array2[] = {1,2,3,4,3,2,7,8,9,10}
max = 4 at index 3
I need the most basic breakdown if possible nothing on an expert level, thanks.
Code from Arduino:
int inp[20] = {24,100,13,155,154,157,156,140,14,175,158,102,169,160,190,100,200,164,143,20};
void setup()
{
Serial.begin(9600); // for debugging
}
void loop()
{
int i;
int count = 0;
for (i = 0; i < 20; i++)
{
Serial.println((String)inp[i]+" index at - "+i);
delay(100);
};
int N = 5; // loc max neighborhood size
for (int i = N-1; i < 19-N; i++)
{
bool loc = false;
for (int j = 1; j < N; j++) // look N-1 back and N-1 ahead
{
if (inp[i] > inp[i-j] && inp[i] > inp[i+j]) loc = true;
}
if (loc == true)
{
Serial.println((String)"max = "inp[i]+" at index "+i);
}
}
Serial.println("----------------------------------");
}
You can detect "local maxima" or peaks in a single loop without the need of copying something into another array. You just have to ignore repeating values, and you just have to keep track if the values considered are currently increasing or decreasing. Each value after which this status switches from increasing to decreasing is then a peak:
int main() {
int Array1[] = {1,2,3,4,4,4,3,2,7,8,9,10};
int prevVal = INT_MIN;
enum {
Ascending,
Descending
} direction = Ascending;
for (int i=0; i<sizeof(Array1)/sizeof(*Array1); i++) {
int curVal = Array1[i];
if (prevVal < curVal) { // (still) ascending?
direction = Ascending;
}
else if (prevVal > curVal) { // (still) descending?
if (direction != Descending) { // starts descending?
cout << "peak at index " << i-1 << ": " << prevVal << endl;
direction = Descending;
}
}
// prevVal == curVal is simply ignored...
prevVal = curVal;
}
}

Sum of factoriais to be equal a given number

I'm trying to solve the following problem:
What is the smallest number of factoriais summed that are needed to be equal an given number a? (1 ≤ a ≤ 10^5)
Example:
Input: 10, Output: 3. (10 = 3! + 2! + 2!)
Input: 25, Output: 2. (25 = 4! + 1!)
My code:
#include<bits/stdc++.h>
using namespace std;
int a;
int rec(int vet){
int count = 0;
a = a - vet;
if(a >= vet){
count++;
rec(vet);
}
count++;
return count;
}
int main(){
int vet[8] = {1}, count = 0;
cin >> a;
for(int i = 2; i <= 8; i++){
vet[i-1] = vet[i-2]*i;
}
for(int i = 7; i >= 0; i--){
if(a < vet[i]){
continue;
}
count += rec(vet[i]);
}
cout << count << endl;
}
My logic:
1°: a max is equal to 100000, so the maximum fatorial we have to
compare is 8!;
2°: I take a factioral that is equal or nearest small to a,
subtract the factorial from it and count++; If after the subtraction,
a still bigger then my factorial, I do the same step recursively.
This code pass on the base cases, but I got a wrong answer. I wasn't capable to find what case it didn't pass, so I'm here.
Can you find where am I wrong? Or if my solution is not good and I should try another approach.
Thanks for the help!
The problem is easily solved by a recursive approach.
Here is checked code:
#include <iostream>
using namespace std;
int factorial(int n) {
return n<=1 ? 1 : n * factorial(n-1);
}
int MinFact(int number)
{
static int num_of_facts;
int a = 1;
if (number)
{
while(factorial(a+1)<=number)a++;
cout << a << "!" << endl;
num_of_facts++;
MinFact((number-factorial(a)));
}
return num_of_facts;
}
int main()
{
int num;
cout << "Enter number" << endl;
cin >> num;
num = MinFact(num);
cout << "Number of factorials: " << num;
return 0;
}
As I mentioned in the comment, the issue is with the rec function. Due to rec being local, the count is not being incremented correctly.
A simple solution would be to replace the rec function as follows
int rec(int vec) {
int count = a / vec;
a = a % vec;
return count;
}
Edit : for a failing case try 18. The solution will be 3 but you will get 2.
I guess you can figure out how this logic works. If not you could do it with a loop.

finding minimum number of jumps

Working on below algorithm puzzle of finding minimum number of jumps. Posted detailed problem statement and two code versions to resolve this issue. I have did testing and it seems both version works, and my 2nd version is an optimized version of version one code, which makes i starts from i=maxIndex, other than continuous increase, which could save time by not iteration all the slots of the array.
My question is, wondering if my 2nd version code is 100% correct? If anyone found any logical issues, appreciate for pointing out.
Problem Statement
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
For example:
Given array A = [2,3,1,1,4]
The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)
First version code
class Solution {
public:
int jump(vector<int>& nums) {
int i = 0, n = nums.size(), step = 0, end = 0, maxend = 0;
while (end < n - 1) {
step++;
for (;i <= end; i++) {
maxend = max(maxend, i + nums[i]);
if (maxend >= n - 1) return step;
}
if(end == maxend) break;
end = maxend;
}
return n == 1 ? 0 : -1;
}
};
2nd version code
class Solution {
public:
int jump(vector<int>& nums) {
int i = 0, n = nums.size(), step = 0, end = 0, maxend = 0;
int maxIndex = 0;
while (end < n - 1) {
step++;
for (i=maxIndex;i <= end; i++) {
if ((i + nums[i]) > maxend)
{
maxend = i + nums[i];
maxIndex = i;
}
if (maxend >= n - 1) return step;
}
if(end == maxend) break;
end = maxend;
}
return n == 1 ? 0 : -1;
}
};
thanks in advance,
Lin
The best way is always to test it. A human cannot always think about special cases but a automated test can cover the most of speciale cases. If you think that your first version works well, you can compare the result of the first with the second one. Here an exemple:
/*
* arraySize : array size to use for the test
* min : min jump in the array
* max : max jump in the array
*/
void testJumps(int arraySize, int min, int max){
static int counter = 0;
std::cout << "-----------Test " << counter << "------------" << std::endl;
std::cout << "Array size : " << arraySize << " Minimum Jump : " << min << " Max Jump" << max << std::endl;
//Create vector with random numbers
std::vector<int> vecNumbers(arraySize, 0);
for(unsigned int i = 0; i < vecNumbers.size(); i++)
vecNumbers[i] = rand() % max + min;
//Value of first function
int iVersion1 = jump1(vecNumbers);
//Second fucntion
int iVersion2 = jump2(vecNumbers);
assert(iVersion1 == iVersion2);
std::cout << "Test " << counter << " succeeded" << std::endl;
std::cout << "-----------------------" << std::endl;
counter++;
}
int main()
{
//Two test
testJumps(10, 1, 100);
testJumps(20, 10, 200);
//You can even make a loop of test
//...
}