Why am I getting a segmention fault? - c++

For my class, we are using two compilers, xcode and codeboard, where codeboard is the more rigorous of the two and has a list of preset asserts to test your code. In my code for function a, I have nested loops, where I want i to always be one ahead of k. It works fine in xcode, but gives me a segmentation fault on codeboard.
for (int k = 0; k <= n-2; k++) {
for (int i = k+1; i <= n-1; i++) {
if (array[k] == array[i])
What's strange is if I use k++ or ++k instead of k+1, it won't result in a segmentation fault, but my code won't pass all the asserts. I thought they were supposed to be the same thing?
What's even more strange is if I use k+1 in function b, it doesn't result in an error in codeboard.
for (int k = 0; k <= n-1; k++) {
for (int i = k+1; i <= n-1; i++) {
if (array[k] > array[i])
Basically, what is happening here?
Edit: So, what I'm getting from everyone is that when I use i = k+1 in the inner loop, it increases the k value in the outer loop. Like, if k=1, i=2, then when it goes back to the outer loop, k=3. If that's the case, how would I get i from staying ahead of k?
Edit: Please ignore the k++ and k+1 part of my question, that was not really my main issue, just a side thing that kind of confused me, but I get the difference now. I'd delete that part from my post, but I'm pretty sure that's not allowed. My main question is how to keep my i value 1 greater than my k value.
In the following code, the goal is if any of the array values are the same, it should cout true at some point. In regards to reproducible results:
string a[3] = {"aaa", "bbbb", "cccc"};
int n = 3;
for (int k = 0; k <= n-2; k++) {
int b = 0;
for (int i = k+1; i <= n-1; i++) {
if (a[k] == a[i])
b++;
}
if (b != 0) {
cout << "true" << endl;
break;
}
else
cout << "false" << endl;
}

No, they're not the same:
k + 1
Returns the value of k plus one, but does not change the value of k itself.
++k
Adds 1 to k and returns the new value (pre-increment).
k++
Also adds 1 to k but returns the previous value of k (post-increment).

k++ and ++k both increase k by one, changing the value of k.
k+1 does not.
Your segmentation fault comes from the fact that you are increasing k every time your initial for-loop is evaluated but also every time your second for loop is initialized. This means that you're reading further than your array at the end of your loop.

k++ and k+1 are not the same.
If you use k++ instead of k+1 inside the loop in the code you have shown, you are actually performing two increments on the variable k, which is usually not what you want in the control variable of a loop.
K+1 does not alter the value of k.
k++ increments k after using its value.
++k increments k before using its value.
So basically what is happening is that every time you start the inner loop, k gets incremented. But in the last round of the external loop, when k is equal to n-1, you perform another increment, which sets k to n, and this is most certainly not what you wanted.

Related

Can I create a for loop with two variables and still have time complexity of O(n)?

Say I have a for loop as:
for(int i=0,j=i+1;i<n-1,j<n;j++)
{
//some code
if(condition)
{
i++;
j=i;
}
}
What will be the time complexity and why?
Edited:
void printAllAPTriplets(int arr[], int n)
{
for (int i = 1; i < n - 1; i++)
{
// Search other two elements of
// AP with arr[i] as middle.
for (int j = i - 1, k = i + 1; j >= 0 && k < n;)
{
// if a triplet is found
if (arr[j] + arr[k] == 2 * arr[i])
{
cout << arr[j] << " " << arr[i]
<< " " << arr[k] << endl;
// Since elements are distinct,
// arr[k] and arr[j] cannot form
// any more triplets with arr[i]
k++;
j--;
}
// If middle element is more move to
// higher side, else move lower side.
else if (arr[j] + arr[k] < 2 * arr[i])
k++;
else
j--;
}
}
}
What would be the time complexity of this particular function and why?? #walnut #DeducibleSteak #Acorn .This is the code for "Printing all triplets in sorted array that form AP"
O(n^2) is when you iterate through all the possible values of one variable each time you iterate through the second one. As such:
for(int i=0; i < n; i++){
for (int j = 0; j < m; j++{
//Do some action
}
}
In your example, even though you're using two vars, but it's still a O(n).
Assuming that increasing i by one takes one second, then assigning the new i to j takes one second too, then the complexity is O(2n). Since constant numbers are insignificant when speaking about complexities, then the complexity of your code is still O(n)
The loop you have written does not make sense, because you are using the comma operator and discarding one of the conditions, so it is equivalent to j < n.
Even if the condition gets triggered many times (but a constant number w.r.t. n, i.e. not becoming larger as n grows), then you can easily show you will do <= k*n iterations, which means O(n) iterations.
If that is not true, but the condition is at least side-effect free, then you can only bound it by O(n^2), e.g. as #walnut suggests with j == n - 1 (like in a triangle matrix).
If you allow for side-effects in the condition (e.g. j = 0, with an equals sign), then it can be an infinite loop, so there is no possible bound.

how to see if all elements in vector are the same?

I have a vector of vectors.
How would I check to see if all elements in one of the columns are the same?
I`ve tried to check it with this nested for loop but I'm getting an out of range error.
void move_bee(vector< vector<insect> > &insects_on_board){
for(int i = 0; i < 10; i++){
for(int j = 0; j < insects_on_board.at(i).size(); j++){
for(int k = insects_on_board.at(i).size(); k > 0; k--){
if(insects_on_board.at(i).at(j) == "B" &&
insects_on_board.at(i).at(k) == "B"){
insects_on_board.at(i-1).push_back(bee());
insects_on_board.at(i).erase(insects_on_board.at(i).begin() + j);
}
}
}
}
}
I have read about the:
if (equal(myVector.begin() + 1, myVector.end(), myVector.begin()) )
method but it would not compile for me, I am assuming its because it's a vector of vectors.
The initial value of k is off the end: use
for(auto k=v.size(); k--;)
to loop backwards.
The use of at(i-1) must also be wrong, since i starts at 0.
Unless your vector is sorted, checking just two elements can’t tell you if they’re all equal.
Finally, even if you can’t use a range-for (because of index use like i-1 and ...+j), do bind a reference to the element you’re working on, at least at the outer level. The readability improvement is significant.

C++ Printing Odd numbers instead of Prime Numbers

I have been working on an assignment question for days and cannot seem to get the correct output (I've tried so many things!) The question is:
Write a program that uses two nested for loops and the modulus operator (%) to detect and print the prime numbers from 1 to 10,000.
I have been doing from 1 to 10 as a small test to ensure its working. I am getting 2,3,5,7,9 as my output, so I know something is wrong. When I increase the number from 10 to 20 it is printing 2 plus all odd numbers. I am including my code below. Thanks!!
int main() {
for (int i=2; i <=10; i++){
for (int j=2; j<=i; j++){
if (i%j==0 && j!=i) {
break;
}
else {
cout<< i <<endl;
break;
}
}
}
}
In addition to Sumit Jindal's answer inner for loop can be done by this way as well:
for(int j=2; j*j<=i ; j++)
If we think about every (x,y) ordered pair that satisfies x*y = i, maximum value of x can be square root of i.
The problem lies in the if-else branch. Your inner loop will be run exactly once because it will break out of the inner loop as a result of your if else branch.
When you first enter the inner loop the value of j is 2. Your condition will test if variable i is divisible by 2. If it is it breaks. Other wise (your else branch) will print the value of i and breaks out.
Hence printing odd numbers.
Break out of the inner loop and check whether j equals i in outer loop. You have to make j available for outer loop.
Your print statement is within the inner loop, and it should not be - it's only a prime if you run all the way through the inner loop without finding a divisor.
As a second point, you only need to check for divisors up to the square root of i, not all the way up to i.
You are breaking the inner loop after the first iteration itself, which is checking if the number(ie i) is different from j and is divisible by 2 or not (since j=2 for the first iteration)
I am getting 2,3,5,7,9 as my output
This is because every odd number fails the if and is printed in else condition
A minor correction in your code, adding a flag. Also you don't need to run the inner loop i times, infact only i/2 times is sufficient. This is simple mathematics, but will save significant number of CPU cycles (~5000 iterations lesser in your case)
#include <iostream>
int main()
{
int n = 10;
for(int i=2; i<=n; i++){
bool isPrime = true;
for(int j=2; j<=i/2; j++){
if(i!=j && i%j==0){
isPrime = false;
break;
}
}
if(isPrime)
std::cout << i << " ";
}
return 0;
}
Another version, if you don't mind output in reverse order.
int n = 10;
for (int i = n; i > 1; --i)
{
int factorCount = 0;
for (int j = 2; j <= n; ++j)
{
if (i % j == 0)
factorCount++;
if (factorCount > 1)
break;
}
if (factorCount == 1)
cout << i << endl;
}
int main() {
for (int i = 2; i <= 100; i++) {
for (int j = 2; j < i; j++) {
if (i%j == 0)
break;
if (j==i-1) // means has never run previous if blog
cout << i << endl;
}
}
return 0;
}

What is the time complexity when the iteration goes from 1 to i*i

Okay, so I have been wondering what will be the time complexity when the the for loop iterates from 1 to n*n.
Can someone please elaborate the time complexity in the following program???
for(i = 1 ; i < n ; i++)
for(j = 1 ; j < i*i ; j++)
for(k = 1 ; k < j ; k++)
Also, a little twist that confuses:
for(i = 1 ; i < n ; i++)
for(j = 1 ; j < i*i ; j++)
if(j%i == 0)
for(k = 1 ; k < j ; k++)
I think the first one is O(n^5). j is done i^2 times so does k.
i -> n
j -> n^2
k -> n^2
Thus it is O(n^5).
EDIT:
Regarding the second part, maximum number of divisor of a number, N, is less than 2*sqrt(N). Therefore, we can say that upper bound for for(k=1; k < j; k++) is O(sqrt(j)) = O(n).
So, the upper bound for the second part is O(n^4)
i = 1..n
j = 1..i*i
k = 1..j
WolframAlpha says O(n^5)
The sum to evaluate is
There is an equation for polynomial sums, but the important thing is that the leading term is always one order higher than the polynomial that is being summed. I.e, the answer is O(n^5).
To see the answer directly for loops of type
for(i = 1 ; i < n ; i++)
for(j = 1 ; j < i ; j++)
The correct answer can be calculated by just setting the inner loop to be the worst case,
for(i = 1 ; i < n ; i++)
for(j = 1 ; j < n ; j++)
which gives directly the answer for this e.g., O(n^2).
In the case with the remainder, the condition effects i^2-i cases out of possible i^2. Hence, the loop is effectively just run i times. The inner loop still runs up to n^2. Hence the overall complexity is O(n^4).
Edit: fixed the answer for the remainder case.
For the twisted one what I feel is,
The outer loop (i iterator) will iterate n times. --> n
The j iterator will iterate for 1+2+...n^2 times. So basically making it --> O(n^3)
The if condition will hold true for i times each iteration of outer loop (i iteration) because j goes till i * i so the inner loop (k iterator) will execute for n times (same as outer loop; i iterator). And the final code inside inner loop will execute for 1^3+2^3+3^3....n^3 times. Which makes the total complexity O(n^4).
But I don't feel so confident on this either.

Sieve of Eratosthenes C++ code

I'm fairly new to programming, and I just started C++
I found this problem, which involved generation all prime numbers upto "n". This is my code, where I've assumed "n" to be 10. I've tried my best. I'd really appreciate it if you guys could tell me what's wrong.
The for loop that's in a separate blockquote is repeating indefinitely, that means the value of i isn't being updated. I used a cout statement to print the value, it's either 0 or 1. Why is this happening? Is there a fault in the logic?
#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
int NumList[10], flag[10];
int i,j;
for(i = 0; i<10; i++) //Generate a list of numbers from 1 to 10
NumList[i] = i+1;
for(i = 0; i<10; i++) // Create a flag array, initialized to 1
flag[i] = 1;
for(i=1; i<10; i++)
{
if(NumList[i]%2==0) // Mark all even numbers in the list
flag[i] = 0; // since they're not prime
}
for(i = 2; i<10; i++) //Start from 3
{
if(flag[i]==1) // Check which numbers are left over
{
for(j = NumList[i]-1;j<10; ) //Since index = value-1 in this case
{
j+= NumList[i]; //Keep incrementing by value and marking in flag[]
flag[j] = 0;
}
}
}
}
The code is looping infinitely because you have accessed out of bounds in the following loop
for(j = NumList[i] - 1; j<10; )
{
j += NumList[i];
flag[j] = 0;
}
given that Numlist[i] is 3 when i = 2 in your outer loop, and j starts of as 2 in your inner loop, the following happens:
j takes value 2+3, flag[5] is assigned the value 0, current loop ends check 5 < 10
j takes value 5+3, flag[8] is assigned the value 0, current loop ends check 8 < 10
j takes value 8+3, flag[11] is assigned the value 0, current loop ends check 11 < 10
Once the third loop has finished (having modified flag[11]) all bets are off with respect to what will happen next. Indeed it is plausible that you are clobbering some other variable you have defined which is living at the address referenced by flag[11].
As for making this problem going away, with least disturbance to your current logic (whatever it is - it doesn't look correct) you can just increase the size of the flags array.