c++ code magically add 1 to the output - c++

So I can't figure this out. (obviously)
Basically the variable count is declared in the beginning, then only modified or incremented in one place. The expected final count is 78682. And when count is equal to that, I'll print out the string "ok". When count is incremented to 78683, the code checks the condition and prints the string "not ok".
It never prints "not ok", but at the very end when we print the value of the count, it's 78683! When did c++ incremented?
Another thing is that when the comment is uncommented below, the final result then becomes 78682, though I just don't understand why. Anyone? (oh btw, the code takes a minute to run....)
#include <stdio.h>
int main(){
int count=0, sum=0;
int length []={1,2,4,10,20,40,100,200};
int value [] ={200,100,50,20,10,5,2,1};
int tmp[8] ={0};
bool stop=false;
while(!stop){
sum=0;
for(int j=0,k=0; j<8; j++){
sum+=value[j]*tmp[j];
if(j==7){
if(sum==200){
count++;
if(count==73682) printf("ok\n");
if(count==73683) printf("not ok\n");
}
k=j;
tmp[k]++;
while(tmp[k]==length[k]+1){
tmp[k]=0;
k--;
tmp[k]++;
if(tmp[0]==2)
{
//tmp[0]--;
stop=true;
}
}
}
}
}
printf("Total %d.", count);
return 0;
}

