Display Problem in C++ If Even Numbers is Inputted - c++

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)

Related

Generating an edge graph using four values a,b,c,d in c++

I'm having a trouble solving a question which asks me to generate an edge graph using 4 random numbers a,b,c,d , so the formula is as follows , to generate the nodges of the graph we'll use variable d , if we divide d with 3 and we get a remainder of 0 then 10 nodges are generated , if d/3 = 1 then 11 nodges if d/3 = 2 then 12 nodges are generated , as for the edges we have the following formula (i,j) ∈ U <-> ((ai+bj)/c) / d ≤ 1 , basically the edge will connect the nodge of i with the nodge of j if the formula after dividing by d gives a remainder smaller or equal to 1. Can someone tell me what's the problem with the code below ?
Here is the code :
#include <iostream>
#include <vector>
using namespace std;
struct Edge {
int src, dest;
};
class Graph
{
public:
vector<vector<int>> adjList;
Graph(vector<Edge> const& edges, int N)
{
adjList.resize(N);
for (auto& edge : edges)
{
adjList[edge.src].push_back(edge.dest);
}
}
};
void printGraph(Graph const& graph, int N)
{
for (int i = 0; i < N; i++)
{
cout << i << " ——> ";
for (int v : graph.adjList[i])
{
cout << v << " ";
}
cout << endl;
}
}
int main()
{
vector<Edge> edges;
int a, b, c, d,remainder,Nodges,result;
cout << "Enter 4 values : \n";
cin >> a >> b >> c >> d;
remainder = d % 3;
if (remainder == 0)
{
Nodges = 10;
}
else if (remainder == 1)
{
Nodges = 11;
}
else if (remainder == 2)
{
Nodges = 12;
}
for (int i = 0; i < Nodges; i++)
{
for (int j = 0; j < Nodges; j++)
{
result = ((a * i + b * j) / c) % d;
if (result <= 1)
{
edges =
{
{i,j}
};
}
}
}
Graph graph(edges, Nodges);
printGraph(graph, Nodges);
return 0;
}
At first you do not handle the case of d being outside of desired range. If d is e. g. 37, then you leave Nodges uninitialised, invoking undefined behaviour afterwards by reading it. You might add a final else to catch that case, printing some representation for an empty graph or a message and then return, so that you do not meet the for loops at all.
Simpler, though:
if(remainder < 3)
{
nodes = 10 + remainder;
// your for loops here
}
If you want to create an empty graph anyway, then don't forget to initialise nodes to 0; otherwise you should include the graph code in the if block above, too.
The main point your code fails is the following, though:
edges =
{
{i,j}
};
That way, you create a new vector again and again, always containing a single element, and the old one is replaced by that.
You actually need:
edges.emplace_back(i, j);
Finally: Get used to always check the stream's state after input operation. Users tend to provide invalid input, if you do not catch that you might get inexpected and actually undefined behaviour (such as dividing by 0).
if(std::cin >> a >> b >> c >> d)
{
/* your code */
}
else
{
// handle invalid input, e. g. by printing some message
// if you want to go on reading the stream:
// clears the error flags:
std::cin.clear();
// clears the stream's buffer yet containing the invalid input:
std::cin.ignore(numeric_limits<streamsize>::max(), '\n');
}

