Getting parameter values in the scope of another function - c++

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

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
}

Display Problem in C++ If Even Numbers is Inputted

i have a very simple problem when displaying the single "A". It should start on the RIGHT SIDE and not on the left. It is correct when i input odd numbers but if i input even numbers it outputs wrong.
I have to follow this guidelines by the way,
Guidelines:
Pointers and references must be used to display the values.
displayRoad runs recursively.
Loop statements are not allowed
Object instance must be destroyed after use.
Pls see the pictures below:
WRONG RESULT (EVEN NUMBERS)
CORRECT RESULT (ODD NUMBERS)
CODE
#include <iostream>
#include <string>
using namespace std;
class myRoad
{
private:
char myChar;
int myH, myW;
public:
myRoad(){
askChar();
askHeight();
askWidth();
}
void askChar();
void askHeight();
void askWidth();
void recurs_W(char c, int w, int h);
void recurs_H(char c, int h, int w);
char getChar(){return myChar;}
int getHeight(){return myH;}
int getWidth(){return myW;}
};
void displayRoad(myRoad* mRoad);
int main()
{
myRoad* mRoad = new myRoad();
cout << endl << endl;
displayRoad(mRoad);
delete mRoad;
}
void displayRoad(myRoad* mRoad)
{
mRoad->recurs_H(mRoad->getChar(),mRoad->getHeight() * 2 + 1, mRoad->getWidth());
}
void myRoad::askChar()
{
char ch;
cout << "Enter a character: ";
cin >> ch;
myChar = ch;
}
void myRoad::askHeight()
{
int h = 0;
cout << "Enter height: ";
cin >> h;
myH = h;
}
void myRoad::askWidth()
{
int w = 0;
cout << "Enter width: ";
cin >> w;
myW = w;
}
void myRoad::recurs_H(char c, int h, int w)
{
if(h == 0)
return;
recurs_W(c, w, h);
recurs_H(c, --h,w);
}
void myRoad::recurs_W(char c, int w, int h)
{
if(w == 0)
{
cout << endl;
return;
}
else
{
if(h % 2 == 1)
cout << myChar;
else
{
if (w == myW && h % 4 == 0)
{
cout << myChar;
}
else if (w == 1 && h % 2 == 0 && h % 4 != 0)
{
cout << myChar;
}
else
cout << ' ';
}
}
return recurs_W(c, --w, h);
}
You choose whether to put the character on the right or left, depending on whether h is odd or even.
So, it is not surprising that making h start as an odd number (rather than an even one) should reverse that choice for the first step.
I propose you introduce a new variable i, that instead of going 10→0 (or 5→0), goes 0→10 (or 0→5).
(I'm ignoring one-based indexing and exclusive ranges in the above numerical examples, but you get the point)
Then make your left-or-right decision based on i instead of h, as it'll always start as even (0).
This variable would begin at zero and be incremented every time h is decremented, so it's the exact mirror.
You don't actually need to store i anywhere; you can just calculate it when needed:
int myRoad::currentRowNumber(int h)
{
return getHeight() - h;
}
Then instead of, say, h % 2, you do currentRowNumber(h) % 2.
There are simpler ways to achieve the wider goal, but this is a quick fix that demonstrates the cause of the problem.
Best thing you can do is converting your algorithm into an iterative one:
for(int i = 0; i < myH; ++i)
{
for(int j = 0; j < myW; ++j)
std::cout << 'A';
std::cout << '\n';
if((i & 1) == 0)
{
for(int j = 1; j < myW; ++j)
std::cout << ' ';
}
std::cout << "A\n";
}
if(myH != 0) // drop, if you want to have a single line for height = 0
{
// final line:
for(int i = 0; i < myW; ++i)
std::cout << 'A';
std::cout << std::endl; // in contrast to simple '\n', std::endl flushes the output
// stream as well, assuring user sees output immediately
}
If you insist on a recursive variant (be aware that you might suffer from stack overflow pretty quickly for larger widths and heights!): The problem is that you decide by remaining height, not current height, if you want to draw the A on left or right. That reverses your structure in vertical direction. As for odd numbers the structure is axially symmetric, you won't notice, though, but with even numbers, you get bitten.
You could fix that, for instance by providing an additional parameter indicating current height, which iterates from 0 to maximum height:
void myRoad::recurs_H(char c, int h, int w)
{
if(h < myH)
{
recurs_W(c, w, h);
recurs_H(c, ++h, w);
// ^^ (!)
}
}
with initial call as:
recurs_H('A', 0, myW);
// ^ (!)
I personally recommend re-organising the functions, though:
void myRoad::recurs_W(char c, int w)
{
if(w < myW)
{
std::cout << c;
recurse_W(c, w + 1);
}
}
void myRoad::recurs_H(char c, int h)
{
if(h < myH)
{
recurse_W(c, 0);
std::cout << '\n';
if((h & 1) == 0)
recurs_W(' ', 1);
std::cout << c << '\n';
recurs_H(c, h + 1);
}
}
void displayRoad(myRoad* mRoad)
{
if(mRoad->getWidth() && mRoad->getHeight())
{
mRoad->recurs_H(mRoad->getChar(), 0);
// draw the final line
mRoad->recurs_W(mRoad->getChar(), 0);
std::cout << std::endl;
}
}
See how much this resembles the iterative variant? See how far less complicated the recurse_W function got? Additionally, as you don't need the value of the member variable any more after the recursive call (the recursive call is the very last thing you do!), you can profit from tail call optimisation, which will prevent your stack from growing...
Negative width or height is pretty meaningless, isn't it? So you might consider changing the type to unsigned (and the recursive function parameters as well). Careful, though, when downcounting – people tend to overlook that unsigned numbers cannot get negative:
for(unsigned int n = 7; n >= 0; --n)
results in endless loop. But that's actually easily covered:
for(unsigned n = 8; n-- > 0; )
or, if you consider that unsigned overflows:
for(unsigned n = 7; n <= 7; --n)

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

C++ : How do I only look at one dimension of a 2-Dimensional array?

I'm writing a battleship game in the console, and I'm writing a function that will draw one grid based on a 2-dimensional array. The approach I'm taking is such:
--> Draw 1 row which contains a character X amount of times (like 10)
--> Draw that row, putting a newline at the end of the drawing process, 10 times to get a nice field.
Now, I do need to insert a newline at the end of 1 row, right? But how do I compare only the x-element of the array, and not the y-element?
Here's my code:
// Includes
#include <iostream> // For IO
#include <cstdlib> // For rand()
// Important game stuff
const int empty = 0; // Water
const int occupied = 1; // Ship
const int hit = 2; // Hit a ship
const int missed = 3; // Missed
// Variables
const int fields = 10;
// We want a 10x10 field
int board[fields][fields]; // board[x][y]
// Initialize board
void initb(int array[fields][fields]);
// Draw board x-axis
void drawbx(int array[fields][fields]);
int main(void)
{
drawbx(board;)
// game(Players);
return 0;
}
// Initialize the board, make everything hit
void initb(int array[fields][fields])
{
for(int x = 1; x <= 10; x++)
{
for(int y = 1; y <= 10; y++)
{
array[x][y] = hit;
}
}
}
void drawbx(int array[fields][fields])
{
for(int i = 1; i <= fields; i++)
{
if(array[i][] == empty || array[i][] == occupied)
{
if(i == 10)
std::cout << " X\n";
else if(i == 1)
std::cout << "X ";
else
std::cout << " X ";
}
}
}
Take a look specifically at the drawbx() function. I want to draw something like
X X X X X X X X X X\n
The syntax that I tried, if(array[i][] == empty || array[i][] == occupied), doesn't work. There must be an expression in the second pair of square brackets. Can someone help me?
I see two major problems:
1) Array indexing is out of range. You use index 1 to 10. It shall be 0 to 9.
2) Code array[i][] == empty is illegal syntax. You can't leave one index empty.
If you want a function that draw one row, perhaps pass the row number to the function like:
void draw_one_row(int array[fields][fields], int row_to_draw)
{
for(int i = 0; i < fields; i++)
{
if(array[row_to_draw][i] == empty || array[row_to_draw][i] == occupied)
{
...
}
}
}
To draw the whole board:
void draw_board(int array[fields][fields])
{
for(int i = 0; i < fields; i++)
{
draw_one_row(array, i);
}
}
BTW: Since you write C++, I'll recommend that you use vector instead of arrays.

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;
}
}