Only able to print entry of an array at most twice [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 7 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
When I run the executable containing a function with the following code from the command line result[1] is only printed twice before the program crashes (" *.exe has stopped working ") even though blocklength is set to 25.
When I run the exact same executable with a double click the program crashes without printing anything. (but it runs until right before the for loop)
result is an array of type double and length blocklength, it is passed to the function as an argument.
for (int i = 0; i < blocklength; i++) {
cout << result[1] << endl;
}
When I used the GNU Project Debugger (GDB) to go through the program step by step it printed out result[1] 25 times and did not crash.
Obviously the original for loop did more than just print the same value over and over, but I narrowed the problem down to this and am now totally stuck and confused.
I would really appreciate any help or inputs.
Here's the full code, result is defined in the main function as double* result = new double[blocklength] and immediately passed to the function:
void entropy(char* input, int l_input, double* result, int blocklength, char order)
{
int l_counter = pow(order, blocklength);
int* counter = new int[l_counter];
double prob = 0;
int max_counter = 1;
int* temp = new int[l_input];
for (int i = 0; i < l_input; i++) {
temp[i] = 0;
}
for (int s = 1; s <= blocklength; s++)
{
max_counter *= order;
// reset counter
for (int i = 0; i < max_counter; i++) {
counter[i] = 0;
}
// init result
result[s] = 0;
for (int b = 0; b < l_input + 1 - s; b++) {
temp[b] = order * temp[b] + input[b - 1 + s];
counter[temp[b]]++;
}
for (int b = 0; b < max_counter; b++) {
prob = counter[b] / (double)(l_input - s + 1);
if (prob != 0)
{
result[s - 1] = result[s - 1] + fabs(prob * log(prob));
}
}
std::cout << "Block " << s << " okay" << std::endl;
}
cout << "sum done" << endl;
for (int i = 0; i < blocklength; i++)
{
cout << result[1] << endl;
}
std::cout << "Entroyp done!" << std::endl;
}

There are 2 things that seem wrong with your code.
result[s] is not read/written after it's initialised.
result[s] = 0;
Instead result[s-1] is accessed.
result[s - 1] = result[s - 1] + fabs(prob * log(prob));
This means that result[0] will never be set to 0. This also means that result[blocklength] = 0 will be assigned but never used.
If you have a line like int* result = new int[blocklength]; in your code, then you access a value that isn't in your array at all. A valid index is between 0 and arrayLenght-1.
Or more general:
If your input is wrong your programm blows up. You have to ensure that no value beyond an arrays capacity is accessed, this should be done in the line/loop in which it is accessed, not somewhere else.
In this case you have to ensure that results capacity is atleast blocklength+1.

Related

Incorrect mathematical results calculating power series [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
#include <iostream>
#include <cmath>
using namespace std ;
int main ()
{
int n, sum=0 ;
cout<< "Input number of terms: " ;
cin>> n ;
for (int i=1; i<=n; i++)
{
int k = pow(10, i) - 1 ;
cout << k ;
if(i < n)
{
cout<< " + " ;
}
sum += k ;
}
cout << "\nThe sum of the series = " << sum ;
{int m;cin>>m;}
return 0 ;
}
every time I run this code it gives me weird output like
9 + 98 + 999 + 9998 + ...
it subtracts some Ks from 2 !!
The rule is mathematically right and there is no syntax errors.
Is it the way of declaring k inside the loop or it's an compiler error ?
So, what's wrong here?
Here is the for loop without using the pow function:
int power = 10;
for (int i = 1; i < n-1; ++i)
{
const int k = power - 1 ;
cout << k;
if(i < n)
{
cout<< " + " ;
}
sum += k;
power *= 10; // This is important.
}
This should be more accurate than using pow because there is no conversions between integer and floating point.
Also, you may want to try using the series from 0 .. (n-1).
I think the best thing to do is to create your own power function because pow() is not working that way before when I used it. Kinda like this one
int pow_num(int base_num, int exp_num)
{
int result = 1;
for(int i = 0; exp_num > i; ++i)
{
result = result * base_num;
}
return (result);
}

my object::collides(object * o) function always returns true, but doesn't do anything

I have a function that returns a boolean. this function when compiled seems to contain nothing, and will always return true while also skipping over all the calls to cout or cin that i put in it. to see what it's actually doing. What is going on and how do i fix this issue.
In my process of troubleshooting, i have,
used GDB with a breakpoint at object::collides, this resulted in the function being called but not outputting anything to the console
Numbered my objects to and compared what objects the program thinks are colliding to the objects that are colliding. if it passes the proximity test, the program thinks the objects are colliding, evidence that it is always returning true.
tried various other methods to try to figure out what is going on, but all have left my without answers
in object.cpp:
bool object::collides(object * other)
{
std::vector<point> a_pnt = getBounds();
std::vector<point> b_pnt = other->getBounds();
for (int i = 0; i < a_pnt.size(); i++)
{
for (int j = 0; j < b_pnt.size(); j++)
{
point v1 = a_pnt[i];
point v2 = a_pnt[(i+1)%a_pnt.size()];
point v3 = b_pnt[j];
//edit: fixed typo
point v4 = b_pnt[(j+1)%b_pnt.size()];
double num_1 = ((v3.x - v1.x) * -(v4.y - v3.y)) - (-(v4.x - v3.x) * (v3.y - v1.y));
double num_2 = ((v2.x - v1.x) * (v3.y - v1.y)) - ((v3.x - v1.x) * (v2.y - v1.y));
double den =((v2.x - v1.x) * -(v4.y - v3.y)) - (-(v4.x - v3.x) * (v2.y - v1.y));
double frac_1 = num_1 / den;
double frac_2 = num_2 / den;
//debug code start
std::cout << num_1 << "/" << den << "=" << frac_1 << std::endl;
std::cout << num_2 << "/" << den << "=" << frac_2 << std::endl;
std::cout << (frac_1 > 0.0) << " " << (frac_1 < 1.0) << " " << (frac_2 > 0.0) << " " << (frac_2 < 1.0) << std::endl;
std::cout << std::endl;
std::string hahah;
std::cin >> hahah;
//end debug code
//edit: fixed conditional
if((frac_1>0.0)&&(frac_1<1.0)&&(frac_2>0.0)&&(frac_2<1.0));
return true;
}
}
//edit: fixed conditional
return false;
}
in mode.cpp in function mode::step():
for (int i = 0; i<onScreen.size(); i++)
{
object * o1 = onScreen[i];
for(int j = i+1; j<onScreen.size(); j++)
{
object * o2 = onScreen[j];
if(o1->getVectorLength(o2)<50){
std::cout << "Checking collisions for objects " << i << " and " << j << std::endl;
if(o1->collides(o2))
{
std::cout << "somthing collided\n";
}
}
}
}
output:
Checking for Collisions
Checking collisions for objects 0 and 11
somthing collided
Checking collisions for objects 1 and 8
somthing collided
Checking collisions for objects 1 and 18
somthing collided
Checking collisions for objects 1 and 26
somthing collided
Expected results is for the "collides" function to output to the screen or request the input for that string, this will show that it is actually going through that section of code properly. however it doesn't do this. the "collides" function returns true regardless of whether or not the actual intersect section is true or false, while skipping over all of my debug code, as shown in the output.
edits:
fixed the return in collides
fixed a typo
still doesn't work.
does go thought loops with bullet/bullet combinations not bullet/asteroid or asteroid/asteroid
checking getBounds has me scratching my head...
std::vector asteroid::getBounds()
{
//my issue was here, check your functions a bit more closely :P
//wasn't returning a vector with anything in it.
std::vector t;
//now it's
std::vector t = lyrs[0].pnts;
for (int i = 0; i < t.size(); i++)
{
double x = t[i].x+location.x;
double y = t[i].y+location.y;
t[i] = point{x, y, t[i].z};
}
return t;
}
i thought that was implemented properly
The problem occurs on this line:
if((frac_1>0.0)&&(frac_1<1.0)&&(frac_2>0.0)&&(frac_2<1.0)); //This semicolon here
return true;
Putting a semicolon at the end of the if statement basically ends the if statement. What you wrote is equivalent to
if((frac_1>0.0)&&(frac_1<1.0)&&(frac_2>0.0)&&(frac_2<1.0))
{
}
return true;
Fixing it is pretty simple. Just remove the semicolon:
if((frac_1>0.0)&&(frac_1<1.0)&&(frac_2>0.0)&&(frac_2<1.0))
return true;
So my issue was simple, and a bit of a "doh" moment. First the unrealtated issue I had to fix, was a return true, regardless of whether or not my math was actually done correctly, but as this section wasn't being hit, this wasn't the real issue. Thanks for those that noticed it anyway.
Issue one (no if on return true):
In collides.cpp
for (int i = 0; i < a_pnt.size(); i++)
{
for (int j = 0; j < b_pnt.size(); j++)
{
...
return true;
}
}
Fixed to:
for (int i = 0; i < a_pnt.size(); i++)
{
for (int j = 0; j < b_pnt.size(); j++)
{
...
if((frac_1>0.0)&&(frac_1<1.0)&&(frac_2>0.0)&&(frac_2<1.0))
return true;
}
}
The second issue, and the main one, after a suggestion from a commenter, his name is up in the question above, I double checked my getter for the bounding boxes. Low and behold, that was my issue. While at first I discounted his advice, because I thought I had fully implemented that getter, it was my issue and learning valuable lessons is always a good thing.
Issue two(incomplete implementation of GetBounds, resulted in empty vector getting returned.):
in asteroids.cpp:
std::vector asteroid::getBounds()
{
//my issue was here, check your functions a bit more closely :P
//wasn't returning a vector with anything in it.
std::vector<point> t;
//now it's
std::vector<point> t = lyrs[0].pnts;
for (int i = 0; i < t.size(); i++)
{
double x = t[i].x+location.x;
double y = t[i].y+location.y;
t[i] = point{x, y, t[i].z};
}
return t;
}
Lesson to learn: Even when you think you have everything working correctly there are times when you don't and you should check and double check EVERY function you are calling just incase one of those functions you think is working isn't actually working as it should.

Why was `unsigned int` causing the program to crash? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I had to make a program that checks if two words can be obtained one from the other by permutating the letters. I wrote the code as you can see below and I struggled quite a long time to find out why the program is crashing, and at some point I had the idea to change the fundametal type of these variables from unsigned int (unsigned int code = 0, i, j, counter = 0, ok = 1;) to integer (int code = 0, i, j, counter = 0, ok = 1;) and now it works properly but I don't know what changed so that now it works. I know (please correct me if I'm wrong) that unsigned int goes from 0 (including 0) to a very large number. All the variables were not going under 0, so I don't know why it didin't work in the unsigned int version and how the fundamental type changing solved the crash.
#include<iostream>
#include<string.h>
using namespace std;
int main()
{ char word1[50], word2[50];
unsigned int code = 0, i, j, counter = 0, ok = 1;
cout << "Type in the first word and then press ENTER:";
cin.getline(word1, 50);
cout << "Type in the second word and then press ENTER:";
cin.getline(word2, 50);
cout << endl;
if (strlen(word1) == strlen(word2)) //If the two words don't have the same lenght, it's impossible to obtain one word of the other by permutating it's letters.
{ for (i = 0; word1[i]; i++) /*This nested FOR will generate a number in the code variable. The first digit will indicate how many times will the letter word1[0] be found in word2,
the second digit will indicate how many times will the letter word1[1] be found in word2 and so on until the end of word1*/
{ counter = 0;
for (j = 0; word2[j]; j++)
if (word1[i] == word2[j])
counter += 1;
code = code * 10 + counter;
}
i = strlen(word1) - 1;
while (i >= 0 && ok) /*In this loop we are checking if the code is valable also for the word1 itself. If it is, it means that the words can be obtained one of the other by permutating the letters*/
{ counter = 0;
for (j = strlen(word1) - 1; j >= 0; j--)
if (word1[i] == word1[j])
counter++;
if (counter == code % 10)
ok = 1;
else
ok = 0;
code = code / 10;
i--;
}
if (ok)
cout << "Yes, the words can be obtained one of the other by permutating the letters.";
else
cout << "No, the words can not be obtained one of the other by permutating the letters.";
}
else
cout << "No, the words can not be obtained one of the other by permutating the letters.";
cin.get();
}
Part of your code goes:
while (i >= 0 && ok) { /* ...stuff here... */ --i; }
With an unsigned, if i is 0 and you decrement it, it will become the maximum unsigned value. As a result, i is always greater than or equal to 0 and the while loop keeps executing.
My guess is that is what is happening, and then, when you access word[i] you are accessing outside of the bounds of the array and crashing.
the problem is probably from the following code:
for (j = strlen(word1) - 1; j >= 0; j--)
because you defined j as unsigned int the for loop goes on for ever and never breaks.
Beginners mistake: Consider that if i is an unsigned int, i >= 0 will always be true. It cannot be false. If you set i to 0 and then subtract 1, you will get a very large positive number.
If your compiler didn't give you a warning, ask someone to show you how to turn more warnings on.

What is the purpose of the increment statement?

Why are increment statements a thing in for-loops in C++? To me it seems redundant, because you could simply put the increments inside the conditional code. Am I misunderstanding something important here?
To illustrate my question better, I'm including some pseudocode:
What is the difference between ->
for( int a = 10; a < 20; a = a + 1 )
{
cout << a << endl;
}
and
for( int a = 10; a < 20;)
{
a = a + 1
cout << a << endl;
}
It's more than mere convenience sometimes.
These are equivalent:
for (int a = 10; a < 20; a = a + 1) {
cout << a << endl;
}
for (int a = 10; a < 20; ) {
cout << a << endl;
a = a + 1;
}
But, these are not:
// this works ...
for (int a = 10; a < 20; a = a + 1) {
if (blah ...)
continue;
cout << a << endl;
}
// this doesn't
for (int a = 10; a < 20; ) {
if (blah ...)
continue;
cout << a << endl;
a = a + 1;
}
Since you're coming from python, an idiomatic for loop is like a python range, but much more powerful. Your C for loop, expressed in python would be:
for a in range(10,20,1)
It's more idiomatic to express this as:
for (a = 10; a < 20; a += 1)
Because the loop increment is 1, it's even more idiomatic to do this:
for (a = 10; a < 20; ++a)
But, for loops are:
for ([init_stmt]; [test_stmt]; [incr_stmt])
Where any of the *_stmt can be compound:
for (x = 0, y = 0; x < 10; ++x, y += 2)
Convenience.
However, your equivalent code should be:
for (int a = 10; a < 20;)
{
cout << a << endl;
a = a + 1;
}
It runs at the end of the loop body.
[ snips grumbling about quality of now deleted/ edited answers ;-) ]
This:
for (unsigned counter = 1; counter <= 10; ++counter) {
doStuff();
}
is largely equivalent to this:
unsigned counter = 1;
while (counter <= 10) {
doStuff();
++counter;
}
with the notable exception that, in the 1st case, you have the considerable benefit that counter is scoped only to within the for block and automatically goes out-of-scope as soon as it finishes - whereas with the latter, counter must remain in-scope after the loop, where it's potentially useless or even an obstacle.
(tangential: Note that C did not support within-for declaration, or any non-top-of-block declarations, until C99 - but barring extenuating circumstances, anyone not using at least C99 by now is making a questionable choice imho.)
edit: Craig also makes a very good point regarding continue - an oft-forgotten but certainly useful statement. I'm sure there are probably other differences we could conjure up.
for this example:
using namespace std;
int main(int argc, char** argv) {
for( int a = 10; a < 20;)
{
a = a + 1;
cout << a << endl;
}
return 0;
}
the output will be from 11-->20
the first example will be from 10-->19
your are putting the increment part outside the loop and this possible, but notice that the value 10 will not appear, because you are increment before printing the value of a
so in the 2nd example your printing the value and then increment, and at the end of the loop, you are quiting the loop without reaching 20, because the condition get you out the loop
executing code block before increment is the key for you, the for loop increment just after the code block is executed
Well it is not required, it is just for convenience.
In your second code, you made a little mistake which would make the code nonequivalent to the the first one.
Your increment should be at the end of loop in order to be equivalent to the first code
so it should rather be:
for( int a = 10; a < 20;)
{
cout << a << endl;
a = a + 1; //increment at the end of instructions
}
These little errors and also errors like forgetting to include your increment is why it is convenient to include the increment in the for loop.
Or you can use the while loop instead:
while (condition)
{//instructions here;}

How to make this algorithm faster? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am trying to come up with the following algorithm:
The input is unsigned integer number.
The output is the size of the array of unordered pairs of unsigned integers, which, when multiplied, give a number less then or equal to the input.
I have one naive implementation working, but it is way too slow for my purpose (compl. O(n^2), please correct me if I am wrong). My question is: how to make it faster?
#include <iostream>
using namespace std;
bool notInYet(int t[][1], int mi, int ma, int m) {
bool val = true;
for(int i = 0; i < m; i++)
if(t[i][0] == mi && t[i][1] == ma)
val = false;
return val;
}
int main() {
int n, m;
int t[100000][1];
cin >> n;
m = 0;
for(int i = 1; i <= n; i++) {
for(int j = 1; j*i <= n && j <= i; j++) {
if(notInYet(t, j, i, m)) {
t[m][0] = j;
t[m][1] = i;
//cout << "t[" << m << "] = (" << t[m][0] << ", " << t[m][1] << ")" << endl;
m++;
}
}
}
cout << m << endl;
return 0;
}
I think it should be something like that - pseudocode:
int counter = 0;
for int i = 1 to sqrt(input), i++ {
if (input % i == 0) counter++;
}
counter is an answer if you need unique pairs, otherwise you need to multiply it by 2 (and sub 1 if input % sqrt(input) == 0)
If I'm reading correctly #jauser's algorithm doesn't get what you want.
If the target is 5, then the pairs are (1,1)(1,2)(1,3)(1,4)(1,5)(2,2). So the answer is 6. His algorithm will produce 1 because 5 mod 1 == 0, but not mod 2.
In general, if the target is n, then you know (1,k) is a counted pair for all k from 1 to n. There are n - 1 + 1 = n of these. Now you have (2,k) for k from 2 to floor(n/2) (skip 1 because your pairs are unordered). There are n/2-2+1 of these. Continue this through (j,k) for j= floor(sqrt(n)). Putting this is pseudocode
count = 0;
for j in 1 .. floor(sqrt(n))
count += floor(n / j) - j + 1;
Maybe there is even some clever series solution that gets this to a constant time calculation.
Am I missing something in the problem?
Well, you are spending a lot of time effectively calculating the following per i:
j= n/i;
So if you just do that you reduce the complexity to O(n). You can halve it also since the list will contain both (i, j) and (j, i) when i!=j, but that won't reduce the overall complexity.