comparing two integers arrays in c++ string printing - c++

I am trying to compare two arrays.where if it is true it needs to print the string.since it need to print only one time but the string is printing three times .where i have stored three values in both arrays.can you guys spot and tell me what is wrong.
for (int i = 0; i < n; i++)
{
if (l[i] == g[i])
{
cout << "equal" << endl;
}
else if (l[i] < g[i])
{
cout << "lesser" << endl;
}
else if (l[i] > g[i])
{
cout << "greater" << endl;
}
}

I'm guessing that you're trying to do a lexicographic comparison.
It should be obvious that if you want to print the message only once then you shouldn't put the print statements inside the loop.
The following code works how I think you want your code to work. The result of the comparison is stored in a variable result and that variable is examined only after the loop has finished. I use break because once you have found an item that is not equal there is no need to carry on the comparison.
int result = 0;
for (int i = 0; i < n; i++)
{
if (l[i] < g[i])
{
result = -1;
break;
}
else if (l[i] > g[i])
{
result = +1;
break;
}
}
if (result == 0)
cout << "equal" << endl;
else if (result < 0)
cout << "lesser" << endl;
else
cout << "greater" << endl;

You could simplify:
for (int i = 0; i < n; ++i)
{
const int l_value = l[i];
const int g_value = g[i];
if (l_value == g_value)
{
cout << "slot[" << i << "] is equal\n";
}
else
{
if (l_value < g_value)
{
cout << "slot[" << i << "] is less than\n";
}
else
{
cout << "slot[" << i << "] is greater than\n";
}
}
}
In order compare the entire array, you'll need to sort it first. The "less than" and "greater than" apply to a sorted array.

Related

for loop with nested if statement stops iterating after first iteration becomes true. C++

I have a function that receives a character "x" from a user. If the "x" exists in a hard-coded array, "x" is pushed into another array filled with lowdashes in the same position as in the first array. Fo example:
firstArray = ["h", "e", "l", "l","o"]
//user provided character that exist in first array. "e"
lowDashesArray= ["_", "e", "l", "l", "o"]
Then, I want to check if both arrays are equal, my problem is that when the user guesses the firts element in the array (in the above example "h"), the for loop stops iteraring without checking if the other elements are equal. As a result, the block of code that expects both arrays to be equal is executed.
The function looks like so:
bool checkIfLetterExistOnWord(string word, char letter, char* lettersArray, char* lowDashesArray, bool hasWon, bool hasLost, int lives){
bool isCorrectLetter = false;
for(int i = 0; i<word.length(); i++ ){
if(letter == lettersArray[i]){
int position = i;
lowDashesArray[position] = letter;
cout << lowDashesArray;
cout << endl;
isCorrectLetter = true;
}
}
if(isCorrectLetter){
for(int j = 0; j < word.length(); j++){
if(lettersArray[j] == lowDashesArray[j]){
hasWon = true;
//here is the problem. But only when user guesses the first element of the array
}
else{
break;
}
}
if(hasWon){
cout << "You have won";
cout << endl;
cout << hasWon;
cout << endl;
cout << lowDashesArray;
cout << endl;
cout << word;
cout << endl;
return hasWon;
}
else{
cout << "good job. Guess the next letter";
cout << endl;
return hasWon;
}
}
else{
cout << "wrong";
cout << endl;
lives--;
if(lives == 0){
hasLost = true;
cout << "You lost";
return hasLost;
}
else {
cout << "You still have this lives :";
cout << endl;
cout << lives;
cout << endl;
return hasLost;
}
}
}
Both your loop logic is incorrect.
bool isCorrectLetter = false;
for(int i = 0; i<word.length(); i++ ){
if(letter == lettersArray[i]){
int position = i;
lowDashesArray[position] = letter;
cout << lowDashesArray;
cout << endl;
isCorrectLetter = true;
}
}
Here you print the array once for every occurance of the guess character. FUrthermore you do not check, if the letter "was already uncovered". You need to do the printing after the loop and depending on whether you want guessing uncovered chars to be an error, you may need to ajust the check.
for(int j = 0; j < word.length(); j++){
if(lettersArray[j] == lowDashesArray[j]){
hasWon = true;
//here is the problem. But only when user guesses the first element of the array
}
else{
break;
}
}
You're trying to check here, if every char meets a certain criterion (being a non placeholder char). In this case you cannot break early. In general the loop for this kind of check needs to look like this:
bool checkSuccess = true;
for (size_t i = 0; checkSuccess && i != length; ++i)
{
if (!Check(elements[i]))
{
checkSuccess = false;
}
}
Or in your case (using break instead):
hasWon = true;
for(int j = 0; j < word.length(); j++)
{
if(lettersArray[j] != lowDashesArray[j])
{
hasWon = false;
break;
}
}
Imho it's preferrable to separate the replacement logic from io logic. You could e.g. rewrite the logic similar to this:
constexpr char MaskChar = '_';
/**
* Replaces placeholders in \p maskedText, if they the corresponding char in \p clearText
* matches \p guess.
*
* \param[in,out] maskedText the text with some chars replaced with '_'
*
* \return true, if at least one char was replaced, false otherwise
*/
bool GuessChar(std::string const& clearText, std::string& maskedText, char const guess)
{
assert(clearText.length() == maskedText.length());
bool guessCorrect = false;
for (size_t i = 0; i != clearText.length(); ++i)
{
if (maskedText[i] == MaskChar && clearText[i] == guess)
{
guessCorrect = true;
maskedText[i] = guess;
}
}
return guessCorrect;
}
int main()
{
std::string const clearText = "hello";
std::string maskedText(clearText.length(), MaskChar);
size_t lives = 3;
while (lives > 0 && maskedText.find(MaskChar) != std::string::npos)
{
std::cout << "Word: " << maskedText
<< "\nMake your guess!\n";
char c;
std::cin >> c;
if (GuessChar(clearText, maskedText, c))
{
std::cout << "Guess correct!\n";
}
else
{
--lives;
std::cout << "Guess incorrect\n"
<< lives << " lives left\n";
}
}
if (lives > 0)
{
std::cout << "You win!\n";
}
else
{
std::cout << "You loose!\n";
}
}

