How to avoid infinite loop in this program - c++

I am trying to solve a 3n+1 problem in C++. I want to take the input in pairs and calculate its maximum cycle length then output it.
I/P: 1 10
100 200
201 210
900 1000
O/P: 1 10 25
100 200 125
201 210 89
900 1000 174
Code:
#include<iostream>
using namespace std;
int clen(int i)
{
int len=1;
while(i!=1)
{
len++;
if(i%2==0)
i/=2;
else
i=3*i+1;
}
return len;
}
int maxclen(int a, int b)
{
int i,len,maxlen=0;
for(i=a;i<=b;i++)
{
len=clen(i);
if(len>maxlen)
maxlen=len;
}
return maxlen;
}
main()
{
int b[10][2],l,i,len[10];
for(i=0;;i++)
{
cin>>b[i][0];
if(cin.fail())
{
cin.clear();
goto a;
}
cin>>b[i][1];
if(cin.fail())
goto a;
}
a:
l=i;
for(i=0;i<=l;i++)
{
if(b[i][1]>b[i][0])
len[i]=maxclen(b[i][0],b[i][1]);
else
len[i]=0;
}
for(i=0;i<l;i++)
cout<<b[i][0]<<" "<<b[i][1]<<" "<<len[i]<<endl;
}
I want to stop entering the input whenever cin.fail() returns true but its working for few first execution of the program but after that it is entering in an infinite loop to enter the numbers and it just cant get out. Can anyone help me on this cin issue, How can I avoid this infinite loop?