c++ programming arrays to of find number of integers in range [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
The question is attached and so I've tried to solve this but the output I'm getting is large numbers which is probably garbage data and therefore is definitely not correct.
Here is my code
#include <iostream>
#include <fstream>
using namespace std;
const int size=8;
void readData(char filename[], int list[], int size)
{
ifstream fin;
fin.open("HW4_Q1data.txt");
int value=0;
for(int i=0;i<30;i++)
{
fin>>filename[i];
value=filename[i];
if (value >= 0 && value <= 24)
list[0]++;
else if (value >= 25 && value <= 49)
list[1]++;
else if (value >= 50 && value <= 74)
list[2]++;
else if (value >= 75 && value <= 99)
list[3]++;
else if (value >= 100 && value <= 124)
list[4]++;
else if (value >= 125 && value <= 149)
list[5]++;
else if (value >= 150 && value <= 174)
list[6]++;
else if (value >= 175 && value <= 200)
list[7]++;
}
fin.close();
}
void print(int list[], int size)
{
cout << " Range"<<'\t'<<"# of students"<<endl;
cout << "0-24: " <<'\t'<<list[0] << endl;
cout << "25-49: " << '\t'<<list[1] << endl;
cout << "50-74: " <<'\t'<< list[2] << endl;
cout << "75-99: " <<'\t'<< list[3] << endl;
cout << "100-124: " <<'\t'<< list[4] << endl;
cout << "125-149: " <<'\t'<<list[5] << endl;
cout << "150-174: " <<'\t'<< list[6] << endl;
cout << "175-200: " <<'\t'<< list[7] << endl;
}
int main()
{
char filename[70];
int list[size];
readData(filename,list,size);
print(list,size);
return 0;
}
As VTT said, you do not initialize list values, therefore it has garbage values there. You should initialize them with 0.
int main() {
// filename stuff
int list[size];
for(int i = 0 ; i < size; i++) {
list[i] = 0;
}
// read and write functions
}
Also, as I far I can read from the question char filename[] should be used as the name of the file: fin.open(filename);
EDIT
Most of the program, to fix your problems:
void readData(char filename[], int list[], int size)
{
ifstream fin;
fin.open(filename);
int value;
for(inti= 0; i<30; i++) {
fin>>value;
if (value >= 0 && value <= 24)
list[0]++;
// ... other if else stuff
}
fin.close()
}
// print stuff
int main() {
int list[size] = {0}; // initialize the list with 0.
readData(*filename*, list, size); // replace *filename* with the real file name
print(list,size);
return 0;
}
Your assumption is correct, you are getting random (undefined behavior as standard says) data as the array values are uninitialised. There are several ways to initialise static arrays:
You can initialise static array with curly braces
int list[10] = {1,2,3,4,5,6,7,8,9,10} // will put 1,2...10 to your array
If you specify less elements in the brackets the compiler will put 0 in there, therefore initialising your array to zeroes (which you might often do) can be achieved easily:
int list[10] = {}
If you want to use any number, you can easily use the fill function:
fill(std::begin(arr), std::end(arr), 25); //will fill all elements to 25
using std::end for static array is convenient, because sometimes you cannot exactly say how many elements are there. You can define array with 10 elements as before, or you can have a curly brackets at the definition and then let the compiler to count the elements for you
int list[] = {32,5,0,10};
In C (and so in C++ using C style code) you can get this information in a bit hacky way:
int arraySize = sizeof(list)/sizeof(list[0]);
In your case it might be even more convenient to use C++ std::array rather than plain old static array. It is a simple wrapper around static array with few good methods and overloaded operators.
Regarding your assignment I believe when programming in C++ you should not pass char pointers, rather references to string, since C++ provides these higher level classes that are generally safer and more convenient to use. I have written my solution using some C++ features.
#include <iostream>
#include <fstream>
#include <array>
constexpr int arraySize = 8;
constexpr int maxNumber = 200;
using arrayType = std::array<int, arraySize>;
bool readData(const std::string &fileName, arrayType &results, count int numCount){
results.fill(0);
std::ifstream inFile(fileName, std::ifstream::in);
if (!inFile.is_open())
return false;
for(int i = 0; i < numCount; i++){
int val;
if(!(inFile >> val) || val < 0 || val > maxNumber)
return false;
results[std::min(maxNumber-1,val)/25]++; //Since 200 is included and the range contains 201 numbers
}
return true;
}
void print(const arrayType &count){
std::cout << "Range" << '\t' << "# of Students" << std::endl;
const auto printLine = [](const int minVal, const int maxVal, const int count){
std::cout << minVal << "-" << maxVal << '\t' << count << std::endl;
};
const int segmentSize = maxNumber/arraySize;
for(int i = 0; i < arraySize-1; i++){
printLine(i*segmentSize, (i+1)*segmentSize-1, count[i]);
}
printLine((arraySize-1)*segmentSize, maxNumber, count[arraySize-1]);
}
int main()
{
constexpr int numberCount = 30;
std::string fileName = R"(/mnt/d/Prog/C++/in2.txt)";
std::array<int,arraySize> frequences;
readData(fileName, frequences, numberCount);
print(frequences);
return 0;
}
Beside different language features used I also tried to remove the part with long list of if statements as it can be written with one line and such way follow the DRY principle, which is a good things to follow (less bugs, shorter code, lower chance of bugs in future as someone changes the code not at all places).

C++: find first prime number larger than a given integer

Question: How to find, for a given integer n, the first prime number that is larger than n?
My own work so far
I've managed to write a program that checks whether or not a given integer is a prime or not:
#include <iostream>
#include <cmath>
using namespace std;
bool is_prime (int n)
{
int i;
double square_root_n = sqrt(n) ;
for (i = 2; i <= square_root_n ; i++)
{
if (n % i == 0){
return false;
break;
}
}
return true;
}
int main(int argc, char** argv)
{
int i;
while (true)
{
cout << "Input the number and press ENTER: \n";
cout << "To exit input 0 and press ENTER: \n";
cin >> i;
if (i == 0)
{
break;
}
if (is_prime(i))
cout << i << " is prime" << endl;
else
cout << i << " isn't prime'" << endl;
}
return 0;
}
I'm struggling, however, on how to proceed on from this point.
You have a function is_prime(n), and a number n, and you want to return the smallest number q such that is_prime(q)==true and n <= q:
int q = n;
while (!is_prime(q)) {
q++;
}
// here you can be sure that
// 1. q is prime
// 2. q >= n -- unless there was an overflow
If you want to be a bit more efficient, you can check explicitly for the even case, and the increment by 2 each time.
It's a concrete example of a general theme: if you have a test function and a method for generating elements, you can generate the elements that pass the test:
x = initial_value
while (something) {
if (test(x)) {
// found!
// If you only want the first such x, you can break
break;
}
x = generate(x)
}
(note that this is not a valid C++ code, it's pseudocode)
int i;
**int k_koren_od_n = (int)(sqrt(n) + 0.5)**
for (i = 2; i <= k_koren_od_n ; i++){
To get around casting issues, you might want to add this fix.

Different ways of generating the partitions of a number in order

I have an exercise in my algorithms text book that asks me to generate the partitions of a number in order. I have solved it, but while solving the exercise the traditional way I came up with a new idea of solving that problem.
There is the traditional approach:
#include <iostream>
#define MAX_PARTITIONS 100
int count = 1;
void printSolution(int* solution, int size)
{
std::cout << count << "| ";
count++;
for(int i = 0; i < size; i++)
{
std::cout << solution[i] << " ";
}
std::cout << std::endl;
}
void generatePartitions(int* solution, int number, int sum, int partitions)
{
if(sum == number)
{
printSolution(solution, partitions);
return;
}
if(partitions > 1)
{
solution[partitions] = solution[partitions - 1];
}
else
{
solution[partitions] = 0;
}
while(solution[partitions] + sum < number)
{
solution[partitions]++;
sum += solution[partitions];
generatePartitions(solution, number, sum, partitions + 1);
sum -= solution[partitions];
}
}
int main(int argc, char const *argv[])
{
int solution[MAX_PARTITIONS];
generatePartitions(solution, 4, 0, 0);
return 0;
}
Basically, when the number of partitions is bigger than 1 (there exists a previous partition) I assign to the current partition the value of the previous one, otherwise I assign 0 to it.
There is the new approach:
#include <iostream>
#define MAX_PARTITIONS 100
int count = 1;
void printSolution(int* solution, int size)
{
std::cout << count << "| ";
count++;
for(int i = 0; i < size; i++)
{
std::cout << solution[i] << " ";
}
std::cout << std::endl;
}
void generatePartitions(int* solution, int number, int sum, int partitions,
int start)
{
if(sum == number)
{
printSolution(solution, partitions);
return;
}
solution[partitions] = start;
while(solution[partitions] + sum < number)
{
solution[partitions]++;
sum += solution[partitions];
generatePartitions(solution, number, sum, partitions + 1,
solution[partitions]);
sum -= solution[partitions];
}
}
int main(int argc, char const *argv[])
{
int solution[MAX_PARTITIONS];
generatePartitions(solution, 4, 0, 0, 0);
return 0;
}
As you can see, the function generatePartitions takes now a new parameter, start. Initially, the value of start is 0, and at each recursive call start takes the value of the current solution[partitions]. So it should work in the same way as the traditional method.
But it doesn't, the output of these programs is completely different. I can't figure out what is wrong. What am I doing wrong?
You forgot to move the index of the solution array when you recurse.
generatePartitions(solution, number, sum, partitions + 1,
solution[partitions]);
becomes:
generatePartitions(solution, number, sum, partitions + 1,
solution[partitions-1]);
Coliru link: http://coliru.stacked-crooked.com/a/83b0418e1b1c9bc1
Also, I'd propose using some form of std::pair<int,int> and a binary tree of some sort to do this for you--for me, it makes more sense to go from the top down, as we are trying to technically divide or partition a number into smaller ones; the algorithm might be a bit complex, but it might be possible to show a tree when you're done with it as well.

Recursive/iterative functions

I'm having a bit of a hard time creating a function, using iteration and recursion to find the sum of all even integers between 1 and the number the user inputs. The program guidelines require a function to solve this three ways:
a formula
iteration
recursion
This is what I have so far:
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
void formulaEvenSum(int num, int& evenSum)
{
evenSum = num / 2 * (num / 2 + 1);
return;
}
void loopEvenSum(int num, int& evenSum2)
{
}
int main()
{
int num, evenSum, evenSum2;
cout << "Program to compute sum of even integers from 1 to num.";
cout << endl << endl;
cout << "Enter a positive integer (or 0 to exit): ";
cin >> num;
formulaEvenSum(num, evenSum);
loopEvenSum(num, evenSum2);
cout << "Formula result = " << evenSum << endl;
cout << "Iterative result = " << evenSum2 << endl;
system("PAUSE");
return 0;
}
Using iteration to find the sum of even number is as given below.
void loopEvenSum(int num, int &evenSum2)
{
evenSum2=0;
for (i=2;i<=num;i++)
{
if(i%2==0)
evenSum2+=i;
}
}
The following code though not the most efficient can give you an idea how to write a recursive function.
void recursiveEvenSum(int num,int &evenSum3,int counter)
{
if(counter==1)
evenSum3=0;
if(counter>num)
return;
if(counter%2==0)
evenSum3+=counter;
recursiveEvenSum(num,evenSum3,counter+1);
}
Now you can call recursiveEvenSum(...) as
int evenSum3;
recursiveEvenSum(num,evenSum3,1);
You should be able to build an iterative solution using a for loop without too much problem.
A recursive solution might take the form:
f(a)
if(a>0)
return a+f(a-1)
else
return 0
f(user_input)
You have to differentiate between a case where you "dive deeper" and one wherein you provide an answer which doesn't affect the total, but begins the climb out of the recursion (though there are other ways to end it).
An alternative solution is a form:
f(a,sum,total)
if(a<=total)
return f(a+1,sum+a,total)
else
return sum
f(0,0,user_input)
The advantage of this second method is that some languages are able to recognise and optimize for what's known as "tail recursion". You'll see in the first recursive form that it's necessary to store an intermediate result for each level of recursion, but this is not necessary in the second form as all the information needed to return the final answer is passed along each time.
Hope this helps!
I think this does it Don't forget to initialize the value of evenSum1, evenSum2 and evenSum3 to 0 before calling the functions
void loopEvenSum(int num, int& evenSum2)
{
for(int i = num; i > 1; i--)
if(i%2 == 0)
evenSum2+=i;
}
void RecursiveEvenSum(int num, int & evenSum3)
{
if(num == 2)
{
evenSum3 + num;
return;
}
else
{
if(num%2 == 0)
evenSum3+=num;
num--;
RecursiveEvenSum(num, evenSum3);
}
}
void loopEvenSum(int num, int& evenSum2)
{
eventSum2 = 0;
for(int i = 1 ; i <= num; i++){
(i%2 == 0) eventSum += i;
}
}
void recurEvenSum(int num, int& evenSum3)
{
if(num == 1) return;
else if(num % 2 == 0) {
eventSum3 += num;
recurEvenSum(num-1, eventSum3);
}
else recurEvenSum(num-1, eventSum3);
}
btw, you have to initialize evenSum to 0 before calling methods.
the recursive method can be much simpler if you return int instead of void
void iterEvenSum(int num, int& evenSum2)
{
evenSum2 = 0;
if (num < 2) return;
for (int i = 0; i <= num; i+=2)
evenSum2 += i;
}
int recurEvenSum(int num)
{
if (num < 0) return 0;
if (num < 4) return 2;
return num - num%2 + recurEvenSum(num-2);
}
To get the sum of all numbers divisible by two in the set [1,num] by using an iterative approach, you can loop through all numbers in that range, starting from num until you reach 2, and add the number of the current iteration to the total sum, if this is divisible by two.
Please note that you have to assign zero to evenSum2 before starting the loop, otherwise the result will not be the same of formulaEvenSum().
void loopEvenSum(int num, int& evenSum2)
{
assert(num > 0);
evenSum2 = 0;
for (int i=num; i>=2; --i) {
if (0 == (i % 2)) {
evenSum2 += i;
}
}
}
To get the same result by using a recursive approach, instead of passing by reference the variable that will hold the sum, i suggest you to return the sum at each call; otherwise you'll need to hold a counter of the current recursion or, even worse, you'll need to set the sum to zero in the caller before starting the recursion.
int recursiveEventSum(int num)
{
assert(num > 0);
if (num == 1) {
return 0;
} else {
return ((num % 2) ? 0 : num) + recursiveEventSum(num-1);
}
}
Please note that, since you get an even number only if you subtract two (not one) from an even number, you could do optimisation by iterating only on those numbers, plus eventually, the first iteration if num was odd.