How to print a message one time after all the iterations in the loop "for" are done?

My program analyzes the array in the loop "for". If all elements satisfy the condition, it should print a message one time, but my program does it after each iteration.
Here's my code:
#include <iostream>
using namespace std;
int main()
{
const int size = 32;
int ARR[size];
cout << "The size of the set is " << size << " elements." << endl << endl;
cout << "Enter the elements of the set: ";
for (int i = 0; i < size; i++)
{
cin >> ARR[i];
}
for (int i = 0; i < size; i++)
{
if (ARR[i] > ARR[i])
cout << "\nThe relation is reflexive." << endl;
else
cout << "\nThe relation is not reflexive." << endl;
}
return 0;
}
I need that message to be printed after all the iterations are done. How can I achieve that result?
It's pretty easy, just use a boolean flag to determine if the condition is met:
bool isReflexive = true;
for (int i = 0; i < size; i++) {
if (ARR[i] <= ARR[i]) {
isReflexive = false;
break;
}
}
if(isReflexive)
cout << "\nThe relation is reflexive." << endl;
else
cout << "\nThe relation is not reflexive." << endl;
Note: The code above will always set isReflexive to false. You also need to compare two different indices:
for (int i = 1; i < size; i++) {
if (ARR[i-1] <= ARR[i]) { // Or whatever the correct comparison is
isReflexive = false;
break;
}
}
I would suggest to separate analysis of "reflexiveness" from printing the result. That would allow you to simply end the loop as soon as negative result is determined:
#include <iostream>
using namespace std;
bool IsReflexive(int a[], int size)
{
for (int i = 0; i < size; i++)
{
if (a[i] > a[i]) // TODO: correct this!!!
return false;
}
return true;
}
int main()
{
const int size = 32;
int ARR[size];
cout << "The size of the set is " << size << " elements." << endl << endl;
cout << "Enter the elements of the set: ";
for (int i = 0; i < size; i++)
{
cin >> ARR[i];
}
if (IsReflexive(ARR, size))
cout << "\nThe relation is reflexive." << endl;
else
cout << "\nThe relation is not reflexive." << endl;
return 0;
}

How to print a message only once in a loop

