Second for loop is not being executed - c++

I am solving one competitive programming problem where I'm trying to traverse an array in reverse and inside it again traverse it in reverse direction. I've included this snippet from my code which doesn't seem to be working. The second loop is just ignored. It just outputs:
loop3
loop2
loop1
for(int i=n;i>0;i--)
{
cout<<"loop"<<i<<endl;
int a=arr[i];
int cnt=0;
if(!checked[a]) continue;
checked[a]=1;
int kk=k;
for(int j=i;j>=0;j--)
{
cout<<"in second loop";
int b=arr[j];
int res=a-b;
if(res<=kk)
{
kk-=res;
cnt++;
continue;
}
}
}

Instead of
if(!checked[a]) continue;
checked[a] = 1;
You might mean
if(checked[a]) continue;
checked[a] = 1;

I belive that checked is an array of zeros at the start of the for loop, if thats the case your if statment shoud be
if(checked[a]) continue;
Without the '!'.

Related

What can I use to stop a loop instead of 'return 0'?

so I made a simple loop that finds out if an array has the elements with the values of 0 and 1.
if the loop indeed finds 0 or 1 inside of the array, it will say "YES", otherwise "NO".
yes, the program works just fine, but at the end of the program it prints out "YES" or "NO" as many times as i put cin>>dim to.
for example if dim which means (dimension[of the array]) is 5 it's going to print either "YESYESYESYESYES" or "NONONONONO"
I have to use return 0 in order to make it print it out like once, but I feel like this is not the right way to do it. Please help me with this. thanks!
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i, dim, v[100];
cin>>dim;
for(i=0;i<dim;i++)
cin>>v[i];
for(i=0;i<dim;i++)
if(v[i]==0 || v[i]==1){
cout<<"YES"; return 0;}
else{
cout<<"NO"; return 0;}
return 0;
}
The break statement can be used to break out of loops. The example from cppreference:
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 5; k++) { //only this loop is affected by break
if (k == 2) break;
std::cout << j << k << " ";
}
}
As the comment suggests, break only breaks the innermost loop.
In your code you always exit from the loop on the very first iteration, hence you do not need the loop in the first place. This will have the same output as your code:
int main() {
int i, dim, v[100];
cin >> dim;
for(i=0; i < dim; i++)
cin >> v[i];
if(v[0] == 0 || v[0] == 1) {
cout << "YES";
} else {
cout << "NO";
}
}
After reading the question again...
I made a simple loop that finds out if an array has the elements with the values of 0 and 1
If you exit the loop after checking the first element then you only check the first element. If you want to see if an array contains only 1 or 0 or it contains at least one element which is 0 or 1 (not 100% clear which one you want), then you rather need this:
bool only_zero_or_one = true;
bool one_zero_or_one = false;
for (int i = 0; i < dim; ++i) {
zero_or_one = ( v[i] == 0 | v[i] == 1);
only_zero_or_one = zero_or_one && only_zero_or_one;
one_zero_or_one = zero_or_one || one_zero_or_one;
}
Only for one_zero_or_one you can break the loop once zero_or_one == true.
Moreover, you should rather use a std::vector. In your code, if the user enters a dim which is greater than 100 you write beyond the bounds of v. This can be avoided easily:
size_t dim;
std::cin >> dim;
// construct vector with dim elements
std::vector v(dim);
// read elements
for (size_t i=0; i < v.size(); ++i) std::cin >> v[i];
// .. or use range based for loop
for (auto& e : v) std::cin >> e;
but I feel like this is not the right way to do it
Returning is an entirely right way to break out from a loop.
Another right way is the break statement, which jumps to after the loop.
Even better, you can actually check if v[i]==0 or 1 inside the input for loop immediately after taking input and set a flag to true. Depending on requirement, you can either break or wait until the entire input is read and then come out and check for flag==true and then print "YES" and print "NO" if flag==false.
This will save you running the loop again to check for 0 or 1.

program for n-queens problem only works for n<=10 even though it should work for all n