On my computer I getting
ok
Total 73682.
both with the line commented and with the line uncommented. Therefore I can't debug it.
But the most probable assumption is that the reason you get wrong result is out-of-bounds array access. If you write tmp[anything] it can be any place in memory, including the place where count is stored. So you need to check that 0 <= anything && anything < 8. You can such an access here:
while(tmp[k]==length[k]+1){
tmp[k]=0;
k--;
please add safety checks to ensure k >= 0.
P.S. I added the check:
while(tmp[k]==length[k]+1){
tmp[k]=0;
k--;
if( k < 0 ) printf("oops\n");
with the line commented I get
ok
oops
Total 73682.
with the line uncommented I get
ok
Total 73682.
so probably you have some other mistake in the program. Sorry, can't find it. (Also knowing what the program suppose to do you can print intermediate results and check them. But you should see out of bounds access on you computer if you get 73683).

Related

C++ time limit exceeded when it doesn't even execute the function

While I was solving a problem in LeetCode, I found something very strange.
I have this line which I assume gives me a time limit exceeded error:
s.erase(i-k, k);
when I comment(//) this line, it doesn't show me time exceed error, but the strange part was, it has never executed even when i didn't comment it.
below is the entire code.
and Here is the problem link.
class Solution {
public:
string removeDuplicates(string s, int k) {
char prev = s[0];
int cnt = 1;
cnt = 1;
for(int i = 1; i < s.size() + 1; i++){
if(s[i] == prev){
cnt++;
} else {
if(cnt == k){
// when input is "abcd" it never comes to this scope
// which is impossible to run erase function.
s.erase(i-k, k);
i = 0;
}
if(i >= s.size()) break;
cnt = 1;
prev = s[i];
}
}
return s;
}
};
When Input is "abcd", it never even go to the if scope where 'erase' function is in.
Although 'erase' function never run, it still affect on the time complexity, and I can't get the reason.
Does anyone can explain this? or is this just problem of LeetCode?
Many online contest servers report Time Exceeding when program encounters critical error (coding bug) and/or crashes.
For example error of reading out of bounds of array. Or dereferencing bad (junk) pointers.
Why Time Exceeded. Because with critical error program can hang up and/or crash. Meaning it also doesn't deliver result in time.
So I think you have to debug your program to find all coding errors, not spending your time optimizing algorithm.
Regarding this line s.erase(i-k, k); - it may crash/hang-up when i < k, then you have negative value, which is not allowed by .erase() method. When you get for example i - k equal to -1 then size_t type (type of first argument of erase) will overflow (wrap around) to value 18446744073709551615 which is defnitely out of bounds, and out of memory border, hence your program may crash and/or hang. Also erase crashes when there is too many chars deleted, i.e. for erase s.erase(a, b) you have to watch that a + b <= s.size(), it is not controlled by erase function.
See documentation of erase method, and don't put negative values as arguments to this method. Check that your algorithm never has negative value i.e. never i < k when calling s.erase(i-k, k);, also never i-k + k > s.size(). To make sure there is no program crash you may do following:
int start = std::min(std::max(0, i-k), int(s.size()));
int num = std::min(k, std::max(0, int(s.size()) - start));
s.erase(start, num);

Storing strlen(str) to n integer gives different output than using it as it is in a for loop

In the code, if we use an integer n to store strlen(str), the output by for loop becomes different than used here! Why is that happening?
void helper(char str[], int start){
int n=strlen(str)
if(str[start]=='\0'||str[start]=='\0')
return;
helper(str,start+1);
if(str[start]=='p' && str[start+1]=='i'){
for(int i=n;i>=start+2;i--){
str[i+2]=str[i];
}
str[start]='3';
str[start+1]='.';
str[start+2]='1';
str[start+3]='4';
}
}
In order to complete your question, you should include your expected output and the one you got. Or the difference that you observe.
Anyway, it seems that your code contains undefined behaviour / out of bond array access.
for(int i=n;i>=start+2;i--){
str[i+2]=str[i];
}
If n is the size of the string, then at the first loop iteration, i+2 is greater than the string size.
Please complete your question to get more details.

ARRAYS DEBUGGING incorrect outputs, complex algorithm

I made this algorithm, i was debugging it to see why it wasnt working, but then i started getting weird stuff while printing arrays at the end of each cycle to see where the problem first occurred.
At a first glance, it seemed my while cycles didn't take into consideration the last array value, but i dunno...
all info about algorithm and everything is in the source.
What i'd like to understand is, primarily, the answer to this question:
Why does the output change sometimes?? If i run the program, 60-70% of the time i get answer 14 (which should be wrong), but some other times i get weird stuff as the result...why??
how can i debug the code if i keep getting different results....plus, if i compile for release and not debug (running codeblocks under latest gcc available in debian sid here), i get most of the times 9 as result.
CODE:
#include <iostream>
#include <vector>
/*void print_array
{
std::cout<<" ( ";
for (int i = 0; i < n; i++) { std::cout<<array[i]<<" "; }
std::cout<<")"<<std::endl;
}*/
///this algorithm must take an array of elements and return the maximum achievable sum
///within any of the sub-arrays (or sub-segments) of the array (the sum must be composed of adjacent numbers within the array)
///it will squeeze the array ...(...positive numbers...)(...negative numbers...)(...positive numbers...)...
///into ...(positive number)(negative number)(positive number)...
///then it will 'remove' any negative numbers in case it would be convienent so that the sum between 2 positive numbers
///separated by 1 negative number would result in the highest achievable number, like this:
// -- (3,-4,4) if u do 'remove' the negative number in order to unite the positive ones, i will get 3-4+4=3. So it would
// be better not to remove the negative number, and let 4 be the highest number achievable, without any sums
// -- (3,-1,4) in this case removing -1 will result in 3-1+4=6, 6 is bigger than both 3 and 4, so it would be convienent to remove the
// negative number and sum all of the three up into one number
///so what this step does is shrink the array furthermore if it is possible to 'remove' any negatives in a smart way
///i also make it reiterate for as long as there is no more shrinking available, because if you think about it not always
///can the pc know if, after a shrinking has occured, there are more shrinkings to be done
///then, lastly, it will calculate which of the positive numbers left is highest, and it will choose that as remaining maximum sum :)
///expected result for the array of input, s[], would be (i think), 7
int main() {
const int n=4;
int s[n+1]={3,-2,4,-4,6};
int k[n+1]={0};
///PRINT ARRAY, FOR DEBUG
std::cout<<" ( ";
for (int i = 0; i <= n; i++) { std::cout<<k[i]<<" "; }
std::cout<<")"<<std::endl;
int i=0, j=0;
// step 1: compress negative and postive subsegments of array s[] into single numbers within array k[]
/*while (i<=n)
{
while (s[i]>=0)
{
k[j]+=s[i]; ++i;
}
++j;
while (s[i]<0)
{
k[j]+=s[i]; ++i;
}
++j;
}*/
while (i<=n)
{
while (s[i]>=0)
{
if (i>n) break;
k[j]+=s[i]; ++i;
}
++j;
while (s[i]<0)
{
if (i>n) break;
k[j]+=s[i]; ++i;
}
++j;
}
std::cout<<"STEP 1 : ";
///PRINT ARRAY, FOR DEBUG
std::cout<<" ( ";
for (int i = 0; i <= n; i++) { std::cout<<k[i]<<" "; }
std::cout<<")"<<std::endl;
j=0;
// step 2: remove negative numbers when handy
std::cout<<"checked WRONG! "<<unsigned(k[3])<<std::endl;
int p=1;
while (p!=0)
{
p=0;
while (j<=n)
{
std::cout<<"checked right! "<<unsigned(k[j+1])<<std::endl;
if (k[j]<=0) { ++j; continue;}
if ( k[j]>unsigned(k[j+1]) && k[j+2]>unsigned(k[j+1]) )
{
std::cout<<"checked right!"<<std::endl;
k[j+2]=k[j]+k[j+1]+k[j+2];
k[j]=0; k[j+1]=0;
++p;
}
j+=2;
}
}
std::cout<<"STEP 2 : ";
///PRINT ARRAY, FOR DEBUG
std::cout<<" ( ";
for (int i = 0; i <= n; i++) { std::cout<<k[i]<<" "; }
std::cout<<")"<<std::endl;
j=0; i=0; //i will now use "i" and "p" variables for completely different purposes, as not to waste memory
// i will be final value that algorithm needed to find
// p will be a value to put within i if it is the biggest number found yet, it will keep changing as i go through the array....
// step 3: check which positive number is bigger: IT IS THE MAX ACHIEVABLE SUM!!
while (j<=n)
{
if(k[j]<=0) { ++j; continue; }
p=k[j]; if (p>i) { std::swap(p,i); }
j+=2;
}
std::cout<<std::endl<<"MAX ACHIEVABLE SUM WITHIN SUBSEGMENTS OF ARRAY : "<<i<<std::endl;
return 0;
}
might there be problems because im not using vectors??
Thanks for your help!
EDIT: i found both my algorithm bugs!
one is the one mentioned by user m24p, found in step 1 of the algorithm, which i fixed with a kinda-ugly get-around which ill get to cleaning up later...
the other is found in step2. it seems that in the while expression check, where i check something against unsigned values of the array, what is really checked is that something agains unsigned values of some weird numbers.
i tested it, with simple cout output:
IF i do unsigned(k[anyindexofk]) and the value contained in that spot is a positive number, i get the positive number of course which is unsigned
IF that number is negative though, the value won't be simply unsigned, but look very different, like i stepped over the array or something...i get this number "4294967292" when im instead expecting -2 to return as 2 or -4 to be 4.
(that number is for -4, -2 gives 4294967294)
I edited the sources with my new stuff, thanks for the help!
EDIT 2: nvm i resolved with std::abs() using cmath libs of c++
would there have been any other ways without using abs?
In your code, you have:
while (s[i]>=0)
{
k[j]+=s[i]; ++i;
}
Where s is initialized like so
int s[n+1]={3,-2,4,-4,6};
This is one obvious bug. Your while loop will overstep the array and hit garbage data that may or may not be zeroed out. Nothing stops i from being bigger than n+1. Clean up your code so that you don't overstep arrays, and then try debugging it. Also, your question is needs to be much more specific for me to feel comfortable answering your question, but fixing bugs like the one I pointed out should make it easier to stop running into inconsistent, undefined behavior and start focusing on your algorithm. I would love to answer the question but I just can't parse what you're specifically asking or what's going wrong.

C++ Dynamic bool array causes crash

Today I tried to program the Sieve of Eratosthenes and it works as far as it provides me with the prime numbers. But I have a problem with the dynamic array I don't understand.
First problem: As soon as I try to enter a "big" value for n (for example 120), the program crashes, it doesn't even allocate the memory.
Second problem: If I enter a value like 50 it is able to give out the correct prime numbers but crashes before it deletes the array.
Third problem: If I enter a very small value like 5 it is able to execute the entire program, it gives out the correct numbers and deletes the memory.
But I don't understand why it acts so differently. 120 boolean values can't crash my memory, at least I think so. And why isn't it able to delete an array of 50 values but is actually able to delete an array of 5 values?
Can anyone tell me what's the problem?
int n;
cin >> n;
n=n+1;
bool *feld = new bool[n];
for(int i=2;i<n;i++)
{
int j=i*i;
feld[j]=true;
for(;j<n;j+=i)
feld[j]=true;
}
for(int i=2;i<n;i++)
if(!feld[i])
cout << i << endl;
else;
delete[] feld;
feld = NULL;
Your problem is here:
int j=i*i;
feld[j]=true;
there is no check as to whether j < n so you are stomping over unallocated memory when j >= n.
This code is wrong
bool *feld = new bool[n];
for(int i=2;i<n;i++)
{
int j=i*i;
feld[j]=true;
...
}
Suppose n == 10 and i == 9, then j == 81 but you only have 10 elements in your bool array.
This is how it works when you write bugged programs, sometimes it seems to work, it might even give the right answer, other times it will crash. This is a very important lesson, and you're actually lucky to have learned it early.
Actually It's not just that feld[j]=true; is causing the error.
Also, you don't need that line at all before the loop.
because, it's the first case inside the loop.

C++ program to compute lcm of numbers between 1 to 20 (project euler )

as the title explains this is a program to find lcm of numbers between 1 to 20. i found an algorithm to do this, here's the link
http://www.cut-the-knot.org/Curriculum/Arithmetic/LCM.shtml
there is a java applet on the webpage that might explain the algorithm better
Problem: i wrote the code compiler shows no error but when i run the code the program goes berserk, i guess may be some infinite loopig but i can't figure it out for the life of me. i use turbo c++ 4.5 so basically if anyone can look at the code and help me out it would be great . thanks in advance
Algorithm:
say we need to find lcm of 2,6,8
first we find the least of the series and add to it the number above it, i.e the series become
4,6,8
now we find the least value again and add to it the intitial value in the column i.e 2
6,6,8
so the next iteration becomes
8,6,8
8,12,8
10,12,8
10,12,16
12,12,16
14,12,16
14,18,16
16,18,16
18,18,16
18,18,24
20,18,24
20,24,24
22,24,24
24,24,24
as you can see at one point all numbers become equal which is our lcm
#include<iostream.h>
/*function to check if all the elements of an array are equal*/
int equl(int a[20], int n)
{
int i=0;
while(n==1&&i<20)
{
if (a[i]==a[i+1])
n=1;
else
n=0;
i++;
}
return n;
}
/*function to calculate lcm and return that value to main function*/
int lcm()
{
int i,k,j,check=1,a[20],b[20];
/*loading both arrays with numbers from 1 to 20*/
for(i=0;i<20;i++)
{
a[i]=i+1;
b[i]=i+1;
}
check= equl(a,1);
/*actual implementation of the algorith*/
while(check==0)
{
k=a[0]; /*looks for the least value in the array*/
for(i=0;i<20;i++)
{
if(a[i+1]<k)
{
k=a[i+1]; /*find the least value*/
j=i+1; /*mark the position in array */
}
else
continue;
}
a[j]=k+b[j]; /*adding the least value with its corresponding number*/
check= equl(a,1);
}
return (a[0]);
/*at this point all numbers in the array must be same thus any value gives us the lcm*/
}
void main()
{
int l;
l=lcm();
cout<<l;
}
In this line:
a[j]=k+b[j];
You use j but it is unitialized so it's some huge value and you are outside of the array bounds and thus you get a segmentation fault.
You also have some weird things going on in your code. void main() and you use cout without either saying std::cout or using namespace std; or something similar. An odd practice.
Also don't you think you should pass the arrays as arguments if you're going to make lcm() a function? That is int lcm(int a[], int b[]);.
You might look into using a debugger also and improving your coding practices. I found this error within 30 seconds of pasting your code into the compiler with the help of the debugger.
Your loop condition is:
while(n==1&&i<20)
So your equl function will never return 1 because if n happens to be 1 then the loop will just keep going and never return a 1.
However, your program still does not appear to return the correct result. You can split the piece of your code that finds the minimum element and replace it with this for cleanliness:
int least(int a[], int size){
int minPos = 0;
for(int i=0; i<size ;i++){
if (a[i] < a[minPos] ){
minPos = i;
}
}
return minPos;
}
Then you can call it by saying j = least(a, 20);. I will leave further work on your program to you. Consider calling your variables something meaningful instead of i,j,k,a,b.
Your equl function is using array indices from 0-20, but the arrays only have 1-19
j in lcm() is uninitialized if the first element is the smallest. It should be set to 0 at the top of the while loop
In the following code, when i=19, you are accessing a[20], which is out of the bounds of the array. Should be for(i=0;i<19;i++)
for(i=0;i<20;i++) {
if(a[i+1]<k)
You are not actually using the std namespace for the cout. this should be std::cout<<l
Your are including iostream.h. The standard is iostream without the .h, this may not work on such an old compiler tho
instead of hard-coding 20 everywhere, you should use a #define. This is not an error, just a style thing.
The following code does nothing. This is the default behavior
else
continue;