c++ problem

Feb 22, 2012 at 7:54pm
Hello I would need your help in building a simple piece of program.

I'm working on a program that reads out of a txt file data that looks like this:


a 845
b 265
c 259
d 369
e 907
f 187
g 242
h 249
i 497
j 48
k 214
l 576
m 308
n 426
o 687
p 340
q 7
r 498
s 792
t 521
u 364
v 85
w 222
x 34
y 192
z 42

now it gets read by the program:

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
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
 
int main()
{
    string line;

    ifstream in("letter_number.txt"); // the file that the data is read out off
    if( !in.is_open())
    {
          cout << "Input file failed to open\n";
          return 1;
    }

    while( getline(in,line) ) // it reads line by line
    {
         cout<< line[0] << " "; // prints the letter
         
         for (int pos = 2; pos <= line.length(); ++pos) // prints the numbers
         {
         cout << line[pos]; 
         }
         
         cout << "\n";

    }
    in.close();
   
 
    string end;
    cin >> end;
    
    
    return 0;
}


now i would need some code that saves it into array or something, sorts the data by the number but the corresponding letter has to be left next number. Then the program needs to print the letter corresponding to the biggest number. If the letter was printed before it should print the second biggest and so on..
Feb 22, 2012 at 8:07pm
The simplest way is to use standard container std::vector for std::pair<char, int>

for example

1
2
3
4
5
6
7
8
9
10
11
std::vector<std::pair<char, int> > v;

while ( std::getline( in, line ) )
{
   std::istringstream is( line );
   std::pair<char, int> p;

   is >> p.first >> p.second;

   v.push_back( p );
}


When you can sort your vector as needed.

Or another variant is to use container std::multimap<int, char> It will be sorted automatically when you add records to it.
Feb 22, 2012 at 8:09pm
could you please give me a working code that could function because im a total newbie

thnks
Last edited on Feb 22, 2012 at 8:09pm
Feb 22, 2012 at 8:17pm
In fact I have already presented a working code. I only have not tested it.

You should include the following headers along with your previosly included headers

#include <vector>
#include <sstream>
#include <utility>
#include <algorithm>

When in your program change your loop to main. Also can include outputing read data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::vector<std::pair<char, int> > v;

while ( std::getline( in, line ) )
{
   std::istringstream is( line );
   std::pair<char, int> p;

   is >> p.first >> p.second;

   std::cout << p.first << ' ' << p.second << std::endl;

   v.push_back( p );
}

std::cout << "Total read lines are " << v.size() << std::endl;


If you use using directive you may drop std:: prefix, i.e. you may write cout instead of std::cout
Last edited on Feb 22, 2012 at 8:18pm
Feb 22, 2012 at 8:22pm
Yeah I got that running but could you give me a piece of code that tells me the letter that has the biggest number next to it..

could you give me your skype for help?
Feb 22, 2012 at 8:24pm
devilsk13, have you even tried to do this on your own? We're not here to do your homework for you.
http://www.cplusplus.com/forum/beginner/1/#msg6680
Feb 22, 2012 at 8:24pm
You could store these in a vector. If you want to keep them togeather, stick them into a structure, or better yet, a pair. You can use the pre-defined sort algorithm from STL to put everything in order according the the number.

I think there is something wrong with my compPair function, but I have to leave you with something right?

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
#include <utility> // for std::pair
#include <vector> // for std::vector
#include <sstream> // for std::stringstream and std::string
#include <fstream> // for std::ifstream
#include <iostream> // for std::cout and std::endl
#include <algorithm> // for std::sort()
using namespace std;

//Function for the sort algorithm
struct compPair {
	bool operator()(const pair<char,int> &i, const pair<char,int> &j) { return i.second > j.second; }
};

int main()
{
	vector<pair<char, int> > MyList;
	vector<pair<char, int> >::iterator it;
	vector<pair<char, int> >::iterator jt;

	//Read in stuff
	string line;
	ifstream in("letter_number.txt");
	if( !in.is_open())
	{
		cout << "Input file failed to open\n";
		return 1;
	}
	while ( getline(in, line)) // Read line by line
	{
		stringstream iss(line); //stick the line into a stringstream
		pair<char, int> temp; 
		iss >> temp.first >> temp.second; //divide the line into seperate objects
		MyList.push_back(temp); //Add it to the vector
	}
	in.close(); // close the file (this is where your stuff ends)

	//sort the list
	sort(MyList.begin(), MyList.end(), compPair);

	//if the letter existed before, delete it
	for (it = MyList.begin()+1; it < MyList.end(); it++)
		for (jt = MyList.begin(); jt < it; jt++)
			if (jt->first == it->first)
				MyList.erase(it);

	//print out the letters in order
	for (it = MyList.begin(); it < MyList.end(); it++)
		cout << it->first;
}
Last edited on Feb 22, 2012 at 8:41pm
Feb 22, 2012 at 8:27pm
Are you asking how to sort your data? If so then you can use standard algorithm std::sort which is declared in header <algorithm>

