C++ odd-even array, infinite answer - c++

This program supposed to read the number of elements and a list, and split the array for even and odd numbers, and display the number of zeros in original array.
I posted a question before for the first problem I had with this program and the answers were really helpful since this is an assignment. But now I have another problem which is every time I run the program it gave me 0 'z. and it does not stop until I close the window. I think the problem is with the count function but I was not able to diagnose the problem by myself. I added:
cout<< odd_num<< " " << even_num;
after I called count function to find out what is the problem and it gave me a really big number so whatever the error is, it is coming from this function.
So please help me! I'm sure for most of you this is very basic but I just started to learn this and really appreciate it if you can help me.
Edit: I edited this code and the only problem is an extra zero as output; look at the example output at the end.
Here is the code:
int count(const int list[], int size, int & odd , int & even)
{
int zero(0);
for (int i(0); i<size ; i++)
{
if (list[i] == 0)
{
zero++;
}
if (list[i]% 2 ==0 & list[i]!=0)
{
even++;
}
else if (list[i]% 2 ==1 & list[i]!=0)
{
odd++;
}
}
return zero;
}
void split(const int list[], int size, int list_even[], int even_num, int list_odd[], int odd_num )
{
int j(0);
int k(0);
for (int i(0); i<size; i++)
{
if(list[i]%2 == 0)
{
list_even[j]= list[i];
j++;
}
else if(list[i]%2 != 0)
{
list_odd[k]= list[i];
k++;
}
}
if (j != even_num || k != odd_num)
{
cerr << "Error.";
}
}
// function to print an array
void print_list(int array[], int length)
{
for (int a=0; a<length; a++)
{
cout <<array[a]<<" ";
}
}
And here is the sample answer:
Enter number of elements: 3
Enter list:
2
30
0
Error.Even elements:
2 30 0 0
Odd elements:
There were 1 zeros in the list
Another sample is:
Enter number of elements: 3
Enter list:
2
1
5
Error.Even elements:
2 2752708
Odd elements:
1 5 2762032 2752708
There were 0 zeros in the list

You did not initialize your variables try:
int zero_num(0); // number of zeros
int even_num(0);
int odd_num(0);
Try printing them out before you start using them (before this fix) and see what they are set too. :)
Fix to your count function:
// function to copy odd and even number to seperate arrays
void split(const int list[], int size, int list_even[], int even_num, int list_odd[], int odd_num )
{
int j(0);
int k(0);
for (int i(0); i<size; i++)
{
if (list[i] == 0)
{ // zeros are not considered even in the count function
// so they should not be added here.
continue;
}
else if(list[i]%2 == 0)
{
list_even[j]= list[i];
j++;
}
else if(list[i]%2 != 0)
{
list_odd[k]= list[i];
k++;
}
}
// test that we have found the right number of even and odd numbers.
if (j != even_num || k != odd_num)
{
cerr << "Error.";
}
}
And to make sure that multiple calls to the count function does not mess up your numbers make this change:
//function to count the odd and even numbers and th enumber od zeros
int count(const int list[], int size, int & odd , int & even)
{
// reset the even and odd counts before we start.
odd=0;
even=0;
int zero(0); // variable to count zeros
for (int i(0); i<size ; i++)
{
if (list[i] == 0)
{
zero++;
}
else if (list[i]% 2 == 0 )
{
even++;
}
else if (list[i]% 2 == 1 )
{
odd++;
}
}
return zero;
}
Sample output:
Enter number of elements: 5
Enter list:
1
2
5
0
0
Even elements: 2
Odd elements: 1
5
There were 2 zeros in the list
Another sample output with zeros in begining and middle:
Enter number of elements: 5
Enter list:
0
2
0
1
7
Even elements: 2
Odd elements: 1
7
There were 2 zeros in the list

In if condition you are using & which is bit-wise operator instead of && which is Logical AND.
See:
if (list[i]% 2 ==0 & list[i]!=0)
{
even++;
}
use && instead and see if it works, else drop me a message.

[Improvement] How about to write your count function like this,
int count(const int list[], int size, int & odd , int & even)
{
int zero(0);
for (int i(0); i<size; ++i)
{
if (list[i]==0)
{
++zero;
}
else
{
if (list[i]%2==0) ++even;
else ++odd;
}
}
return zero;
}

Related

finding the number of possible decodings of the given number(dynamic programming)

