Consecutive comparisons using if statements inside a while loop - c++

I am supposed to compare two consecutive integers, i and j, that are given from a list of integers separated by whitespace which end with a 0 and, if i is less than j, I compare j to max and i to min. If the opposite, I compare j to min and i to max. The output is supposed to be each comparison I do with max, min, i, and j. Additionally, the list must be greater than 2 integers. If it is less then I am supposed to output 0. However the program does not seem to execute the if statements correctly.
int i = 1;
int j;
int max = 0;
int min = 0;
int counter = 0;
while (i != 0) {
cin >> i;
if (counter == 0) {
cout << 0 << endl;
i = min;
j = max;
} else if (counter == 1) {
cout << 0 << endl;
i = min;
j = max;
} else {
if (i < j) {
if (j > max) {
cout << j << " " << max << endl;
max = j;
}
if (i < min) {
cout << i << " " << min << endl;
min = i;
}
}
else {
if (j < min) {
cout << j << " " << min << endl;
min = j;
}
if (i > max) {
cout << i << " " << max << endl;
max = i;
}
}
}
j = i;
counter += 1;
}
}

You are overwriting i (and j) in the first iteration of the while loop (counter == 0) with min which is 0. As your while says while (i != 0) you immediately exit, after one while iteration. The ifs should be fine.

Input and counter logic can be improved by:
#include <iostream>
using namespace std;
int main(){
int i;
int j;
int max = 0;
int min = 0;
int counter = 0;
bool flag = true; // fix the input logic
while (flag){
cin >>i;
cin>>j;
if(i==0 || j==0){
flag = false;
break;
}else{
counter ++;
if(counter < 2 ){
//your code
}
else if(i<j){
cout<<"i: "<<i<<" j: "<<j;
j = max;
i = min;
// your code
}
else if(i>j){
//your code
}
}
}
return 0;
}

Related

Trying to find distinct positive integers from 1 to n such that they add up to s, random number pops up in a for loop

I'm trying to make a C++ program to find numbers from 1 to n (and their count) such that they add up to s, I've hit time limits so I was trying to optimise it by calculating sum only once and then mutating it. In the for loop in the removeStuff function, i becomes a random number even though length isn't.
#include <iostream>
using namespace std;
#define ll long long
//ll sumArray(ll arr[], ll length) {
// ll sum = 0;
// for (ll i = 0; i < length; i++) {
// sum += arr[i];
// }
// return sum;
//}
void printArray(ll arr[], ll length) {
string w;
ll count = 0;
for (ll i = 0; i < length; i++) {
if (arr[i] != 0) {
count += 1;
w += to_string(arr[i]) + " ";
}
}
cout <<count<<" " << w<< endl;
}
void removeStuff(long long arr[], long long length, long long target, ll sum) {
if (sum == target) {
printArray(arr, length);
return;
}
for (long long i = length - 1; i >= 0; i--) {
if (sum - arr[i] > target && arr[i] != 0) {
sum = sum - arr[i];
arr[i] = 0;
if (sum == target) {
printArray(arr, length);
return;
}
continue;
}
}
}
ll sum(ll n) {
return (n * (n + 1)) / 2;
}
int main() {
ios::sync_with_stdio(false);
int testCases;
cin >> testCases;
while (testCases--) {
ll n, s;
cin >> n >> s;
if (sum(n) < s) {
cout << -1 << endl;
continue;
} else if (sum(n) == s) {
string w;
for (ll i = 1; i <= n; i++) {
w += " " + to_string(i);
}
cout << n << " " << w << endl;
continue;
} else {
if (n >= s) {
cout << "1 " << s << endl;
continue;
} else if (s % n < n && n+n > s) {
cout << "2 " << n << " " << s - n << endl;
continue;
} else {
ll arr[n];
ll sum = 0;
for (ll i = 0; i < n; i++) {
arr[i] = i + 1;
sum = sum + i + 1;
}
removeStuff(arr, n, s, sum);
}
}
}
}
The problem occurs when I use the input 1 4 9.
For reference, here is a screenshot of my debugger results

How to display output in rows of five numbers?

