Trying to copy elements from one array to another using only pointers - c++

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).

Related

getting the minimum for arrays and for statments?

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
}

what does int numbers[n+2]; statement do?

#include<iostream>
int fastFibonacci(int n)
{
int numbers[n+2]; // int numbers[n].
numbers[0] = 0;
numbers[1] = 1;
for (int i = 2; i <= n; i++)
{
numbers[i] = numbers[i - 1] + numbers[i - 2];
}
return numbers[n];
}
int main() {
int n;
std::cout << "Enter a Number";
std::cin >> n;
int result = fastFibonacci(n);
std::cout << result << "\n";
return 0;
}
in this code when i enter input 0 or 1 get correct answer. But the problem is that when i replace int numbers[n+2]; with the commented part it start giving me wrong answer when input is 0 or 1. why? anyone please explain me.
In this function
int fastFibonacci(int n)
{
int numbers[n+2]; // int numbers[n].
numbers[0] = 0;
numbers[1] = 1;
for (int i = 2; i <= n; i++)
{
numbers[i] = numbers[i - 1] + numbers[i - 2];
}
return numbers[n];
}
there is used a variable length array with n + 2 elements declared in this line
int numbers[n+2]; // int numbers[n].
Variable length arrays is not a standard C++ feature. It can be implemented as own language extension of a C++ compiler.
Using the variable length array makes the function very unsafe because there can occur a stack overflow.
As within the function there is explicitly used two elements of the array
numbers[0] = 0;
numbers[1] = 1;
then the array shall have at least two elements even when the parameter has a value less than 2.
To calculate the n-th Fibonacci number there is no need to declare an array of such a size.
Apart from this the function argument shall have an unsigned integer type. Otherwise the function can invoke undefined behavior if the user passes a negative number.
Also for big values of n there can be an integer overflow for the type int.
The function can be implemented in various ways.
Here is one of possible its implementations.
#include <iostream>
#include <functional>
unsigned long long fibonacci( unsigned int n )
{
unsigned long long a[] = { 0, 1 };
while ( n-- )
{
a[1] += std::exchange( a[0], a[1] );
}
return a[0];
}
int main()
{
const unsigned int N = 10;
for ( unsigned int i = 0; i < N; i++ )
{
std::cout << i << ": " << fibonacci( i ) << '\n';
}
return 0;
}
The program output is
0: 0
1: 1
2: 1
3: 2
4: 3
5: 5
6: 8
7: 13
8: 21
9: 34
int numbers[n+2]; is the declaration of an array of ints with space for n + 2 ints, this is a variable lenght array and is not part of C++ standard, though some compilers allow it it's not somenthing you should use.
If you need a variable lenght array use std::vector.
With int numbers[n+2]; if n is equal to 0 you still have space for 2 ints, if you have int numbers[n]; the array will have space for 0 ints, so the code will fail because you are trying to access memory that does not exist with numbers[0] and numbers[1].
There are several good ways to implement the Fibonacci sequence, in the site you can find many questions regarding this matter in several programming languages, here is one of them Fibonacci series in C++
Edit
So I've seen your comments about using a vector, for making the sequence you wouldn't need the vector just two variables to store the two numbers to add, to store the sequence in a vactor, you can do somenthing like:
#include <iostream>
#include <vector>
#include <iomanip>
//passing the vector by reference
void fastFibonacci(unsigned long long n, std::vector<unsigned long long>& sequence) {
unsigned long long first = 0;
unsigned long long second = 1;
sequence.push_back(first); //add first values to the vector
sequence.push_back(second); //add first values to the vector
for (unsigned long long i = 0, value = 0; i < n && value <= LLONG_MAX ; ++i) {
value = first + second;
first = second;
second = value;
sequence.push_back(value); //adding values to the vector
}
}
int main() {
unsigned long long limit; //number of values in the sequence
int num = 1;
std::vector<unsigned long long> sequence; //container for the sequence
std::cout << "Enter upper limit: ";
std::cin >> limit;
fastFibonacci(limit, sequence);
//print the sequence in a range based loop formatted with <iomanip> library
for(auto& i : sequence){
std::cout << std::setw(4) << std::left << num++ << " " << i << std::endl;
}
return 0;
}
If you want to print just one of the numbers in the sequence, just use, for instance:
std::cout << sequence[10];
Instead of the whole vector.
The code you post in the comment to the other answer won't work because the access to the vector is out of bounds in numbers[i] = numbers[i - 1] + numbers[i - 2];, if for instance i = 5, your vector only has 2 nodes but you are accessing the 6th node numbers[5].

