3

I'm trying to count the cats and dogs in a string. So,

for example:

if the string is "cc+dd-cd",:

I want to count 2 positive cats, 2 positive dogs, 1 negative cat, 1 negative dog (yes I know this is a weird way to count, but it's part of my assignment).

I thought about doing a for loop where I iterated over the string, then nested inside the for loop, I'd have a while loop that would run until a '-', then run until a '+' or the end. I started the code, and without even getting that far into it, it created an infinite loop.

Question: How can I fix it?

Thanks!

string animalparkString = "cc+dd-cd" 
for (int k = 0; k != animalparkString.size(); k++)
   {
       while (k != '-'){
           pdc = pdc + 1; //positive dog count
           pcc = pcc + 1; //positive cat count
       }
       while (k != '+') {
           ndc = ndc + 1;
           ncc = ncc + 1;
       }
       
   }

Community
  • 1
  • 1
  • 1
    Those `while` loops don't do anything with `k`, so if the condition is `true` the first time, it will always be `true`. Besides, the condition doesn't make much sense anyway, instead of checking chars againt `k`, you should check them against `animalparkString[k]`. – Blaze Jan 30 '20 at 08:39
  • 1
    For starters, `k` is an index, so to compare with `'-'` or `'+'` you should be using `animalparkString[k]`. – acraig5075 Jan 30 '20 at 08:42
  • don't forget to check K in the will loop as well, the answer by @Blaze is correct and add checks – alon Jan 30 '20 at 08:47

4 Answers4

4

The immediate issue is that the while loops check k's value, but don't modify it. So once you entered one of them you'll be stuck there infinitely as k doesn't change inside the loop's body.

I wouldn't bother with nested loops - I'd just go over the entire string in one loop, and evaluate each character in its turn. A neat way to accomplish this is to keep a state of whether you're adding or subtracting (according to whether you last encountered a + or a - sign:

bool positive = true;
string animalparkString = "cc+dd-cd";
for (int k = 0; k < animalparkString.size(); k++) {
     char ch = animalparkString[k];

     switch (ch) {
         case '+':
             positive = true;
             break;
         case '-':
             positive = false;
             break;
         case 'c':
             if (positive) {
                 pcc++;
             } else {
                 ncc++
             }
             break;
         case 'd':
             if (positive) {
                 pdc++;
             } else {
                 ndc++
             }
             break;
     }
}
Mureinik
  • 297,002
  • 52
  • 306
  • 350
1

This post describes iterating all characters is a string.

This is a simple solution using modern C++:

int sign = 1; 
int dogs_count = 0, cats_count = 0;  
std::string animalparkString = "-cccccc+dddd-cd"; 
for (const char& ch : animalparkString)
{
     switch (ch) {
         case '+':
             sign = 1;
             continue;
         case '-':
             sign = -1;
             continue;
         case 'c':
             cats_count += sign;
             continue;
         case 'd':
             dogs_count += sign;
             continue;
     } 
}

std::cout <<"dogs: " << dogs_count << " cats: " <<cats_count;  

A couple of suggestions to help you get started:
1. Use online c++ compilers to quickly test code
2. If your code doesn't behave as expected, use step-by-step debugging in your IDE or print our variables as you go using std::cout
3. Explicitly stating namespace is considered good practice. i.e:

// preferable:  
std::string myString; 
// avoid:  
using namespace std;  
string myString   
Eyal D
  • 169
  • 1
  • 15
0

To make your code work without too many changes , you can simply replace the while() condition with an if(). Moreover, instead of checking the iterator value k, you should compare the kth string element animalparkString[k].

Then you might start wondering if the code you wrote is actually doing what you expect. Possible questions you could try to answer is "how do I distinguish between positive or negative counts" and, then, "how do I distinguish between cats and dogs "? You will probably need to check also for cs and ds, not only for the operation sign!

string animalparkString = "cc+dd-cd" 
for (int k = 0; k != animalparkString.size(); k++)
   {
       if(animalparkStrink[k] != '-'){
           // Now you know, there will be a pos count. Dog or Cat?
       }
       if(animalparkString[k] != '+') {
          // Now you know, there will be a neg count. Dog or Cat?
       }

   }

Note that if you write while( k != '-'), it will always evaluate true and, therefore, you will be stuck there. If it is the first time working with for-loops, consider printing the iterator value, to understand when and where you are stuck.

string animalparkString = "cc+dd-cd" 
for (int k = 0; k != animalparkString.size(); k++)
   {

       std::cout << "for-loop iteration number: " << k << std::endl;

       if(animalparkStrink[k] != '-'){
           // Now you know, there will be a pos count. Dog or Cat?
       }
       if(animalparkString[k] != '+') {
          // Now you know, there will be a neg count. Dog or Cat?
       }

   }
tip
  • 11
  • 3
0

for and while together approach is unnecessarily complicated. Here's a simpler solution:

#include <concepts>
#include <iostream>

int main() {
  auto const& str{"cc+dd-cd"};
  std::boolean auto isPositive = 1;
  std::integral auto pdc{0}, pcc{0}, ndc{0}, ncc{0};
  for (char const ch : str) {
    switch (ch) {
      case 'c': {
        pcc += isPositive;
        ncc += !isPositive;
        break;
      }
      case 'd': {
        pdc += isPositive;
        ndc += !isPositive;
        break;
      }
      case '+': {
        isPositive = true;
        break;
      }
      case '-': {
        isPositive = false;
        break;
      }
    }
  }

  std::cout << "pcc: " << pcc << '\n'
            << "ncc: " << ncc << '\n'
            << "pdc: " << pdc << '\n'
            << "ndc: " << ndc << '\n';
}

LIVE

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93