-4

Note: I can't use maps or anything in the algorithm library

I only have the main function, but am completely lost on how I'm supposed to write the function

#include <string>
#include <iostream>


using namespace std;


int* count(const string& s);

int main() {

    string userinput = "random word";

    int *counts = count(userinput);

    for (int i = 0; i < 11; i++) {
        cout << "Letter " << i << " occured " << counts[i] << " times.";
    }




    system("pause");

    return 0;
}



int* count(const string& s) {

    for (int i = 0; i < 11; i++)
    {
        return s[i];
    }
}

The int* count function is not correct and will not compile. How can I write a function that will work in returning the occurences?

JeJo
  • 30,635
  • 6
  • 49
  • 88
  • It's supposed to return the occurrences of the letters in the string – swagalistic May 14 '18 at 04:39
  • Recommend getting a [good book](https://stackoverflow.com/q/388242/9254539). Using dynamic arrays and pointers doesn't look like good teaching to me. – eesiraed May 14 '18 at 04:43
  • Unfortunately I have to use it. I know how to do it with the map and algorithm library but I'm supposed to use dynamic arrays and pointers – swagalistic May 14 '18 at 04:57

2 Answers2

0

How do I count the occurences of each digit in a string using int* count (const string& s) in c++? Note: I can't use maps or anything in the algorithm library

A few things to note:

  1. Always bad idea, if we don't follow the simplest way of approaching a problem and it's sad that teachers are the promoters of such situations.

  2. There is not need of a int*. which does not provide your solution at any manner. If it would have been array to count the chars of your string, then it might make sense(i.e, pointer to the array).

  3. Try to avoid practicing with using namespace std;

You can do something like as follows, if you are not allowed to use std::map<char, int>(hint for your alternative solution).

I have commented on it, for better understanding.

#include <string>
#include <iostream>
#include <cstddef>

// consider 128 ASCII decimal and their coresponding character codes
int charASCIIArray[128] = {0};

void count_char(const std::string& s)
{
   for(const auto& it: s)
   {
        if(('A' <= it && it <= 'Z') ||     // if char between (A,B,....,Z) or
           ('a' <= it && it <= 'z') )      //         between (a,b,....,z)
           charASCIIArray[static_cast<int>(it)]++; // we count each corresponding array then
   }
}

int main()
{
   std::string userinput = "random words WITH *- aLl";

   count_char(userinput);
   for(std::size_t index = 0; index < 128; ++index)
      if(charASCIIArray[index] != 0)
        std::cout << "Letter " << static_cast<char>(index)  // convert back to char
                  << " occured " << charASCIIArray[index] << " times.\n";

   return 0;
}

See live action here: https://www.ideone.com/uFG2HJ

Letter H occured 1 times.
Letter I occured 1 times.
Letter L occured 1 times.
Letter T occured 1 times.
Letter W occured 1 times.
Letter a occured 2 times.
Letter d occured 2 times.
Letter l occured 1 times.
Letter m occured 1 times.
Letter n occured 1 times.
Letter o occured 2 times.
Letter r occured 2 times.
Letter s occured 1 times.
Letter w occured 1 times.

UPDATE

Inspired from @Fei Xiang's comment, here is two over engineered solutions:

Firstly, with returning pointer to a dynamic array(which will meet actual question requirements): https://www.ideone.com/ouHqK4

#include <string>
#include <iostream>
#include <cstddef>

int* count_char(const std::string& s)
{
    // consider 128 ASCII decimal and their coresponding character codes
    int *charASCIIArray = new int[128]{0};
    for(const auto& it: s)
    {
        if(('A' <= it && it <= 'Z') ||     // if char between (A,B,....,Z) or
           ('a' <= it && it <= 'z') )      //         between (a,b,....,z)
           charASCIIArray[static_cast<int>(it)]++; // we count each corresponding array then
    }
    return charASCIIArray;
}

int main()
{
    std::string userinput = "random words WITH *- aLl";

    int *charASCIIArray = count_char(userinput);
    for(std::size_t index = 0; index < 128; ++index)
        if(charASCIIArray[index] != 0)
        std::cout << "Letter " << static_cast<char>(index)  // convert back to char
                  << " occured " << charASCIIArray[index] << " times.\n";

    delete[] charASCIIArray;
    return 0;
}

Secondly with smart pointer(std::unique_ptr) : https://www.ideone.com/dfc62J

#include <string>
#include <iostream>
#include <cstddef>
#include <memory>
#include <utility>

std::unique_ptr<int[]> count_char(const std::string& s)
{
    // consider 128 ASCII decimal and their coresponding character codes
    std::unique_ptr<int[]> charASCIIArray = std::unique_ptr<int[]>(new int[128]{0});
    for (const auto& it : s)
    {
        if (('A' <= it && it <= 'Z') ||     // if char between (A,B,....,Z) or
            ('a' <= it && it <= 'z'))       //         between (a,b,....,z)
            charASCIIArray[static_cast<int>(it)]++; // we count each corresponding array then
    }
    return std::move(charASCIIArray);
}

int main()
{
    std::string userinput = "random words WITH *- aLl";

    std::unique_ptr<int[]> charASCIIArray = count_char(userinput);
    for (std::size_t index = 0; index < 128; ++index)
        if (charASCIIArray[index] != 0)
            std::cout << "Letter " << static_cast<char>(index)  // convert back to char
            << " occured " << charASCIIArray[index] << " times.\n";

    return 0;
}
JeJo
  • 30,635
  • 6
  • 49
  • 88
  • Thank you so much, it works, but is there a way I can use arrays? – swagalistic May 14 '18 at 06:20
  • @swagalistic: isn't int charASCIIArray[128] = {0}; an array? or what you mean? – JeJo May 14 '18 at 06:30
  • Using the int* count(const string& s) function – swagalistic May 14 '18 at 08:27
  • @swagalistic No. Its not possible for the function signature you mentioned above. Just imagine this: you have only a string passing to the function and you need to return a array pointer; that means you are planning to create a so called array inside your count function. Once you will be out of your function scope, what is the validity of your pointer? it will be dangling. in short, what you returning is a pointer to nowhere. This question is not a good example to try your function signature. However, if you play around with list and all you might need something like this. – JeJo May 14 '18 at 08:38
  • This function returns the counts as an array of 10 elements. For example, after invoking int counts[] = count("2312ABcaB2") counts[0] is 0, counts[1] is 1, and counts[2] is 3, etc. – swagalistic May 14 '18 at 09:31
  • here you can create an array inside the function and return it to main(). Then the return must be an array in the function signature. – JeJo May 14 '18 at 09:40
  • 1
    @SaufenmitProgramming You could return a pointer to a dynamic array, but that is bad practice anyway, just like global arrays (sucks when you have terrible teachers). It's also bad practice to use magic numbers like 65 and 90 which are meaningless without an ASCII chart handy all the time. Use the character literals instead such as `'A'`, or even better, the [`isalpha()` function](http://en.cppreference.com/w/cpp/string/byte/isalpha). There is also no point in making a 128 element array (or explicitly initializing it to 0) when most of the elements are unused. – eesiraed May 14 '18 at 23:39
  • `size_t` is in the `std` namespace, so it should be `std::size_t`. – eesiraed May 15 '18 at 00:17
  • @FeiXiang: Thanks for pointing out my mistakes in using ASCII numbers directly and not using `std` namespace for `size_t`. However, not mentioning a dynamic array was intentional, because there he only had alphabets to count(which is in total 52 maximum in array size) and this problem can be approached with stack memory. I have updated with some new solutions anyways. – JeJo May 15 '18 at 08:46
  • @FeiXiang regarding 128 elements array; I could only think of like this, so that the code would be much readable. we might able to create an 52 sized array, but incrementing each chars count might make the code a bit not-easy-readable(in my opinion). If you have better ideas, most welcome and once again thanks for reviewing my solution and pointing out the drawbacks. – JeJo May 15 '18 at 08:51
0

Not so sure you wanted this answer but I hope it helps you can seperate it into seperate function but I did it in a single go

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string userInput = "random word";
    int fCharacter[256];


    for (int i = 0; i <= 255; i++)
    {
        fCharacter[i] = 0;
    }

    for (int i = 0; i < userInput.length(); i++)
    {
        fCharacter[userInput[i]]++;
    }
    cout << "The character changes are as follows" << endl;
    for (int i = 0; i <= 255; i++)
    {
        if (fCharacter[i] != 0)
        {
            cout << (char)i << endl; 
        }
    }

    system("pause");
    return 0;
}