C++ HELP in character displaying from a string

hi, Im new here :)
I want to input a string,
say: abcdaa
so, the program should output:
a
b
c
d
In other words, the program will display each character for only ONCE!!!! And display their frequency.

To avoid the issue of "spoonfeeding", although I would highly appreciate if someone gives me a program about my problem (cause Ive been searching for 3 hours! and this is not my assignment, this is not connected to my subjects right now, I just want to make a very small project)

here is my idea:
user will input a string and such string will be copied into another string variable called "checker".
There will be a loop and each character will be printed, BUT, first, the program will check if the character to be printed is not equals to all elements of the checker string.

I already have the function to count the frequency of each character
GOAL: to make a program that will accept a string and use the HUFFMAN CODING to compress it.
please reply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 for(x=0; x<string_in.size(); x++)
   {       
           cout<<"\t\t   "<<string_in[x]<<endl;
           
            for(y=0; y<string_in.size(); y++)
           {
                     if(checker[y]==string_in[x])
                     break;
                     else
                     checker[x]=string_in[x];
                  
                   }
           
           }


I know this is lame. :3 But I really don't have time to think now, there will be alots of quizzes coming this week, and I really want to finish my program.
I would have a class or struct that holds the character and the frequency count. Then store instances of the class in a map using the character value as the key.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <map>

template <typename T, size_t N>
size_t SizeOfArray(const T(&)[N])
{
    return N;
}

class CData
{
public:
    CData(const char _c)
    : c(_c)
    , count(1)
    {}
    
    int count;
    char* print()
    {
        sprintf(output, "char: %c \tCount: %d", c, count);
        return output;
    }
private:
    char c;
    char output[10];
};

int main(int argc, const char * argv[])
{
    typedef std::map<char, CData*> M;
    M m;
    
    // this is our input data:
    const char input[] = {'a', 'b', 'c', 'd', 'a', 'a'};
    
    for (int n = 0; n < SizeOfArray(input); ++n)
    {
        M::iterator itr = m.find(input[n]);
        
        if (itr != m.end())
            itr->second->count++;
        else
        {
            CData* pData = new CData(input[n]);
            m.insert(m.end(), M::value_type(input[n], pData));
        }
    }
    
    // output the results:
    for (M::iterator itr = m.begin(); itr != m.end(); ++itr)
    {
        CData* pData = itr->second;
        if (pData)
        {
            std::cout << pData->print() << std::endl;
            delete pData;
            pData = NULL;
        }
    }
    
    return 0;
}
> I would have a class or struct that holds the character and the frequency count.
> Then store instances of the class in a map using the character value as the key.

I would just have an array of character counts.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <limits>
#include <string>
#include <iostream>

int main()
{
    int cnt[ std::numeric_limits<unsigned char>::max() + 1 ] = { 0 } ;

    const std::string str = "sleeplessness" ;
    for( unsigned char c : str ) ++cnt[c] ;

    std::string checker ;

    for( char c : str )
    {
        unsigned char u = c ;
        if( cnt[u] )
        {
            std::cout << c << ' ' << cnt[u] << '\n' ;
            cnt[u] = 0 ;
            checker += c ;
        }
    }

    std::cout << checker << '\n' ;
}
In your post you are showing the output without corresponding frequencies.

The simplest way is to use standard container std::map

For example

1
2
3
4
std::map<char, unsigned int> m;
for ( char c : string_in ) ++m[c];

for ( auto p : m ) std::cout << p.first << '\t' << p.second << std::endl;


> In your post you are showing the output without corresponding frequencies.

The post is just the source code for a program; no output is shown.

To physically see the actual output, you will need to build and then run the program.
@JLBorges
> In your post you are showing the output without corresponding frequencies.

The post is just the source code for a program; no output is shown.

To physically see the actual output, you will need to build and then run the program.


I have not understood what you are speaking about. I meant the original post of the thread.:)
@glennboy13


If the string is supposed contains only latin symbols then you can define an array with the size equal to 26 (the number of latin symbols). Then your code can look the following way

1
2
3
4
5
6
7
8
9
10
11
12
13
const int N = 26;
int letters[N] = {};

for ( char c : in_string )
{
   if ( c >= 'A' && c <= 'Z' ) c = 'a' + c - 'A';
   if ( c >= 'a' && c <= 'z' ) ++letters[ c - 'a' ];
}

for ( int i = 0; i < N; i++ )
{
   if ( letters[i] ) std::cout << char( 'a' + i ) << '\t' << letters[i] << std::endl;
}
Last edited on
> If the string is supposed contains only latin symbols then you can define
> an array with the size equal to 26 (the number of latin symbols).

http://jrgraphix.net/r/Unicode/0020-007F

@glennboy13, just use an array of size std::numeric_limits<unsigned char>::max() + 1. Writing sound, portable code is not any more difficult than using some magic number as a kludge. Unlearning wrong things later is far more difficult than learning it right the first time.

@JLBorges

@glennboy13, just use an array of size std::numeric_limits<unsigned char>::max() + 1. Writing sound, portable code is not any more difficult than using some magic number as a kludge. Unlearning wrong things later is far more difficult than learning it right the first time.


I do not think that it is a good idea to define an array of size std::numeric_limits<unsigned char>::max() + 1
if it is required only for example 26 elements.:) C++ has no all named definitions for constants that exist in the real world.
So I would prefer to decalre the array as

char letters[ 'z' - 'a' + 1] = {};

instead of

char letters[std::numeric_limits<unsigned char>::max() + 1] = {};

if only 'z' - 'a' + 1 elements are required.:)



Last edited on
> So I would prefer to decalre the array as

> char letters[ 'z' - 'a' + 1] = {};


You are being stupid. The IS makes no guarantee that 'z' - 'a' would not evaluate to, say, -78.
@JLBorges
The IS makes no guarantee that 'z' - 'a' would not evaluate to, say, -78.


I think that this is guaranteed by another standards that describes character sets as for example ISO/IEC 10646 or ASCII and so on
Last edited on
> I think that this is guaranteed by another standards that describes character sets
> as for example ISO/IEC 10646 or ASCII and so on

Yes, indeed.

And that the object representation of an integer is a 32-bit binary value in little-endian format is guaranteed by another standards that describe hardware architectures - for example, the IA-32 specification and so on.

So go ahead, in the programs that you write:
- never use std::isupper(), just hardcode a check for the ASCII range
- never use sizeof(int), just hardcode 4
- etc.


Just stop encouraging folks who are trying to learn C++ to follow the path that you have set out for yourself. Giving patently absurd advice is a lot worse than giving no advice at all.

And in this case, all this asinine contortions is to serve what purpose?
Save 286 and three quarters bytes in the storage used by a temporary object?
In my opinion your analogy with sizeof( int ) and 4 is incorrect applying to the original question. C/C++ standards are based on SO/IEC 10646 and other standards relative to sets of symbol. Moreover there is so-called default locale. So I do not see a problem if the PC needs to display only latin letters.
> So I do not see a problem if the PC needs to display only latin letters.

I do not see any problem with hard coding sizeof(int) as 4 either.

If.

If this wonderful PC which needs to display only latin alphabetic characters 'a' to 'z' happens to have an IA-32 processor.

I refuse to waste any more time on this; if you still can't see the issues involved, so be it.
Topic archived. No new replies allowed.