I am using for loops combined with if statements to read integers from a text file into a two-dimensional array.
This is my code:
for (int i = 0; i < MAX_ROWS;i++) {
for (int j = 0; j < MAX_COLUMNS; j++) {
inFile >> ArrB[i][j];
if (ArrB[i][j] == -1) {
bad = true;
cout << "The array does not have enough integers" << endl;
break;
}
else {
if (ArrB[i][j] < 1) {
invalidnum = true;
}
}
if (invalidnum = true) {
cout << *(*(ArrB + i) + j) << " ";
cout << "There is/are negative number(s) or zero(s) in the array imported from your text file." << endl;
}
}
}
This code will read in the first 6 integers (max_row * max_column) from a text file into ArrB.
If -1 exists in the first 6 integers, it will exit the loop and print out "The array does not have enough integers".
If there is no -1 in the first 6 integers, then it will check all 6 integers to see if there are any other negative numbers or zero.
If there are negative numbers or zero, I want it to still print out the array, then print out the error message (There is/are negative number(s) or zero(s) in the array imported from your text file) ONLY ONCE.
For example, this is my text file. As you can see, there is no -1 in the first 6 numbers, but there is a -7.
So, ideally, the result should be something like:
2 4 5 6 9 -7
There is/are negative number(s) or zero(s) in the array imported from your text file
But this is what I am getting if I run my code above:
-------------------------------------UPDATE--------------------------------------
Figured it out based on #ZedLepplin 's comment
Here is the code:
for (int i = 0; i < MAX_ROWS;i++) {
for (int j = 0; j < MAX_COLUMNS; j++) {
inFile >> ArrB[i][j];
if (ArrB[i][j] == -1) {
bad = true;
cout << "The array does not have enough integers" << endl;
break;
}
else {
if (ArrB[i][j] < 1) {
invalidnum = true;
}
}
cout << *(*(ArrB + i) + j) << " ";
}
}
if (invalidnum == true) {
cout << "There is/are negative number(s) or zero(s) in the array imported from your text file." << endl;
}
You could just set a counter, and put the message outside of the loop.
Something like :
int counter = 0;
for(int i = 0; i < MAX_ROWS ; i++) {
if(myVector[i] == -1) {
counter++;
}
else {
// Do normal stuff
}
}
if(counter > 0) {
cout << "The array contained " << counter << "negative values" << endl;
}
Ho, and I'd advise to avoid comparisons to "true". If myVar is a boolean alrady, I can just do if(myVar). No need to do if(myVar == true).
And doing if(myVar = true) is worse, as it sets myVar to true, regardless of its initial value. That's a common typo that can be hard to detect when proofreading code.
Edited version (to adapt to comments) :
bool earlyNegativeOneFound = false;
int otherNegativeCounter;
for(int i = 0; i < MAX_ROWS ; i++) {
if(i < 6 && myVector[i] == -1) {
earlyNegativeOneFound = true;
break;
}
else if(myVector[i] < 0) {
cout << myVector[i] << endl;
otherNegativeCounter++;
}
else {
// Do normal stuff
}
}
if(!earlyNegativeOneFound && otherNegativeCounter> 0) {
cout << "The array contained " << otherNegativeCounter << "negative values" << endl;
}
Put the conditional error message print after your for loop. Leave the cout for displaying the array number inside the for loop so it is output for every iteration of the loop.
for (int i = 0; i<MAX_ROWS;i++) {
for (int j = 0; j<MAX_COLUMNS; j++) {
inFile >> ArrB[i][j];
if (ArrB[i][j] == -1) {
bad = true;
cout << "The array does not have enough integers" << endl;
break;
}
else {
if (ArrB[i][j] < 1) {
invalidnum = true;
}
}
cout << * (*(ArrB + i) + j) << " ";
}
}
if (invalidnum = true) {
cout << "There is/are negative number(s) or zero(s) in the array imported from your text file." << endl;
}
I am not sure if this is what you meant
for (int i = 0; i < MAX_ROWS;i++) {
for (int j = 0; j < MAX_COLUMNS; j++) {
flag log = false;
inFile >> ArrB[i][j];
if (ArrB[i][j] == -1) {
bad = true;
cout << "The array does not have enough integers" << endl;
break;
}
else {
if (ArrB[i][j] < 1) {
invalidnum = true;
}
}
if (invalidnum = true) {
cout << *(*(ArrB + i) + j) << " ";
if(!flag)
{
cout << "There is/are negative number(s) or zero(s) in the array
imported from your text file." << endl;
flag = true;
}
}
}
}
Adding the flag boolean variable would allow the statement "there are negative numbers.." to be printed once.
Just store the message and print it where and when you want. Some psuedo-code:
std::string message;
for (int i = 0; i < N; ++i)
{
for (int j = 0; j< M; ++j)
{
if (smth)
{
message {"Your message"};
break; // note that after break,
// you are still in the outer loop
}
else if (smth else)
{
message {"Your message"};
}
}
// print it here
}
// or here, or wherever you want to

