Sieve of Eratosthenes C++ code - c++

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.

Related

How does C++ while code including two integers operate step by step?

I am quite new to C++ programming, I have reviewed while loops in python before however the two integers confuse me here. I would be very happy if you can explain to me how this while loop operates step by step.
#include<iostream>
using namespace std;
int main() {
int i;
int j;
while(i<10 || j < 5) { // i kucuk ondan kucuk oldu surece {} icerisindeki islemler surekli olarak while() loopu ile tekrarlancak
cout<<"i: "<<i<<" "<<"j: "<<j<<endl;
i = i + 1; // eger bu kod olmaz ise, sonsuza dek i degerine basacak
j = j + 1;
}
return 0;
}
#include<iostream>
using namespace std;
int main() {
/* You should first give a starting value
to the I and j, otherwise they
will get a random number and your while won't work*/
int i=0;
int j=0;
/* so as the word says "while" - while (something here is true)do the
following code between the starting
brackets and the finishing brackets. When it's not True skip the loop and go to the next line, in this example we will go to return 0 */
/*The value of i is 0 and the value of j is 0, and we first check if 0(i)<10 that's true next we check the other one
if 0(j) < 5 yes do the following block*/
/* the || mean "or' if either one of them
is true do the following block of code between the brackets*/
while(i<10 || j < 5) {
//we print
cout<<"i: "<<i<<" "<<"j: "<<j<<endl;
//we are incrementing the values of i and j for 1;
i = i + 1;
j = j + 1;
/*so what happens now it jumps again to the while
and checks if the statement is true, now i = 1 and j = 1;
and this runs until i is 10 because only then the i won't be lesser then
10 and j won't be lesser then 5 it will be false*/
*/
}
//close the program
return 0;
}
Hope I was clear!
You don't declare variables in Python. A "variable" is created when you first assign a value to a name. So you can't have uninitialized variables in Python.
That is not the case in C and C++. This code is declaring the i and j variables, but not assigning any values to them before trying to use them in the while loop. So your code has undefined behavior, as the variables contain whatever random values happened to already be present in memory where they get allocated.
You need to initialize the variables before your loop tries to evaluate them:
int i = 0;
int j = 0;

Bug in the 0-1 Knapsack code. What is the error in my code?

I was solving this problem in geeksforgeeks in the practice part but this code fails somewhere I don't understand
#include <iostream>
using namespace std;
int main() {
//code
int T,N,W;
cin>>T;//The number of test cases
while(T-->0){
cin>>N>>W;//N for number of items and W for capacity
int dyna[N+1][W+1] = {{0,0}};//table to store values
int val[N+1],wt[N+1];//val stores value and wt for weight
for(int i = 1;i <= N;i++)cin>>val[i];
for(int i = 1;i <= N;i++)cin>>wt[i];
for(int i = 0;i <=N;i++){
for(int j = 0;j <= W;j++){
if(i==0||j==0)dyna[i][j]=0;
else if(wt[i]<=W)
dyna[i][j] = max(dyna[i-1][j],val[i]+dyna[i-1][j-wt[i]]);
else
dyna[i][j] = dyna[i-1][j];
}
}
cout<<dyna[N][W]<<endl;
}
return 0;
}
For one, you have separate N and W lengths, which is redundant as these should always be equal. I think the problem you are observing, though, is with your else if. You check if the current weight is less than the number of items, which doesn't really make sense. It should probably be something like else if(j-wt[i]>=0), since you are trying to determine if you can subtract the current weight wt[i] from the current sum j and get a valid (in bounds) result. I imagine you are getting a segfault or similar because you are trying to access dyna[i-1][j-wt[i]] when, for instance, i and j are 1 and wt[i] is 10, as dyna[0][-9] is (probably) unalloced memory.

How to Compare multiple variables at the same time in the C++?

I'm making Sudoku validater program that checks whether solved sudoku is correct or not, In that program i need to compare multiple variables together to check whether they are equal or not...
I have provided a snippet of code, what i have tried, whether every su[][] has different value or not. I'm not getting expecting result...
I want to make sure that all the values in su[][] are unequal.
How can i achieve the same, what are mistakes in my snippet?
Thanks...
for(int i=0 ; i<9 ;++i){ //for checking a entire row
if(!(su[i][0]!=su[i][1]!=su[i][2]!=su[i][3]!=su[i][4]!=su[i][5]!=su[i][6]!=su[i][7]!=su[i][8])){
system("cls");
cout<<"SUDOKU'S SOLUTION IS INCORRECT!!";
exit(0);
}
}
To check for each column uniqueness like that you would have to compare each element to the other ones in a column.
e.g.:
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
for (int k = j + 1; k < 9; ++k) {
if (su[i][j] == su[i][k]) {
system("cls");
cout << "SUDOKU'S SOLUTION IS INCORRECT!!\n";
exit(0);
}
}
}
}
Since there are only 8 elements per row this cubic solution shouldn't give you much overhead.
If you had a higher number N of elements you could initialize an array of size N with 0 and transverse the column. For the i-th element in the column you add 1 to that elements position in the array. Then transverse the array. If there's a position whose value is different from 1, it means you have a duplicated value in the column.
e.g.:
for (int i = 0; i < N; ++i) {
int arr[N] = {0};
for (int j = 0; j < N; ++j)
++arr[su[i][j] - 1];
for (int i = 0; i < N; ++i) {
if (arr[i] != 1) {
system("cls");
cout << "SUDOKU'S SOLUTION IS INCORRECT!!\n";
exit(0);
}
}
}
This approach is way more faster than the first one for high values of N.
The codes above check the uniqueness for each column, you would still have to check for each row.
PS: I have not tested the codes, it may have a bug, but hope you get the idea.

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;
}

sort array without conditional

I need a program that sorts an array of integers without using conditional statements. Numbers are in the range from 0 to 100 and don't repeat.
#include <iostream>
using namespace std;
int main() {
int arr[] = { 34, 12, 24, 65, 63, 22 };
int arraySize = (sizeof(arr) / sizeof(*arr));
unsigned char buf[101] = { 0 };
for (int k = 0; k < arraySize; k++) {
buf[arr[k]]++;
}
unsigned char i = 0;
for (int k = 0; k <= 100; k++) {
arr[i] = k;
i += buf[k];
}
for (int a : arr) {
cout << a << endl;
}
system("pause");
return 0;
}
This program works but I get the error after closing of the command prompt:
Run-Time Check Failure #2 - Stack around the variable 'arr' was corrupted.
Is there a way to fix it?
The problem is that your code writes past the end of the array. It happens after you have encountered the last element in the counted sequence, but before the array buf has been exhausted, i.e.
for (int k = 0; k <= 100; k++) {
arr[i] = k;
i += buf[k];
}
When you add the highest element, which is 65, to the result, i reaches 6, so assigning a[i] becomes illegal. See what's going on by adding an extra element to your array, setting it to -1, and watching what happens to it (it gets set to 100; demo 1).
You can fix it by adding an early exit condition to stop as soon as you filled the array back, i.e.
for (int k = 0; i < arraySize && k <= 100; k++) {
arr[i] = k;
i += buf[k];
}
Now the -1 past the end of "active" part of our array remains -1 (demo).
The logic of the second loop is wrong. You have six numbers in arr, no doubles, which means that a total of six elements in buf will be set to 1.
That means that after a while, the value of i will be 6, which you then use as an index into arr, but index 6 is the seventh element in an array, leading you to write out of bounds.