I found it died if you hit ctrl+d (eof) after only entering one number.
Maybe try adding another 'clear' the error state there:
main()
{
int b[10][2],l,i,len[10];
for(i=0;;i++)
{
cin>>b[i][0];
if(cin.fail())
{
cin.clear();
goto a;
}
cin>>b[i][1];
if(cin.fail())
{
cin.clear(); // ADDED LINE
goto a;
}
}
...
Though I wasn't able to reproduce the error 100% .. that seemed to help the behaviour with me.
Also your array is only 10 long .. maybe it's reading too much and going into some weird state ?

You have an off-by-one error over here:
for(i=0;i<=l;i++)
{
// ...
}
I modified your main like this to correct a couple of problems:
int main()
{
const size_t length = 10;
int b[length][2], len[length];
size_t i = 0;
while(i < length)
{
cin >> b[i][0];
if(!cin) break;
cin >> b[i][1];
if(!cin) break;
++i;
}
for(int j = 0; j < i; j++)
{
if(b[j][1] > b[j][0])
len[j] = maxclen(b[j][0], b[j][1]);
else
len[j] = 0;
}
for(int j = 0; j < i; j++)
cout << b[j][0] << " " << b[j][1] << " " << len[j] << endl;
}

Related

Find Extreme Value in Integers Given

I'm trying to find the highest value in a given list, but in an input list like this
7 385 -390 305 470 -145 255 30
my output is wrong, 385 instead of 470.
Could anyone please guide me towards my error!
Task description:
Read in an input value for variable numIn. Then, read numIn integers from input and output the largest of the integers read. End with a newline.
Ex: If the input is 2 345 -5, then the output is:
345
my code below
#include <iostream>
using namespace std;
int main() {
int numIn;
int high = 0;
cin >> numIn;
for (int i = 0; i < numIn; i++) {
cin >> numIn;
if (numIn > high) {
high = numIn;
}
}
cout << high << endl;
return 0;
}
First of all, your list has negative numbers. You can't set the default value of high to 0 since a list with all negative numbers won't work if you do this.
The error in your loop occurs because you overwrite numIn. Use a different variable for the number of input numbers.
cin >> numIn; // numIn is the number of input numbers
for (int i = 0; i < numIn; i++) {
cin >> numIn; // oops, numIn is now the first input number. it has been overwritten.
if (numIn > high) {
high = numIn;
}
}
A correct solution would look like this:
#include <iostream>
int main() {
int N; // assume that N >= 1. You could also replace this with numIn.
std::cin >> N;
int max;
std::cin >> max; // take in the first integer outside the loop
for (auto i = 1; i < N; i++) { // loop which runs N - 1 times
int E;
std::cin >> E;
max = std::max(max, E);
}
std::cout << max << '\n';
}
Without using std::max()
If you don't want to use std::max(), replace the line where you use it with a normal comparison (this is what std::max() does internally too)
if (E > max) { max = E; }

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.

C++ Array Processing

I am having trouble debugging this code so it reads two columns from the file and when the first column (Department is the same it just adds the second column to the old dept already created)This code is having trouble with looping. Any walk through, help would be much appreciated ! Thanks.
#include <iostream>
#include <fstream>
using namespace std;
ifstream inputFile; //stream object
int main()
{
inputFile.open("text.txt");
const int SIZE = 15;
int candy[SIZE];
int dept[SIZE];
int valuecounter = 0;
int Candy;
int Department;
while (inputFile >> Department >> Candy)
{
// Exit loop if we have filled the entire array
if (valuecounter == SIZE)
break;
// Update previous values
for (int index = 0; index < valuecounter; index++)
{
if (dept[index] == Department)
{
candy[index] += Candy;
}
}
// Update current values and increment counter
dept[valuecounter] = Department;
candy[valuecounter] = Candy;
valuecounter++;
}
for (int i = 0; i < valuecounter ; i++)
cout << dept[i] << " " << candy[i] << endl;
inputFile.close();
return 0;
}
and the list of input being for ex:
910 8
450 9
750 10
150 35
750 19
150 18
910 19
390 19
520 6
110 78
300 23
110 1
110 5
120 6
150 16
300 23
110 1
110 5
120 6
150 16
the array should be partially filled. but it produces weird outcome! logic error?
You have initialized valuecounter, and all elements of array dept, to zero. For this reason, in every iteration of the while loop, condition dept[valuecounter] == NULL will always evaluate to true. This means that, in every iteration, only code in the first if statement will execute.
Note that this is not the only problem with this code. As user Crazy Eddie pointed out, using NULL as an integer is considered very bad practice.
EDIT:
Replace your while loop with the following:
while (inputFile >> Department >> Candy)
{
// If this Department already exists ...
for (int index = 0; index < valuecounter; index++)
{
if (dept[index] == Department)
{
// ... update the corresponding value in 'candy' and continue the loop
candy[index] += Candy;
continue;
}
}
// If this Department does not exist, and if there are are more
// available array elements, assign a new Department
if (valuecounter < SIZE)
{
dept[valuecounter] = Department;
candy[valuecounter] = Candy;
valuecounter++;
}
}
int main()
{
const int SIZE = 15;
int candy[SIZE];
int dept[SIZE];
int valuecounter = 0;
int Candy;
int Department;
inputFile.open("text.txt");
if (!inputFile)
{
cout << "\nError opening file" << endl
<< "Exiting\n" << endl;
exit(1);
}
while (valuecounter < SIZE && inputFile >> Department >> Candy)
{
//setting bool to false everytime loop starts over.
bool found = false;
for (int index = 0; index < valuecounter; index++)
{
if (dept[index] == Department)
{
candy[index] += Candy;
//setting bool to true if department found
found = true;
}
}
if (!found)
{
dept[valuecounter] = Department;
candy[valuecounter] = Candy;
valuecounter++;
}
}
inputFile.close();
if (valuecounter == 0)
{
cout << "\n\nEMPTY FILE\nExiting.\n\n" << endl;
exit(1);
}
here i had three different functions do different things with data
return 0;
}
basically what i was missing is to set bool back to false whenever while loop started over this is why data wasn't calculated properly. Anyways Thank you all for help and all the tips!

How to average positive inputs until a negative input is given

How can I accept and average positive numbers? When a negative number is entered, it should terminate the loop and display the average (excluding the negative number).
#include <iostream>
using namespace std ;
int main () {
int x,counter=0,sum;
float avg;
while (x>0) {
if(x<0) {
sum+=x;
counter++;
continue;
} else if (x>0) {
cin>>x;
sum+=x;
counter ++;
}
}
avg=(float)sum/counter;
cout<<avg<<endl;
return 0 ;
}
#include <iostream>
using namespace std;
int main() {
int sum = 0, count = 0, input; // initialize all variables
while (true) { // loop forever (until break is reached below)
cin >> input; // get user input
if (input < 0) break; // if it's negative, exit loop
sum += input; // otherwise add it to the running sum
count++; // increase the count by 1
}
if (count > 0) cout << (double)sum / count; // if we have at least one number, display avg
else cout << "No numbers to average" << endl; // else complain.
return 0;
}
Note that this will fail if the user provides bad input. If you need it to handle bad input, see here about cin types.
The implementation that you have immediately adds the input to your sum.
int main () {
int x,counter=0,sum;
float avg;
while (x>0) {
cin >> x;
if (x>0) {
sum+=x;
counter ++;
}
}
avg=(float)sum/counter;
cout<<avg<<endl;
return 0 ;
}
This would allow you to check the input before adding to your total.
It is also important to mention to avoid dividing by zero if the user's first input is a negative number.
here is an improved version, that checks if loop exist without any positive integers entered to avoid divide by zero error
#include <iostream>
using namespace std ;
int main () {
int x;
float counter=0,sum;
float avg;
bool isPositive = true;
while ( isPositive) {
cin>>x;
if(x>0)
{
sum+=x;
counter ++;
}
else {
isPositive = false;
}
}
// if we divide by zero, an error will occur
if(counter > 0)
{
avg=(float)(sum/counter);
cout<<avg<<endl;
}
else cout << "Please enter positive numbers";
return 0 ;
}

Prime number C++ program

I am not sure whether I should ask here or programmers but I have been trying to work out why this program wont work and although I have found some bugs, it still returns "x is not a prime number", even when it is.
#include <iostream>
using namespace std;
bool primetest(int a) {
int i;
//Halve the user input to find where to stop dividing to (it will remove decimal point as it is an integer)
int b = a / 2;
//Loop through, for each division to test if it has a factor (it starts at 2, as 1 will always divide)
for (i = 2; i < b; i++) {
//If the user input has no remainder then it cannot be a prime and the loop can stop (break)
if (a % i == 0) {
return(0);
break;
}
//Other wise if the user input does have a remainder and is the last of the loop, return true (it is a prime)
else if ((a % i != 0) && (i == a -1)) {
return (1);
break;
}
}
}
int main(void) {
int user;
cout << "Enter a number to test if it is a prime or not: ";
cin >> user;
if (primetest(user)) {
cout << user << " is a prime number.";
}
else {
cout << user<< " is not a prime number.";
}
cout << "\n\nPress enter to exit...";
getchar();
getchar();
return 0;
}
Sorry if this is too localised (in which case could you suggest where I should ask such specific questions?)
I should add that I am VERY new to C++ (and programming in general)
This was simply intended to be a test of functions and controls.
i can never be equal to a - 1 - you're only going up to b - 1. b being a/2, that's never going to cause a match.
That means your loop ending condition that would return 1 is never true.
In the case of a prime number, you run off the end of the loop. That causes undefined behaviour, since you don't have a return statement there. Clang gave a warning, without any special flags:
example.cpp:22:1: warning: control may reach end of non-void function
[-Wreturn-type]
}
^
1 warning generated.
If your compiler didn't warn you, you need to turn on some more warning flags. For example, adding -Wall gives a warning when using GCC:
example.cpp: In function ‘bool primetest(int)’:
example.cpp:22: warning: control reaches end of non-void function
Overall, your prime-checking loop is much more complicated than it needs to be. Assuming you only care about values of a greater than or equal to 2:
bool primetest(int a)
{
int b = sqrt(a); // only need to test up to the square root of the input
for (int i = 2; i <= b; i++)
{
if (a % i == 0)
return false;
}
// if the loop completed, a is prime
return true;
}
If you want to handle all int values, you can just add an if (a < 2) return false; at the beginning.
Your logic is incorrect. You are using this expression (i == a -1)) which can never be true as Carl said.
For example:-
If a = 11
b = a/2 = 5 (Fractional part truncated)
So you are running loop till i<5. So i can never be equal to a-1 as max value of i in this case will be 4 and value of a-1 will be 10
You can do this by just checking till square root. But below is some modification to your code to make it work.
#include <iostream>
using namespace std;
bool primetest(int a) {
int i;
//Halve the user input to find where to stop dividing to (it will remove decimal point as it is an integer)
int b = a / 2;
//Loop through, for each division to test if it has a factor (it starts at 2, as 1 will always divide)
for (i = 2; i <= b; i++) {
//If the user input has no remainder then it cannot be a prime and the loop can stop (break)
if (a % i == 0) {
return(0);
}
}
//this return invokes only when it doesn't has factor
return 1;
}
int main(void) {
int user;
cout << "Enter a number to test if it is a prime or not: ";
cin >> user;
if (primetest(user)) {
cout << user << " is a prime number.";
}
else {
cout << user<< " is not a prime number.";
}
return 0;
}
check this out:
//Prime Numbers generation in C++
//Using for loops and conditional structures
#include <iostream>
using namespace std;
int main()
{
int a = 2; //start from 2
long long int b = 1000; //ends at 1000
for (int i = a; i <= b; i++)
{
for (int j = 2; j <= i; j++)
{
if (!(i%j)&&(i!=j)) //Condition for not prime
{
break;
}
if (j==i) //condition for Prime Numbers
{
cout << i << endl;
}
}
}
}
main()
{
int i,j,x,box;
for (i=10;i<=99;i++)
{
box=0;
x=i/2;
for (j=2;j<=x;j++)
if (i%j==0) box++;
if (box==0) cout<<i<<" is a prime number";
else cout<<i<<" is a composite number";
cout<<"\n";
getch();
}
}
Here is the complete solution for the Finding Prime numbers till any user entered number.
#include <iostream.h>
#include <conio.h>
using namespace std;
main()
{
int num, i, countFactors;
int a;
cout << "Enter number " << endl;
cin >> a;
for (num = 1; num <= a; num++)
{
countFactors = 0;
for (i = 2; i <= num; i++)
{
//if a factor exists from 2 up to the number, count Factors
if (num % i == 0)
{
countFactors++;
}
}
//a prime number has only itself as a factor
if (countFactors == 1)
{
cout << num << ", ";
}
}
getch();
}
One way is to use a Sieving algorithm, such as the sieve of Eratosthenes. This is a very fast method that works exceptionally well.
bool isPrime(int number){
if(number == 2 || number == 3 | number == 5 || number == 7) return true;
return ((number % 2) && (number % 3) && (number % 5) && (number % 7));
}