I am writing some function which basically takes in input a range and a 1D vector. It looks at each number in the range of values given of the vector such that:
1) If the number to the left of it is 0 they swap positions.
2) If the number to the left of it is equal to it they add.
Now up till now this was good. The issue arises when I am trying to add return statements:
1) It should return True after all iterations are complete and at least one of the if conditions is entered in each iteration.
2) It should return false after all iterations are complete and none of the conditions are entered.
Now if I put these return statements in the loops they would terminate this function here but this is not desirable since it needs to go through all the iterations first. Is the current code comparable with this or do I need to redo it in a different manner ( if not where could the return statements go?)
bool proc_num(std::vector<int>&v, int LB, int UB) {
bool check = false;
for( int i=LB+2 ; i<UB; i++) {
for(int j = i-1; j>LB; j--) {
if(v[j] == 0){
v[j] = v[i];
check = true;
} else if(v[j] == v[i]) {
v[j]= v[j]+v[i];
v[i] = 0;
check = true;
}
}
}
return check;
}
You can simply add a boolean to make sure that at least one of the if conditions are entered.
Related
This function looks for an integer 'key' in a given vector from a position 'start'. It returns the position of key if it finds it. But if it does not find key, it should return -1.
However, it is only returning -1 as the output. The function works fine if the else statement is removed, but obviously I need it.
So what is wrong in this function? Please explain in simple terms, I am new to C++. Thank you for all your help.
int Sequential_Search(const vector<int>&v, int key, int start){
int result = 0;
int i;
for(i = start; i < v.size(); i++){
if(v[i] == key){
result = i;
}
else{
result = -1;
}
}
return result;
}
This is pretty easy to understand:
for(i = start; i < v.size(); i++){
if(v[i] == key){
result = i;
}
else{
result = -1;
}
}
Let's say your vector contains [1, 2, 3, 4] and you search 2 starting at index 0: here is what your code is doing:
i = 0: (v[i] : 1) == 2 -> false: result = -1
i = 1: (v[i] : 2) == 2 -> true: result = 1
i = 2: (v[i] : 3) == 2 -> false: result = -1
i = 3: (v[i] : 4) == 2 -> false: result = -1
When you've found your value, you still continue to read other value whereas you should stop.
Either using break or directly returning (return i) in the v[i] == key condition;
Either by checking result in the for condition (result == -1 && i < v.size())
Per comment remark: the case with break and return (the last one is not so hard):
int Sequential_Search(const vector<int>&v, int key, int start){
int result = -1; // important for 'break'
for(int i = start; i < v.size(); i++){
if(v[i] == key){
result = i; break;
}
}
return result;
}
int Sequential_Search(const vector<int>&v, int key, int start){
for(int i = start; i < v.size(); i++){
if(v[i] == key){
return i;
}
}
return -1;
}
When the loop finds the key, it sets result = i - but it doesn't stop looping. On the next iteration, v[i] is likely not equal to key, and the loop resets result to -1. The function returns -1 unless key just happens to match the last element.
The reason this is failing with the else statement is because there are many scenarios that the key would not be the last item in the vector.
If the key is 3 and the vector of ints if <1,3,4>, the for loop will loop through 3 times total. On the first iteration, it will go into the else statement since we did not find the key at the 0th index. Result is -1. On the second iteration, we found the key! Set result to i = 1. The third iteration will go into the else statement again, and set the result back to -1.
To fix this, you can use 'break' to leave the for loop as soon as you find result. Set result to I and then follow that with break; This will ensure that if the result is found, you will not go into the else statement again and reset it to -1.
Sorry if the question seems really trivial but I'm just learning how to code and this one kept me in front of the computer for about 2 hours without getting to realize why this happens.
I'll pass the code below.
So, in order to keep it straightforward:
isPrime() is a function that just checks if a current number is Prime or not.
nPrime() is a function that returns the n-ism prime number, given N as the parameter.
The key point here is the main function and, more precisely, the number value in the first while-loop.
If you run this code, when it reaches the last prime number by which number is divisible, it'll enter an infinite loop. This can be easily solved if you just change the first while condition from while(number > 0) to while(number > 1).
That's the weird thing I can't come to realize:
If the inner second while-loop won't exit as long as number % nPrime(index) != 0 and the last instruction of the outter first while-loop is number /= nPrime(index);, how come the program enters an infinite loop?
That last instruction set number's value to 0, so the first while-loop condition should return false and exit the loop.
What am I missing?
Thank you all for your time and patience.
PS: I got downvoted and I don't know why, so I'll make an clarification:
I've done the research. As far as I know, every source seems to agree on the same point:
the > condition returns true if and only if left operand is greater than right operand.
Which takes me to the previously written question: if number is equal to 0, how's the while-loop not evaluating the number > 0 as false and exiting from the iteration?
#include <iostream>
using namespace std;
bool isPrime(int);
int nPrime(int);
int main() {
int number = 264;
if (number > 0)
{
int index = 1;
while(number > 0)
{
while (number % nPrime(index) != 0)
{
index++;
}
cout << nPrime(index) << endl;
number /= nPrime(index);
}
}
else
cout << "Error";
return 0;
}
bool isPrime(int n)
{
bool isPrime = false;
int totalDividends = 0;
for (int i = 1; i <= n; ++i)
{
if (n % i == 0)
totalDividends++;
}
if(totalDividends == 2)
isPrime = true;
return isPrime;
}
int nPrime(int n)
{
int result = 0;
for (int i = 0; i < n; ++i)
{
do
{
result++;
} while (!isPrime(result));
}
return result;
}
What am I missing?
That last instruction set number's value to 0
No it doesn't, it never gets that far. When number equals one then number % nPrime(index) != 0 is always true, so the inner while loop never exits.
Your understanding of while loops is perfect, it's your understanding of what your own code does that is in error. This is normal for bugs like this.
I'm trying to make a for loop so that when there is an item for sale and an item wanted with a lower price, it removes the two listings and exits the for loop using 'j'. For some reason though, the value of askingPrice is staying the same, and removing all items with a lower price, instead of just removing the first one it encounters, and breaking the loop. Is there a different way I should be exiting the loop, or do I just have a logic error somewhere?
for(int i = 0; i < elements; i++){
if(itemArray[i].status == "for sale"){
int askingPrice = itemArray[i].price;
string ITEM = itemArray[i].type;
for(int j = 0; j < elements; j++){
SOLD = 0;
position = 0;
if(itemArray[j].status == "wanted" && itemArray[j].type == ITEM && itemArray[j].price >= askingPrice){
soldArray[soldPosition].type = itemArray[j].type;
soldArray[soldPosition].price = askingPrice;
soldPosition += 1;
//cout << soldPosition << endl;
if(i > j){
for(int k = i; k < elements; k++){
itemArray[k].price = itemArray[k+1].price;
itemArray[k].type = itemArray[k+1].type;
itemArray[k].status = itemArray[k+1].status;
if(k == elements - 2){
elements = elements - 1;
}
}
position = 1;
}
for(int k = j; k < elements; k++){
if(k == elements - 1){
elements = elements - 1;
break;
}
itemArray[k].price = itemArray[k+1].price;
itemArray[k].type = itemArray[k+1].type;
itemArray[k].status = itemArray[k+1].status;
}
if(position = 0){
for(int k = i; k < elements; k++){
if(k == elements - 1){
elements = elements - 1;
break;
}
itemArray[k].price = itemArray[k+1].price;
itemArray[k].type = itemArray[k+1].type;
itemArray[k].status = itemArray[k+1].status;
}
}
SOLD = 1;
}
if(SOLD == 1){
i = i-2;
break;
}
}
}
}
break only breaks out of the innermost loop. There are 2 ways you can conquer this problem:
Set a flag and break out of each subsequent loop if it is triggered.
Extract functions from your program and distinguish single loop breaks from total loop breaks using return to break form multiple associated loops vs break for a single loop. For larger problems always use this method, it will make your code easier to read, well structured and more maintainable.
Either use a sentinel value and sequentially break out of each loop. (The modern way of doing things) OR Cause a massive wave of "You're doing it wrong!" screaming and just use a goto statement. I advocate goto only if you are nesting for loops on 4th or 5th order or higher. If that's the case: "YOU'RE DOING IT WRONG!"
For some reason though, the value of askingPrice is staying the same
You are not changing askingPrice anywhere in your code.
when there is an item for sale and an item wanted
An itemArray object cannot have both status "for sale" and "wanted" at the same time.
So lets say if(itemArray[i].status == "for sale") is true in i loop. The control goes into the if statement and initializes askingPrice and ITEM with ith item's price and type.
From there, j loop is started from 0th element in itemArray. Your j loop has no regard for status = "for sale", this loop only knows the price and type. At this point SOLD = 0;
Now control checks this
if(itemArray[j].status == "wanted" && itemArray[j].type == ITEM && itemArray[j].price >= askingPrice)
Please Note that above if can either be true or false. But in any case it is not considering
status = "for sale"; Therefore, when the above if condition is true, it runs the code within and deletes low priced item according to the condition and when it is false, the code never reaches SOLD = 1; which does not allow j loop to break as if(SOLD == 1) break;
So there you have it and yes you are right, it is indeed a logical error.
I created a custom boolean function named "isPrime()", some how I made it work but I don't know why it works, any explanation in plain english will be appreciated.
for (i = 3; i < 100; i++)
{
if (isPrime(i))
{
std::cout << i << "\n";
}
}
// I don't understand why this loop works:
bool isPrime (int i)
{
int j;
for (j = 2; j < i; j++)
{
if (i % j == 0) // 3 / 2
{
return false;
}
}
return true;
}
As you can see the isPrime() function has a loop so once it's finished, it should return true anyway because the return true; is outside of the loop and compiler will read return true; once the loop is finished. How the isPrime() function can return false when the it is returning true at the end?
If a function reaches a return statement at any point, it will exit completely, no matter where the return statement is, and control will go to the function who called it (in this case, I am assuming main).
When i % j == 0
it will return false and the loop finish
then the last statement "return true" will not run
Check this code segment.
if (i % j == 0) // 3 / 2
{
return false;
}
Because of this code segment when the number is divisible by value of j without any remainders function will return FALSE.
Simply when your if condition is true function returns FALSE. If method never comes to the inside of if condition then it returns TRUE
The function will return only once in execution: and are exit to the called function when return is executed
Logic is that :
a prime number is A prime number can be divided, without a remainder, only by itself and by 1:
so when i % j == 0 is true means that j is a factor of i hence it is not a prime so return false and exit the function
I'm working on a Sudoku solver, and my program is having trouble recursing backwards when it has exhausted its outputs.
I have four functions that do the check:
scolumn, srow, sbox. Each one will return false if the number already exists in the column row or box respectively.
bool sudoku::solve(int row, int column)
{
if(column == 9)
{
column = 0;
row +=1;
}
if(puzzle[row][column] != 0)
{
solve(row, column + 1);
return false;
}
else
{
for(int n = 0; n < 10; n ++)
{
if(srow(column, n) && scolumn(row,n) && sbox(row, column, n)
{
puzzle[row][column] = n;
if(!solve(row, column + 1);
table[row][column] = 0;
}
}
puzzle[row][column] = 0;// if not commented out then infinite loop
}
return false
}
the problem with it is that if its at 9 and there is no next choice, it will not backtrack correctly.
There are a number of problems with your code, as people have observed in the comments.
This answer summarises some of them:
1) As #n.m. said, you should not be trying '0' as a valid choice in a cell. That will be the cause of some infinite looping, no doubt.
2) As you have observed, you don't know how the recursion finishes. The answer is that when you get to the last cell, and you find a value that works in it, you are supposed to return true. This is what is supposed to break the for(n) loop: that loop is saying "try each number until the call of solve to the right of this cell succeeds'. Success is measured by your routine returning true.
Since you try every number (n) in the current cell, no matter whether or not the call to the solve on its right works ... it's not going to work.
You'll know that you're more on the right track when:
You can see the place in your code where you return true when you discover that you can put a number in the last cell (9,9)
You can see how it is that you stop trying numbers (n=0..9) when the call to the right succeeds.
Given int puzzle[9][9], and your srow, scol, and sbox functions:
bool sudoku::solve(int row, int column) //to solve entire puzzle, call with parameters 0 and 0
{
int cell;
//ignore all nonzero cells (zero = empty)
while (row < 9 && puzzle[row][column] != 0)
{
column++;
if (column == 9)
{
row++;
column = 0;
}
}
if (row == 9) return true; //puzzle is already solved
//try values 1-9 inclusive. If successful, then return true
for (cell = 1; cell <= 9; cell++)
{
puzzle[row][column] = cell;
if (srow(row) &&
scol(column) &&
sbox(row-row%3, column-column%3) &&
solve(row, column)) //recursion!!
{
return true;
}
}
//if no value works, reset the cell and return false.
puzzle[row][column] = 0;
return false;
}