I am trying to solve a problem where every letter has a respective number such as a-1,b-2....z-26.
Now given a number, in how many ways can the number be decoded is the question. consider an example where 25114 can be decoded as 'BEAN',‘BEAAD’, ‘YAAD’, ‘YAN’, ‘YKD’ and ‘BEKD’. this could be decoded in 6 ways.
I have written code in c++ but I am getting the wrong answer. Please correct my code.
#include<bits/stdc++.h>
using namespace std;
int total = 0;
int arr[100001];
void func(int start,int end,int factor){
if(start==end)
return;
int j =start;
if(factor==2&&j==end-1)//if j is the last element and factor is 2,accessing j+1 element is illegual
return;
if(factor==2){
if((arr[j]*10+arr[j+1])>26)
return;
else{
total++;
func(start+2,end,1);
func(start+2,end,2);
}
}
else{//factor is 1
total++;
func(start+1,end,1);
func(start+1,end,2);
}
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
int p;
cin>>p;
arr[i]=p;
}
func(0,n,1);
func(0,n,2);
cout<<total<<endl;
return 0;
}
essentially what my code is doing is that it fixes one number from the given array(using one digit or two digits from the the given array) and recurses until all the combinations are covered. for example considering the above case, I first choose '2' as my first digit and decode it as 'B'(factor = 1) and then choose '25' and decode it as 'E'(factor = 2).
**following are the input and output from the following code
input : 25114
expected output : 6
my output : 15
input : 3333333333(10 digits)
expected output : 1
my output : 10
Based on the original program from the question I suggest to count the encodings when you reach the end only (if(start==end)).
As func will always be called twice with factor=1 and factor=2, I can freely choose either condition for counting.
Here is the modified code:
#include<bits/stdc++.h>
using namespace std;
int total = 0;
int arr[100001];
void func(int start,int end,int factor){
if(start==end) {
if(factor == 1) total++; // count once when reaching the end
return;
}
int j =start;
if((factor==2) && (j==end-1))//if j is the last element and factor is 2,accessing j+1 element is illegal
return;
if(factor==2){
if((arr[j]*10+arr[j+1])>26)
return;
else{
//total++;
func(start+2,end,1);
func(start+2,end,2);
}
}
else{//factor is 1
//total++;
func(start+1,end,1);
func(start+1,end,2);
}
return;
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
int p;
cin>>p;
arr[i]=p;
}
func(0,n,1);
func(0,n,2);
cout<<total<<endl;
return 0;
}
This calculates the expected results from the example input in the question.
$ echo 5 2 5 1 1 4|./program
6
$ echo 10 3 3 3 3 3 3 3 3 3 3|./program
1
There is room for improvement.
Instead of modifying a global variable I would return the number of combinations from func and add the values in the higher level.
I would also handle the distinction between 2-digit and 1-digit numbers in the called func instead of in the caller.
Something like this pseudo code:
int func(int start, int end)
{
if(remaining length is <2) {
// we reached the end, so this is one combination
return 1;
}
if(two-digit number is >26) {
// only a 1-digit number is possible, count remaining combinations
return func(start+1, end);
}
// both a 1-digit or 2-digit number is possible, add the remaining combinations for both cases
return func(start+1) + func(start+2);
}
Your question is tagged as "dynamic-programming", but it is anything but.
Instead, think about the state space and its boundary conditions:
The empty string has zero encodings;
A single digit has a single encoding;
An n-digit string has as many encodings as an (n-1)-digit substring plus as many encodings as an (n-2)-digit substring if the first two digits are <= 26.
Thus, we can walk the string from back to front and store the intermediate results for reuse:
uint64_t solve(std::vector<int>& digits) {
const int n = digits.size();
std::vector<int> encodings(n+1);
encodings[n] = 1;
for (int i = n-1; i >= 0; i--) {
bool two_digits_fit = (i < n - 1) && (digits[i] * 10 + digits[i+1]) <= 26; // What if digits[i] == 0?
encodings[i] = encodings[i+1] + (two_digits_fit ? encodings[i+2] : 0);
}
return encodings[0];
}

Sequence with largest size of subsequence having each element as same

I want to find out the largest continuous subsequence having every element equal to 5 .
I tried writing a code for this but couldn't figure out the right method
example -> if sequence is like 5 5 1 0 93 43 5 5 5 5 21
answer will be 4 since 4 continuous 5's are present in the array .
P.S. - I'm a newbie stuck on it .
int large(int a[],int n)
{
int i=0,j=0,sublen=0;
while(i<n)
{
if(a[i]==1)
{
sublen++;
for(int j=i+1;j<n;j++)
{
if(a[j]==1)
{
sublen++;
}
else
{
i=j+1;
continue;
}
}
}
else
{
i++;
}
}
return sublen;
}
You could simply iterate through the sequence, when you see a 5 then increment a counter otherwise reset the counter to 0. When you increment the counter test to see if it's the largest value it's held so far. At the end return the largest value.
Something like:
int large(const int *a, int n)
{
int sublen = 0, counter = 0;
for (int i = 0; i < n; ++i) {
if (a[i] == 5) { // found a 5
++counter;
if (sublen < counter) { // test for largest value so far
sublen = counter;
}
} else { // not a 5
counter = 0;
}
}
return sublen;
}