I'm new to programming and I have to display all the prime numbers that are the product of this code in rows of five. After too many hours of trying to find something online, this is what I came up with. This way, not even the prime numbers are being displayed in the end; only 1s all the way. I'd be happy to know what I did wrong or what I could change.
#include <iomanip>
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
int main() {
int n { 0 };
cout << "Please enter an initial value n<2000 in order for the calculation to begin: " << endl;
cin >> n;
vector<bool> cygnus(n + 1);
for (int m = 0; m <= n; m++) {
cygnus[m]=true;
}
for (int j = 2; j < n; j++) {
if (cygnus[j] == true) {
for (int i = j + 1; i <= n; i++) {
if (i % j == 0) {
cygnus[i] = false;
}
}
}
}
int s = 0;
for (auto value : cygnus) {
if (value == true && s > 0) {
for (int counter = s; counter++; ) {
if (counter % 5 == 0) {
cout << setw(3) << s << " \n ";
}
if (counter % 5 != 0) {
cout << setw(3) << s << " ";
}
}
}
s++;
}
cout << endl;
return 0;
}
You are seriously over-complicating your output logic. Just have a counter variable declared (and initialized to zero) outside the for loop that does the output and then, every time you print a number, increment it. When that reaches the value of 5, print a newline and reset it to zero.
A couple of other points:
The STL containers (like std::vector) use the size_t type (not int) for their sizes and indexes. In the code below, I have changed all your int variables to this type; fortunately, that won't affect your algorithm.
Note that 1 is not a prime number.
Here's a re-worked version of your code:
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
int main()
{
size_t n{ 0 };
cout << "Please enter an initial value n<2000 in order for the calculation to begin: " << endl;
cin >> n;
vector<bool>cygnus(n + 1);
for (size_t m = 0; m <= n; m++) {
cygnus[m] = true;
}
for (size_t j = 2; j < n; j++) {
if (cygnus[j] == true) {
for (size_t i = j + 1; i <= n; i++) {
if (i % j == 0) {
cygnus[i] = false;
}
}
}
}
size_t s = 0;
size_t counter = 0;
for (auto value : cygnus) {
if (value == true && s > 1) { // Note that 1 is NOT a prime number
cout << setw(3) << s << " ";
if (++counter == 5) {
cout << "\n ";
counter = 0;
}
}
s++;
}
if (counter != 0) cout << "\n "; // Add newline for any partial last line.
cout << endl;
return 0;
}

I need this number pyramid to print out a specific sequence of numbers to the console?

I need a Number pyramid identical to this one:
1
121
12321
1234321
123454321
12345654321
I am new to programming and if anyone would't mine running through the code and telling me how each line is being understood by the compiler.
I heard there was a way to do this with embedded while loops. If anyone knows how to do that and can show me, that would be great.
The code I have is partially from the internet and not solely mine.
for (int i = 1; i <= rows; ++i)
{
for (int space = 1; space <= rows - i; ++space)
{
cout << " ";
++count;
}
while (k != 2 * i - 1)
{
if (count <= rows - 1)
{
cout << i << " ";
++count;
}
else
{
++count1;
cout << i + k - 2 * count1 << " ";
}
++k;
}
count1 = count = k = 0;
cout << endl;
}
cout << "\n\n\n";
system("PAUSE");
Try this code:
int main(void) {
int i, j, k, l, n = 6;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n - i; j++) {
cout << " ";
}
for (k = 1; k <= i; k++) {
cout << k;
}
for (l = i - 1; l >= 1; l--) {
cout << l;
}
cout << "\n";
}
return 0;
}

Repeating digits in number C++