for example

1
2
3
std::sort( v.begin(), v.end(),
                       [] ( const std::pair<char, int> &a, const std::pair<char, int> &b ) 
                          { return ( a.second < b.second ); } );
Last edited on Feb 22, 2012 at 8:28pm
Feb 22, 2012 at 8:31pm
I got an error message:

In constructor `std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) [with _U1 = char, _U2 = int, _T1 = std::string, _T2 = int]':

2319 stl_algo.h instantiated from `void std::partial_sort(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<char, int>*, std::vector<std::pair<char, int>, std::allocator<std::pair<char, int> > > >, _Compare = bool (*)(std::pair<std::string, int>, std::pair<std::string, int>)]'

2508 stl_algo.h instantiated from `void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<char, int>*, std::vector<std::pair<char, int>, std::allocator<std::pair<char, int> > > >, _Size = int, _Compare = bool (*)(std::pair<std::string, int>, std::pair<std::string, int>)]'

2591 stl_algo.h instantiated from `void std::sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<char, int>*, std::vector<std::pair<char, int>, std::allocator<std::pair<char, int> > > >, _Compare = bool (*)(std::pair<std::string, int>, std::pair<std::string, int>)]'

35 instantiated from here
90 stl_pair.h invalid conversion from `const char' to `const char*'
90 stl_pair.h initializing argument 1 of `std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]'

I use Dev C++... Please try to solve this..
Last edited on Feb 22, 2012 at 8:32pm
Feb 22, 2012 at 8:39pm
and this code gave me another errors:

1
2
3
std::sort( v.begin(), v.end(),
                       [] ( const std::pair<char, int> &a, const std::pair<char, int> &b ) 
                          { return ( a.second < b.second ); } );


40 expected primary-expression before '[' token
40 expected primary-expression before ']' token
40 expected primary-expression before "const"
40 expected primary-expression before "int"
40 expected primary-expression before "const"
40 expected primary-expression before "int"
Feb 22, 2012 at 8:42pm
lambda expressions are a C++11 trait. If you aren't using a compiler that can handle c++0x, then you shouldn't be using lambda expressions.
Feb 22, 2012 at 8:44pm
could you give me something that will work or a good complier?
Feb 22, 2012 at 8:44pm
This is compiled snip of code. I only changed from your input stream ifstream in("letter_number.txt"); to std::cin for testing. Try to use this snip code as a template for your program.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
	std::string line;
	std::vector<std::pair<char, int>> v;

	while ( std::getline( std::cin, line ) )
	{
		std::istringstream is( line );
		std::pair<char, int> p;

		is >> p.first >> p.second;
		v.push_back( p );
	}

	std::sort( v.begin(), v.end(),
		       [] ( const std::pair<char, int> &a, const std::pair<char, int> &b )
		              { return ( a.second < b.second ); } );

	for ( auto i = v.begin(); i != v.end(); ++i )
        	{
		std::cout << i->first << ' ' << i->second << std::endl;
	}
Last edited on Feb 22, 2012 at 9:00pm
Feb 22, 2012 at 8:50pm
devilsk13, we are not here to solve your homework problems for you. If you don't want to do your research, you're not going to learn anything, and you're going to end up getting bad grades later on, or worse, causing more heartache for the people that you have to work with. At least make an attempt at creating your own code with all of the information that you've been given, and then maybe we can help you debug it.

And please read the link that I posted above at http://www.cplusplus.com/forum/beginner/62625/#msg338925
Feb 22, 2012 at 8:50pm
what complier are you using because it is giving me stupid stuff
Feb 22, 2012 at 8:55pm
I am using MS Visual Studio C++ 2010. There are on-line compilers in internet. For example,
http://liveworkspace.org/
Feb 22, 2012 at 8:56pm
Man, I thought I was the first to respond! That took longer than expected.
Feb 22, 2012 at 8:58pm
Why not just use my code? The sort algorithm uses something a little more basic syntax-wise.
Topic archived. No new replies allowed.