Wierd combination

I have an array of 3 integers {1,2,3}. I need to print combinations in the form of-
1 1+2 1+3 1+2+3
2 2+3
3
for(int i = 0; i < array.size(); ++i)
{
for(int j = 0; (i + j) < array.size(); ++j)
{
sum += my[i + j];
cout << sum << " ";
c++;
}
cout << endl;
}
In above, 1+3 is being skipped.
Please help me with that.
Given a set S the power set P(S) is the set of all subsets of S. What you are trying to do is essentially enumerate all of the non-empty elements of x ∈ P(S). From there, you can iterate over all of the elements of each non-empty x in P(S).
What does this mean for you? Well for starters for a set S containing n elements the number of possible elements of P(S) is 2^n, so the size of the power set scales exponentially with the size of its generating set.
But, where this may be useful for small values of n (in particular n < 64) you can use unsigned long long variables to act as a kind of index. In particular, each bit corresponds to one of your array elements. Bits with a value of 0 exclude its associated element in the sum, while bits with a 1 would include the element. To do something like this try the following:
#include <vector>
#include <iostream>
void print_sum(const std::vector<int>& array, unsigned long long i) {
int sum = 0;
for (int index=0; i > 0; i=i>>1, ++index) {
if (i % 2 == 1) {
std::cout << array[index] << (i>1 ? "+" : "=");
sum += array[index];
}
}
std::cout << sum << std::endl;
}
void printer(const std::vector<int>& array) {
if (array.size() < sizeof(unsigned long long) * 8) {
unsigned long long n = 1 << array.size();
for (unsigned long long i = 1; i < n; ++i) {
print_sum(array, i);
}
}
}
int main(int argc, char** argv) {
std::vector<int> sample {1, 2, 3, 4};
printer(sample);
return 0;
}
This program has output:
1=1
2=2
1+2=3
3=3
1+3=4
2+3=5
1+2+3=6
4=4
1+4=5
2+4=6
1+2+4=7
3+4=7
1+3+4=8
2+3+4=9
1+2+3+4=10

Reverse Array with given sentinel value

FYI: I am new to programming.
I have an arraysize of 10 and the sentinel value is 0.
My original array is [1 2 3] ( user input) but my reverse is [0 0 0 0 0 0 0 3 2 1].
I need help to make my reverse array [3 2 1].
Here is my code:
int temp;
for (int i = 0; i < arraysize/2; i++)
{
temp = array[arraysize-1-i];
array[arraysize - i - 1] = array[i];
array[i] = temp;
}
cout << "The reverse array: ";
for (int i = 0; i < arraysize; i++)
cout << array[i]<< ' ';
cout << endl;
Just use the standard library algorithms
auto end = std::find(std::begin(array),std::end(array),0);
std::reverse(std::begin(array),end);
//And if you only want to print the non-zero values:
size_t effectiveArraySize = end - std::begin(array);
If the fixed size array is not part of your requirement, you should put your user data in a vector that automaticaly grows as large as you need, instead of using an array that might turn out to be too small:
std::vector<int> v;
while(true) {
int t;
cin >> t;
if (t == 0) {
break;
}
v.push_back(t);
}
std::reverse(v.begin(),v.end());
That way, you don't have any sentinel values in your array / vector to begin with.
Note: Using the respective functions from the STL (std::reverse and std::find) is better, I was just guessing that you are bound to implement this on your own.
Step one: Write a proper reverse function. One that takes (a pointer to) the beginning as well as (a pointer to) the end of the range that should be reversed.
Step two: Write a function to find (the first position of) your sentinel in an array (given via beginning and end, again)
Step three: Connect the two: Reverse from the beginning to the position of your sentinel.
Example without templates:
void reverse(int * from, int * to) {
while ((to - from) > 1) {
--to;
int temp = *from;
*from = *to;
*to = temp;
++from;
}
}
int const * find(int const * from,
int const * const to,
int const value) {
while ((from != to) && (*from != value)) {
++from;
}
return from;
}
void reverse_until (int * const from,
int * const to,
int const sentinel) {
int const * const position_sentinel = find(from, to, sentinel);
reverse(from, from + (position_sentinel - from));
// return the sentinel position from this function
// if you want only the reversed part
}
Tested with:
int main() {
int test[10];
for (size_t i = 0; i < 10; ++i) {
test [i] = i + 1;
}
reverse_until (test, test + 10, 6);
copy(test, test + 10, ostream_iterator<int>{cout, " "});
return 0;
}
(live here)
You need to find the actual length of the array, before performing the reverse operation, and then use that length for all further operations.
Like this:
int actualArraySize = 0;
while(actualArraySize < arraysize && array[actualArraySize]!=0)
{
actualArraySize++;
}
int temp;
for (int i = 0; i < actualArraySize/2; i++)
{
temp = array[actualArraySize-1-i];
array[actualArraySize - i - 1] = array[i];
array[i] = temp;
}
cout << "The reverse array: ";
for (int i = 0; i < actualArraySize; i++)
cout << array[i]<< ' ';
cout << endl;
Note that, actualArraySize can be less than or equal to arraysize, but, not more than it, because of the condition in while(actualArraySize < arraysize && array[actualArraySize]!=0), which means that stop when either a 0 is found or the size of the array is reached.