The n-queens problem asks how many different ways are there to put n queens on a n-by-n board such that the queens cannot attack each other in one move. I've written a program which partially solves this problem. I say partially because my program only works for n<=10. However, I did not specify or hard-code the value 10, or any other value, in my code.
For example, my code outputs 92 solutions for 8-by-8, 352 for 9-by-9, and 724 for 10-by-10. These are the expected values as stated on the n-queens wikipedia page. However, my code outputs 1649 for 11-by-11. The expected answer is 2,680.
I really have no idea why this would occur.
using namespace std;
class Board{
struct Position{
int r;
int c;
};
public:
int size;
vector<vector<int> > b;
Position pos;
vector<int> placements;
int count;
Board(int s){
size=s;
pos.r=0;
pos.c=0;
for(int i=0; i<s; i++){
b.push_back(vector<int>());
for(int j=0; j<s; j++){
b.at(i).push_back(0);
}
}
count=0;
}
bool hasQueens(){
for(int i=0; size-i>=0; i++){
if(b[pos.r][pos.c-i]==1){
return true;
}
if(pos.r-i >= 0){
if(b[pos.r-i][pos.c-i]==1){
return true;
}
}
if(pos.r+i < size){
if(b[pos.r+i][pos.c-i]==1){
return true;
}
}
}
return false;
}
void placeQueen(){
b[pos.r][pos.c]=1;
placements.push_back(pos.r);
}
void backtrack(){
pos.c--;
b[placements[pos.c]][pos.c]=0;
pos.r = placements[pos.c] +1;
placements.pop_back();
if(pos.r==size) backtrack();
}
bool canBacktrack(){
if(pos.c==1 && placements[0]==size-1) return false;
else return true;
}
void nextSol(){
while(pos.c!=size){ //while the board is not filled
if(pos.r==size && canBacktrack()){
backtrack();
} else if(pos.r==size && !canBacktrack()){
break;
}else if(!hasQueens()){
placeQueen();
pos.r=0;
pos.c++;
} else {
pos.r++;
}
}
}
void print(){
for(int i=0; i<size; i++){
for(int j=0; j<size; j++){
cout << b[i][j];
}
cout<<endl;
}
cout<<endl;
}
};
int main(){
Board board(11);
board.print();
while(true){
board.nextSol();
if(!board.canBacktrack()) break;
cout << ++board.count << endl;
board.backtrack();
}
}
Your code segfaults for me. Running it through valgrind says that there is invalid read in this line:
if(b[pos.r][pos.c-i]==1){
in function hasQueens(). And indeed, there are cases in which pos.c-i becomes negative: whenever pos.c is smaller than size.
The organization of the code is messy, I would suggest to write your boundaries out clearly instead of relying on stopping for col == 1 and r == size (which if access incorrectly can cause a segfault). Also, NQueen problem has an elegant solution with recursion, I would suggest to look into that as well.
I was able to make some changes to your program and got the expected answer for 11 x 11, however I think there are more bugs in the code. The problem lies in the backtrack() and placeQueen() function, pos.c is decremented without checking if it's greater than 0, so it can potentially go negative and crash when access. Most importantly you don't need to do push_back/pop_back on the placement vector since you know you only can place one queen on each column so it should really be fixed size. when placing queen, you can do placement[c] = r. Hope this helps.

When looping through an array, is there a way to avoid doing a comparison upon each loop?

Assuming a loop that invariably iterates one at a time through some sequence, I want to know if there is some clever loop structure or trick that avoids doing a check upon each iteration for the end of the array.
for (int i=0; i<length; i++) {
//something
}
or
int i=0;
while (i<length) {
//something
i++;
}
For clarification, I'm referring to comparisons like those in the above examples (i<length).
If relevant, I generally code in C++, but am open to hearing about other languages that provide ways around this.
Yes, you can unroll the loop like this:
int i;
for (i = 0; i < length - 3; i += 4) { // 4x unrolled loop
//something(i)
//something(i+1)
//something(i+2)
//something(i+3)
}
for ( ; i < length; i++) { // clean up loop for residual 0..3 iterations
//something(i)
}
You can unroll the loop:
int length = 20 ;
int i=0;
while (i+3<length) {
//something
i++;
//something
i++;
//something
i++;
//something
i++;
}
//handle any remaining cases
while (i<length) {
//something
i++ ;
}
I want to know if there is some clever loop structure or trick that avoids doing a check upon each iteration for the end of the array.
Set i to the length, then decrement i on each iteration of the loop.
int i = length;
while ( i-- >= 0) {
// do something
}

Code not returning the right index

I'm tring to solve a small problem. I have two strings. s1 and s2. I want my function to return the first index of s1 that has a character not present in the string s2. This is my code.
int cad_nenhum_dos (char s1[], char s2[]){
int i,j;
for (i=0;s1[i]!='\0';i++)
{
for (j=0;s2[j]!='\0';j++)
if (s1[i]!=s2[j]) return i;
}
return -1;
}
If I run s1="hello" s2="hellm", the result should be index 4, because s1[4]='o' and "o" is not present in s2... But I allways get 0 when I run this. The -1 works fine if the strings are the same.
What am I doing wrong?
Regards
In your inner loop you need to break out when you find a character the same -- as it stands you're returning when there are any different characters in the second string, even if an earlier one was the same. You want something like
for (j=0;s2[j]!='\0';j++)
if (s1[i]==s2[j]) break;
if (s2[j]==0)
return i;
I.e. you want to return the ith character of the first string when you've made you way through the whole of the second string without having found that character.
For programming exercises at the introductory level it's a good idea to carefully execute the code manually (step through yourself and see what's happening).
As TooTone suggested, you need to break out of the loop when you find a match:
for (int i = 0; s1[i] != '\0'; i++)
{
bool charFound = false;
for (int j = 0; s2[j] != '\0'; j++)
{
if (s1[i] == s2[j])
{
charFound = true;
break;
}
}
if ( ! charFound)
return i;
}
Because the inner for-loop is comparing first letter of the first string against all the letters in the second string.
int cad_nenhum_dos (char s1[], char s2[])
{
int i,j;
for(i=0; s1[i]; i++)
{
if(s1[i] != s2[j])
return(i);
}
return(-1);
}