C++ Lines not executing after a for loop. Loop not infinite

Most of the answers I'm coming across boil down to in infinite loop, but I've inserted some cout statements for diagnostic purposes and I'm thoroughly convinced this is not the case- it looks like the nested for loop finishes but simply skips over some lines before returning to the top of the outside for loop. The only time something gets pushed back is on the first iteration when the for nested loop is skipped completely. As is, the debugger gives an out of range vector fault, I assume because new unique items aren't being pushed back. Any ideas how to get around this?
Template <class T>
void count_unique(string filename, vector<T> input) {
vector<T> unique;
vector<int> count;
bool found = false;
ifstream fin;
fin.open(filename);
T line;
while (!fin.eof()) {
fin >> line;
input.push_back(line);
}
fin.close();
cout << input.size() << endl;
for (unsigned int i = 0; i < input.size(); i++) {
cout << input.at(i) << endl;
}
for (unsigned int i = 0; i < input.size(); i++) {
cout << input.at(i) << endl;
found = false;
for (unsigned int j = 0; j < unique.size(); i++) {
cout << unique.at(j) << "\t=\t" << input.at(i) << " ->" << unique.size() << endl;
if (input.at(i) == unique.at(j)) {
count.at(j)++;
found = true;
cout << "Incremented" << endl;
}
else {
cout << "None;" << endl;
}
}
cout << "Found=" << found << endl;
if (!found) {
unique.push_back(input.at(i));
count.push_back(1);
found = false;
cout << "Pushed back" << endl;
cout << "#";
for (unsigned int i = 0; i < unique.size(); i++) {
cout << unique.at(i) << "\t-\t" << count.at(i) << endl;
}
cout << "#" << endl;
}
}
for (unsigned int i = 0; i < unique.size(); i++) {
cout << "\t" << unique.at(i) << "\t=\t" << count.at(i) << endl;
}
}
Your inner loop incremements the wrong variable. It is actually an infinite loop, since j will never change. This is also why you get the out of range, i will continuously increase, beyond the size of input
//...
for (unsigned int i = 0; i < input.size(); i++) {
cout << input.at(i) << endl;
found = false;
for (unsigned int j = 0; j < unique.size(); j++) { // HERE

How to push_back something into a 2D Vector

I'm trying to code a Tic-Tac-Toe game and can't figure out how to push_back a '+' char whenever it's my turn.
So whenever a player types for example "Oben links" which basically means Top left I want the game to check for the correct input and place a '+' at the position the player picked. What I am doing though does not seem to work. Either it's not saving it or I'm using the wrong syntax.
int main() {
vector < vector <char> > spielbrett(3, vector<char>('3'));
bool gewonnen = true;
string feld;
while (gewonnen) {
cout << "Position waehlen, z. B. Oben links oder Mitte Mitte usw. " << endl;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << spielbrett[i][j] << " ";
if (j < 2) {
cout << " | ";
}
}
if (i < 2) {
cout << endl << " ------------ " << endl;
}
}
cout << endl << endl << endl;
cin >> feld;
if (feld == "Oben links") {
spielbrett[0].push_back('+');
}
else if (feld == "Oben mittig") {
}
else if (feld == "Oben rechts") {
}
else if (feld == "Mitte links") {
}
else if (feld == "Mitte mittig") {
}
else if (feld == "Mittig rechts") {
}
else if (feld == "Unten links") {
}
else if (feld == "Unten mittig") {
}
else if (feld == "Unten rechts") {
}
}
system("pause");
}
You do not want to use push_back here. Since the vector is already 3x3 thanks to
vector < vector <char> > spielbrett(3, vector<char>('3'));
All you need to do is access the positions directly. So if you want the top left corner then you want
spielbrett[0][0] = '+';
The bottom right would be
spielbrett[2][2] = '+';