Getting parameter values in the scope of another function

I can't figure out how to get the variables of read input into the scope of calculate seats. Despite how I declare the variables short of re-defining them; rows, columns, and the array seatingChart cannot seem to be found by the function calculateSeats.
* Added calculateSeats(seatingChart[rows][columns]); *
int main() {
int seatsSold = 0, oneSeat = 0, seatsTogether = 0, threeSeats = 0, fourSeats = 0, fiveSeats = 0, noSeats = 0, totalSold = 0,
rows, columns, pecentageSold, i;
const int SIZE = 50;
char seatingChart[SIZE][SIZE];
readInput(rows, columns, seatingChart[rows][columns]); // Call read input.
// Values of read input are then passed to calculate values.
calculateSeats(seatsSold, oneSeat, seatsTogether, threeSeats, fourSeats, fiveSeats, noSeats, i);
// Calculated valus are then declared as calculated values and passed to write output.
/* int calculatedValues = calculateSeats(seatsSold, oneSeat = 0, seatsTogether = 0, threeSeats = 0,
fourSeats = 0, fiveSeats = 0, noSeats = 0); */
// Function is called to write the output.
writeOutput(seatsSold, oneSeat, seatsTogether, threeSeats, fourSeats, fiveSeats, noSeats, pecentageSold, totalSold);
return 0; // Program ends.
}
// Function is needed for assigning values to the char array. Values are then passed from read to calculate.
int readInput(int & rows, int & columns, int i) {
const int SIZE = 50;
int seatingChart[SIZE][SIZE];
ifstream inputFile;
inputFile.open("SeatingChart.txt");
for (rows; rows < SIZE; rows++) { // Step through the valueless array and give the array values.
for (columns; columns < SIZE; columns++)
inputFile >> seatingChart[rows][columns]; // Assign the array values from the input file.
}
inputFile.close();
calculateSeats(seatingChart[rows][columns]);
return 0;
}
// Function is needed just for calculations. Values are then passed from calculate to write output.
void calculateSeats(int & seatsSold, int & oneSeat, int & seatsTogether, int & threeSeats,
int & fourSeats, int & fiveSeats, int & noSeats, int & sixSeats) {
for (int count = 0; count < rows; count++) { // Step back through the array with loaded values.
for (int num = 0; num < columns; num++) {
// If equal to A and count is equal to count++. Then consecutive read chars is true.
if (seatingChart[count][num] == 'A' && seatingChart[count][num] == seatingChart[count][num]++) {
seatsTogether++;
if (seatsTogether > 1) {
threeSeats++;
if (seatsTogether > 2) {
fourSeats++;
}
if (seatsTogether > 3) {
fiveSeats++;
}
if (seatsTogether > 4) {
sixSeats++;
}
}
}
else {
seatsSold++;
cout << "Total seats sold: " << seatsSold << endl;
if (seatsSold == 6) {
cout << "Rows with no seats available: " << "row" << seatingChart[count] << endl;
}
}
}
}
}
You are declaring rows, columns and seating chart in the scope of main.
This variables lay on the stack. If you want them to make visible in readInput you have to declare them as globals. So it should look like this.
int row, column;
char seatingChart[SIZE][SIZE];
int main()
{
//your code
}
Globals are considered as bad style.
http://en.wikipedia.org/wiki/Global_variable