Sorting array with BubbleSort

l changed my code but still cant figure out why it wont sort array...bubble sort only moves all elements one place to the right in my program instead of sorting array...l tired bsort and ssort and both do same thing shift elements for 1 position
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void bsort(int n,int a[])
{
int i,j,k;
for(i=0;i<n-1;i++)
{
for(j=0;j<n-1;j++)
{
if(a[j]>a[j+1]);
{
k=a[j+1];
a[j+1]=a[j];
a[j]=k;
}
}
}
}
int main()
{
int i,j,k,m,n;
srand(time(0));
printf("Unesi broj clanova niza:");
scanf("%d",&n);
int a[n];
printf("Niz za sortiranje je:\n");
for(int i=0;i<n;i++) //Generisanje niza
{
a[i]=rand()%(81);
}
for(int i=0;i<n;i++)
{
printf("%3d",a[i]);
}
bsort(n,a);
printf("\n\nSortirani niz je:\n");
for(i=0;i<n;i++)
{
printf("%3d",a[i]);
}
}
There are several problems with your bubble sort implementation.
First, this line:
if (a[j] > a[j + 1]); {
is incorrect. The semi-colon terminates the conditional. As a result, the following block executes on every iteration of the inner loop and you end up unconditionally swapping a[j] and a[j+1] for every value of j. This means you're performing a nonsensical rearrangement of the array.
Second, you're not dealing correctly with edge cases in the inner loop. When j == 19, you access a[j+1], which is a[20], which is beyond the end of the array. You thus import garbage data into your array.
Lastly, even after correcting the above, your implementation is needlessly inefficient, in that your inner loop goes through the entire array on each iteration of the outer loop, which it doesn't have to. Hint: Try to think about how the initialization or termination condition of the inner loop could depend on i.
Update (after the OP's rewrite): You only addressed the second issue.
int main() {
int a[20];
srand(time(0));
// array values initialization
for (int i = 0; i < 19; i++) {
a[i] = rand() % (81);
}
// array sorting
bsort(a);
// array printing
for (int i = 0; i < 19; i++) {
printf("%3d", a[i]);
}
}