Find a triplet that sum a given value

I've been struggling with a problem where based on a given number i have to find all the triplets that sum gives the given number.
For example if the given number is 5 conditions are : (x+y+z=5 and x<=y<=z) :
Input :
5
Output :
0 0 5
0 1 4
0 2 3
1 1 3
1 2 2
I've tried to find all the solutions starting with 0 but i can't figure out how to find solutions that start with 1, 2, 3, etc
What i have so far :
int x,y,z;
void showSolutions(int c) {
z=c;
while((x<=y) && (y<=z)) {
if((x<=y&&y<=z)&&(x+y+z)==c) {
cout<<x<<" "<<y<<" "<<z;
cout<<"\n";
}
y++;
z--;
}
}
Thanks for help!
Well you can think of this recursively, let me try to point a generic method which would work for two numbers or triplets or more.
class sum
{
public:
vector<vector<int>> triplets(int k, int target)
{
vector<vector<int>> result;
vector<int> holder;
getTriplets(k, target, holder, result);
return result;
}
void getTriplets(int k, int target, vector<int>& holder, vector<vector<int>>& result)
{
if(target < 0) return;
if(k < 0) return;
if(k == 0 && target == 0)
{
result.push_back(holder);
return;
}
for(int i = 0; i <= target; ++i)
{
holder.push_back(i);
getTriplets(k-1, target - i, holder, result);
holder.pop_back();
}
}
};
You can invoke this as:
sum s;
auto res = s.triplets(3,5);
for(auto row : res)
{
for(auto col : row) cout << col << " ";
cout << endl;
}
where the first argument to triplets is the what the size of set required and the latter is the garget value. The problem here is, it will produce duplicates, 0 0 5 and 5 0 0 I will leave that for you to figure out how.
Simply add results to a temporary holder and recursively try all combinations. until you reach the target value which is 0 in our case since we are subtracting, or hit a error condition. Backtrack and pop the value and exhausting all combinations. Store the result if we hit the target.
Live Demo
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
int x,y,z;
for(z=n;z>=0;z--)
{
for(y=0;y<=z && z+y<=n;y++)
{
x=n-(y+z);
if(x<=y)
cout<<x<<y<<z<<endl;
}
}
}
for n=5,you get
005
014
113
023
122

Need a function to continue decreasing a value once it runs out of valid values

So Im writing a function that is supposed to count up all the first N even numbers in an array where the user picks N. Which is fine, however if there are fewer than N even numbers in the array, then the function should just add them all which is the part I am having difficulty with.
function call:
cout << "The sum of the first " << userSum << " even numbers is: " <<
SumEvens(list, SIZE, userSum) << endl;
function definition:
int SumEvens(int arr[], const int size, int evensAdd)
{
int sum = 0;
for (int i = 0; i < size; i++){
if (arr[i] % 2 == 0 && arr[i] != 0){//if the number is even and not 0 then that number is added to the sum
evensAdd--;
sum += arr[i];
}
if(evensAdd == 0)//once evensAdd = 0(N as previously mentioned) then the function will return the sum
return sum;
}
}
So for example if I have an array: {1,2,3,4,5}
and ask for it to calculate the sum of the first 2 even numbers it would output 6
however if i ask for it to calculate say the first 3 or 4 or 5 even numbers it will output that the sum is 6
why would it subtract one?
If you finish the for loop before evensAdd reaches 0, you never reach the return sum statement and therefore not set the return value of the function. The value returned is then just a random number read from the stack. This is just a technical stuff, the correct approach should look like this:
int SumEvens(int arr[], const int size, int evensAdd)
{
int sum = 0;
for (int i = 0; i < size; i++)
{
if (arr[i] % 2 == 0 && arr[i] != 0)
{
evensAdd--;
sum += arr[i];
}
if (evensAdd == 0)
{
break;
}
}
return sum;
}
Using break will immediately jump to the end of the for loop and the return value will be set if in all cases.
EDIT: Check your compiler warnings, I'm pretty sure that every compiler gives a "Control may reach end of non-void function".
int SumEvens(int arr[], const int size, int evensAdd)
{
int sum = 0;
for (int i = 0; i < size && evensAdd > 0; i++)
{
if (arr[i] % 2 == 0 && arr[i] != 0)
{
evensAdd--;
sum += arr[i];
}
}
return sum;
}
This will work but like #πάντα ῥεῖ said using vectors would be a better idea.
You can just stop the loop with set condition, which is in this case better style than breaking.
Working example!

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.