The task is to write a function which takes a number and finds the digit that is repeated most times in that number. It should print the found digit and the times it is repeated.
I had a problem with the case when two digits were repeating a same number of times.
For example with given number 788995 it should return 8 -> 2 \\ 9 -> 2
How can I print that?
Here is the function:
void maxDigitInNumber (long long n)
{
if (n < MIN || n > MAX)
{
cout << -1;
return;
}
n = abs(n);
int numOfDigits = (int)log10(n)+1;
int digits[100];
int helper[100] = {0};
int counter = 0;
int maxSize = 0;
int number = 0;
for (int i = 0; i <= numOfDigits; i++)
{
digits[i] = n%10;
n /= 10;
}
for(int i = 0; i < numOfDigits; i++)
{
if(helper[i] == 0)
{
counter = 0;
for(int j = i; j < numOfDigits; j++)
{
if(digits[j] == digits[i])
{
counter++;
helper[j] = 1;
}
if(counter > maxSize)
{
maxSize = counter;
number = digits[i];
}
}
}
}
if (number == 0)
{
for (int i = 0; i < numOfDigits; i++)
{
cout << digits[i] << "->" << maxSize << endl;
}
}
else
{
cout << number << "->" << maxSize << endl;
}
}
You should store the count for each digit before picking the max. After that you can pick the max value among all counts, and print all entries matching that max:
int count[10] = {0};
do {
count[n%10]++;
n /= 10;
} while (n != 0);
int maxCount = 0;
for (int i = 0 ; i != 10 ; i++) {
maxCount = max(maxCount, count[i]);
}
bool first = true;
for (int i = 0 ; i != 10 ; i++) {
if (count[i] == maxCount) {
if (!first) {
cout << " \\\\ ";
} else {
first = false;
}
cout << i << "->" << maxCount;
}
}
There are only 10 digits, so an histogram of the digits in the number takes up only 10 words.
// ....
int hist[10] = {}; // Full tally available for further analysis
int max_count = 0; // result.
int max_digit = -1;
for (int i = 0; i <= numOfDigits; i++)
{
int digit = n % 10;
if (++hist[digit] > max_count)
{
max_count = hist[digit]; // could also be ++max_count ;)
max_digit = digit;
}
n /= 10;
}
Here are some algorithms you can use:
// prints digits with a certain score:
void print_if_score_is(const int hist[10], int score)
{
for (int i = 0; i < 10; ++i)
if (hist[i] == score)
std::cout << " digit: " << i << ", score: " << score << "\n";
}
int get_next_best_score(const int hist[10], int score)
{
int new_max = -1;
for (int i = 0; i < 10; ++i)
if (hist[i] > new_max && hist[i] < score)
new_max = i;
return new_max;
}
Usage:
// ....
std::cout << "Digit most frequently found: \n";
print_if_score_is(hist, max_count);
std:: cout << "next in list: \n";
int next_best = get_next_best_score(hist, max_count);
print_if_score_is(hist, next_best);
//...
Structure your program like this:
One function accepts the number to be analyzed and returns a std::multiset. multiset allows multiple entries for the same key. So for the number 788995 you would end up with a multiset { 1: [5, 7], 2: [8, 9] }
Another function analyzes the multiset and returns the numbers for the highest-ranking key in the set.

Explain this line of code

can someone explain when this line of code ends ? :
void constituteSubsequence(int i){
if( Pred[i] + 1) constituteSubsequence(Pred[i]);
cout << a[i] << " ";
}
In this program that calculate the longest increasing subsequence :
#include <iostream>
using namespace std;
int Pred[1000]; //Pred is previous.
int a[1000], v[1000], n, imax;
void read() {
cout << " n = ";
cin >> n;
cout << " Sequence: ";
for (int i = 0; i < n; i++) {
cin >> a[i];
}
}
void constituteSubsequence(int i) {
if (Pred[i] + 1) constituteSubsequence(Pred[i]);
cout << a[i] << " ";
}
void calculate() {
int i, j;
v[0] = 1;
imax = 0;
Pred[0] = -1;
for (int i = 1; i < n; i++) {
v[i] = 1;
Pred[i] = -1;
for (int j = 0; j < i; j++) {
if (a[j] < a[i] && v[j] + 1 > v[i]) {
v[i] = v[j] + 1;
Pred[i] = j;
}
if (v[i] > v[imax]) {
imax = i;
}
}
}
}
void write() {
cout << " Longest Increasing Subsequence : ";
constituteSubsequence(imax);
cout << endl << " Length: " << v[imax];
}
int main() {
read();
calculate();
write();
return 0;
}
If I run this code,it compiles and works as expected,but how does that condition repeat itself after it found a 0 value (false) and it print cout << a[i] ? .And when does it stop ?
In C++ an integer expression can be treated as a Boolean. For example, in the context of if statement Pred[i] + 1 means (Pred[i] + 1) != 0
This provides the answer to your question: the chain of recursive invocations is going to end when Pred[i] is -1. Of course, an easier to read way to express the same condition would be with the != operator:
if( Pred[i] != -1) {
constituteSubsequence(Pred[i]);
}