I am looping i, j, k and n. I want a statement to execute except when k == j and n == k.
If I use the code like this:
if (k != j && n != i)
//statement
The statement will not execute in two cases:
When k != j when n == j.
When k == j when n != j. (which is not what I need)
So I used a code like this:
if (k == j && n == i)
;else
//statement
By this code the statement will successfully execute except when k == j && n == i.
Is semicolon-terminated if-statements is a good way of coding in C++?
No it's not a good way of coding. The usual way is to use ! to invert the logic:
if(!(k==j && n==i))
//statement
Or you could use De Morgan's Law to invert the logic:
if(k!=j || n!=i)
//statement
Your problem is that you're negating the condition incorrectly. You should just do:
if (!(k==j && n==i))
// statement
Or, by De Morgan's laws:
if (k != j || n != i)
// statement
... is a good way of coding?
No.
You should write
if (!(k == j && n == 1))
{
//statement
}
Putting a semicolon after an if, for, or while is almost always wrong. It is highly unexpected and makes reading your code very difficult.
Related
How to invoke lemma as the reasoning for equality to be true. Consider the following example in dafny where I've created a lemma to say that the sum from 0 to n is n choose 2. Dafny seems to have no problem justifying this lemma. I want to use that lemma to say that the number of swaps in bubblesort has an upper bound of the sum from 0 to n which is equivalent to n choose 2. That being the case, I currently have an error when I try to say it's true by the lemma. Why is this happening and how can I say that equality is true given a lemma?
method BubbleSort(a: array?<int>) returns (n: nat)
modifies a
requires a != null
ensures n <= (a.Length * (a.Length - 1))/2
{
var i := a.Length - 1;
n := 0;
while (i > 0)
invariant 0 <= i < a.Length
{
var j := 0;
while (j < i)
invariant j <= i
invariant n <= SumRange(i, a.Length)
{
if(a[j] > a[j+1])
{
a[j], a[j+1] := a[j+1], a[j];
n := n + 1;
}
j := j + 1;
}
i := i -1;
}
assert n <= SumRange(i, a.Length) == (a.Length * (a.Length - 1))/2 by {SumRangeNChoose2(a.Length)};
assert n <= (a.Length * (a.Length - 1))/2
}
function SumRange(lo: int, hi: int): int
decreases hi - lo
{
if lo == hi then hi
else if lo >= hi then 0
else SumRange(lo, hi - 1) + hi
}
lemma SumRangeNChoose2(n: nat)
ensures SumRange(0, n) == (n * (n - 1))/2
{}
You just have a syntax error. There should be no semicolon after the } on the second to last line of BubbleSort. Also, there should be a semicolon after the assertion on the following line.
After you fix the syntax errors, there are several deeper errors in the code about missing invariants, etc. But they can all be fixed using the annotations from my answer to your other question.
I was wondering if I am writing correct "isalnum" logic. This program is checking if the string is a palindrome or not and when I input the string "race a car", it keeps saying it is true, i.e. it's a palindrome.
bool isPalindrome(string s) {
for (int i = 0, j = s.size() - 1; i < j; i++, j--) {
while ((s[i] < 'a' || s[i] > 'z') && (i < j) ||
(s[i] < 'A' || s[i] > 'Z') && (i < j) ||
(s[i] < '0' || s[i] > '9') && (i < j))
i++;
while ((s[j] < 'a' || s[j] > 'z') && (i < j) ||
(s[j] < 'A' || s[j] > 'Z') && (i < j) ||
(s[j] < '0' || s[j] > '9') && (i < j))
j--;
if (toupper(s[i]) != toupper(s[j])) return false;
}
return true;
}
No, your logic is not correct, well, at least not for all the character sets that C++ can use. In ASCII, the letters of the alphabet are in contiguous blocks, so something like
(s[i]<'A'||s[i]>'Z')
works just fine. The issue with that is that ASCII isn't the only character set C++ supports. The most common example to counterpoint ASCII is EBCDIC which has the characters {, }, and \ in between A and Z.
One thing that is guaranteed though is that 0 through 9 are contiguous in all character sets that C++ supports so it's always legal to text if a character is a number using
if (char_var >= '0' && char_var <= '9')
Assuming contiguous alphabets (which isn't going to hold in reality), your logic is broken by the fact that you're doing multi-range checking, where disqualification in one range is still qualified in another.
Specifically, this:
while((s[i]<'a'||s[i]>'z')&&(i<j)||(s[i]<'A'||s[i]>'Z')&&(i<j)||(s[i]<'0'||s[i]>'9')&&(i<j))i++;
Now, consider this: suppose a[i] is in 'a'..'z', so the first range check will be false. But, if that's the case then it is NOT in 'A'..'Z' and is certainly not in '0'..'9'. Since both of those tests result in true, the loop advances i and continues on. As your loop is written, so long as the character is not in at least one of those ranges the loop continues. Since the ranges are mutually exclusive, there will ALWAYS be at least one the current character is not within. That OR separating condition is wrong. It shouldn't be not-in one of those ranges; it should be not-in ALL of those ranges. Thus.. AND is appropriate.
Short work with a debugger will tell you the very first pass of your outer-for-loop is advancing i all the way to j. The second loop is skipped because j and i are already equal, and since s[i] == s[j] is definitely true when i == j, the result is true.
Short version: your loop conditions are broken, even on contiguous character sequence platforms.
The loop you're more inclined to succeed with would be something like:
while( (i < j) && (s[i]<'a'|| s[i]>'z') && (s[i]<'A'||s[i]>'Z') && (s[i]<'0'||s[i]>'9') )
i++;
I leave the other loop and consideration for not doing any of this because of encodings where it will not work as an exercise for you.
The model is optimizing the costs of Machines in Cell layout design
regarding the duplication and subcontracting.
Mod Const. is,
forall (k in 1..Cells, i in 1..nbMachines, j in 1..nbComps)
{
if (U[i][j][k] == 1 && A[k][i] < ((D[k][j]*S[k][j])*52))
DN[i][j][k] == 1;
SC[i][j][k] == 0;
INT[i][j][k] == 0;
}
forall (k in 1..Cells, i in 1..nbMachines, j in 1..nbComps)
{
if (V[i][j][k] == 1 && A[k][i] >= ((D[k][j]*S[k][j])*52))
DN[i][j][k] == 0;
SC[i][j][k] == 1;
INT[i][j][k] == 1;}
U , V are extracted in previous steps, A, D, S are input data.
The variables reqd. are DN, SC and INT.
Errors are those expressions are cannot be extracted, U, V are unbounded,
Please help in this regard,
Since U and V are decision variables, you should not write:
if (U[i][j][k] == 1 && A[k][i] < ((D[k][j]*S[k][j])*52))
DN[i][j][k] == 1;
Instead write:
((U[i][j][k] == 1) && (A[k][i] <= -1+((D[k][j]*S[k][j])*52)))
=> (DN[i][j][k] == 1);
Hi guys so I have this code that I need for a project in university.The code I have is recursive and it is taking a lot of time to load.I tried converting it to iterative but I can't seem to do it in order as the output is different.Could you please help me converting it?Thank you.
void getBrewCount(int n, int i, int j){
if( i ==n && j == n){ //reach the (n,n) point
count++;
}else if( i > n || j > n){//wrong way
return;
}else {
if(i==8 && j==5){
j++;
}
if(i==11 && j==5){
j+=2;
}
if(i==15 && j>=14){
i+=2;
}
if(i==21 && j>=22){
i++;
}
getBrewCount(n, i +1, j );
getBrewCount(n, i , j +1);
}
In recursion you have an ending condition. When this condition is met, recursion ends and you "bubble up" from recursion. When you want to do the same iteratively, ending condition of recursion should be condition of your loop. Your recursion ends after it goes out of range. You can write while() loop which will loop until it reaches out of range, therefore while (i < n && j < n) { }. My while loop increments count and breaks itself right when range is achieved. However I do not know what is the real functionality of your function, so you might want to change it a little.
void getBrewCount(int n, int i, int j) {
while (i < n && j < n) {
// my ending condition
if (i == n && j == n) {
++count;
break;
}
/* code that updates i, j e.g.
if (i == 10)
++j;
*/
}
return;
}
I don't know why this code is not breaking out of the while loop:
int table_size = 953;
store hash_table[953];
for(int i = 0; i < table_size; i++)
hash_table[i].count = 0;
//bunch of stuff to get hash value here
while(hash_table[hashNum].data != pString || hash_table[hashNum].count != 0){
hashNum++;
if(hashNum > table_size)
hashNum = 0;
cout << hash_table[hashNum].count;
// to check the value of the count in the array, it IS 0, thus should have broken the loop
}
you probably mean:
while(hash_table[hashNum].data != pString && hash_table[hashNum].count != 0)
In your code the loop will continue if either case is true, hash_table[hashNum].count == 0 is NOT sufficient to make the clause false.
hash_table[hashNum].count being equal to zero is not sufficient to terminate the loop since you are using || ("or") between the two conditions in the termination test. If hash_table[hashNum].data is not equal to pString then the loop will continue regardless of what hash_table[hashNum].count is.
I think your loop condition should be on hashNum != 0 instead of hash_table[hashNum].count != 0.
Secondly, there should be && instead of || in your while condition.
These are wild guesses since a lot of information is missing in this question.
You should have a look at binary logic, especially De Morgan theorem
!(a && b) is equivalent to (!a) || (!b)