问题
I am trying to make a program generating random numbers until it finds a predefined set of numbers (eg. if I had a set of my 5 favourite numbers, how many times would I need to play for the computer to randomly find the same numbers). I have written a simple program but don't understand the outcome which seems to be slightly unrelated to what I expected, for example the outcome does not necessarily contain all of the predefined numbers sometimes it does (and even that doesn't stop the loop from running). I think that the problem lies in the logical operator '&&' but am not sure. Here is the code:
const int one = 1;
const int two = 2;
const int three = 3;
using namespace std;
int main()
{
int first, second, third;
int i = 0;
time_t seconds;
time(&seconds);
srand ((unsigned int) seconds);
do
{
first = rand() % 10 + 1;
second = rand() % 10 + 1;
third = rand() % 10 + 1;
i++;
cout << first<<","<<second<<","<<third<< endl;
cout <<i<<endl;
} while (first != one && second != two && third != three);
return 0;
}
and here is out of the possible outcomes:
3,10,4
1 // itineration variable
7,10,4
2
4,4,6
3
3,5,6
4
7,1,8
5
5,4,2
6
2,5,7
7
2,4,7
8
8,4,9
9
7,4,4
10
8,6,5
11
3,2,7
12
I have also noticed that If I use the || operator instead of && the loop will execute until it finds the exact numbers respecting the order in which the variables were set (here: 1,2,3). This is better however what shall I do make the loop stop even if the order is not the same, only the numbers? Thanks for your answers and help.
回答1:
The issue is here in your condition:
} while (first != one && second != two && third != three);
You continue while none of them is equal. But once at least one of them is equal, you stop/leave the loop.
To fix this, use logical or (||
) rather than a logical and (&&
) to link the tests:
} while (first != one || second != two || third != three);
Now it will continue as long as any of them doesn't match.
Edit - for a more advanced comparison:
I'll be using a simple macro to make it easier to read:
#define isoneof(x,a,b,c) ((x) == (a) || (x) == (b) || (x) == (c))
Note that there are different approaches you could use.
} while(!isoneof(first, one, two, three) || !isoneof(second, one, two, three) || !isoneof(third, one, two, three))
回答2:
You have a mistake in your logical condition: it means "while all numbers are not equal". To break this condition, it is enough for one pair to become equal.
You needed to construct a different condition - either put "not" in front of it
!(first==one && second==two && third==three)
or convert using De Morgan's law:
first!=one || second!=two || third!=three
来源:https://stackoverflow.com/questions/12157137/c-random-numbers-logical-operator-wierd-outcome