From: DaRQsiDe on 29 Nov 2009 17:41 Greetings all, I got stuck at one point in this exercise. I actually wrote the code for the exercise (for who has the book) but one thing I still wonder... 5-1. Design and implement a program to produce a permuted index. A permuted index is one in which each phrase is indexed by every word in the phrase. In one place of the code, there should be a rotator function that rotates words. I tried to use two different approaches... 1- Using vector of vectors of strings vector< vector<string> > GenerateRotamer (const vector<string>& str_vec) { typedef vector<string>::size_type str_vec_size; vector<string> str_vec_copy (str_vec); vector< vector<string> > rot_vec; str_vec_size i = 0; while (i < str_vec_copy.size()) { rot_vec.push_back(str_vec_copy); string rotated = *(str_vec_copy.begin()); str_vec_copy.erase(str_vec_copy.begin()); str_vec_copy.push_back(rotated); i++; } return rot_vec; } -> This works perfectly. 2- (First trial actually) I tried to use a vector of vectors of string vector iterators typedef vector<string>::iterator str_vec_iter; vector< vector<str_vec_iter> > GenerateRotamer (const vector<string>& str_vec) { vector<str_vec_iter> str_vec_iter; vector< vector<str_vec_iter> > rot_vec_iter; for (str_vec_iter i = str_vec.begin() ; i < str_vec.end() ; i++) { str_vec_iter.push_back(i); } vector<str_vec_iter>::size_type j = 0; while (j < str_vec_iter.size()) { rot_vec_iter.push_back(str_vec_iter) str_vec_iter temp_iter = *(str_vec_iter.begin()) str_vec_iter.erase(str_vec_iter.begin()); str_vec_iter.push_back(temp_iter); j++; } } -> In essence the two codes should do the same work but this code using the iterator vectors didnot worked. So my question is - cannot we use iterators synonymous to pointers in C? I didnot wanted to use pointers sine that would discard the purpose of Accelerated C++ imo. Thanks, Cihan
From: DaRQsiDe on 29 Nov 2009 23:14 Greetings to all again, As I worked with the code and tried to experiment with it I got two more questions... This is the complete code. Works nicely. #include <iostream> #include <string> #include <vector> #include <cctype> #include <algorithm> #include <iomanip> using namespace std; vector<string> SplitStringBySpace (const string& str_in) { typedef string::size_type str_size; vector<string> str_vec; str_size i = 0; while (i != str_in.size()) { while (i != str_in.size() && isspace(str_in[i])) { i++; } str_size j = i; while (j != str_in.size() && !isspace(str_in[j])) { j++; } if (i != j) { str_vec.push_back(str_in.substr(i, (j - i))); i = j; } } return str_vec; } vector< vector<string> > GenerateRotamer (const vector<string>& str_vec) { vector<string> str_vec_copy (str_vec); vector< vector<string> > rot_vec; str_vec_copy.push_back("END_OF_LINE"); vector<string>::iterator iter = str_vec_copy.begin(); while (*(str_vec_copy.begin()) != "END_OF_LINE") { rot_vec.push_back(str_vec_copy); string rotated = *(str_vec_copy.begin()); str_vec_copy.erase(str_vec_copy.begin()); str_vec_copy.push_back(rotated); } return rot_vec; } bool CompareWord (const vector<string>& str_vec_1, const vector<string>& str_vec_2) { vector<string>::const_iterator iter_1 = str_vec_1.begin(); vector<string>::const_iterator iter_2 = str_vec_2.begin(); while (*iter_1 == *iter_2) { iter_1++; iter_2++; } string str_1 = *iter_1; string str_2 = *iter_2; transform (str_1.begin(), str_1.end(), str_1.begin(), ::tolower); // Question 1 transform (str_2.begin(), str_2.end(), str_2.begin(), ::tolower); return str_1 < str_2; } string::size_type VectorToString (vector< vector<string> >& rot_vec, vector<string>& left_output, vector<string>& right_output) { for (vector< vector<string> >::iterator i = rot_vec.begin() ; i < rot_vec.end() ; i++) { string left_line; string right_line; vector<string>::iterator j = (*i).begin(); while (j != (*i).end()) { while (*j != "END_OF_LINE") { right_line += *j; right_line += " "; j++; } if (*j == "END_OF_LINE") { j++; } while (j != (*i).end()) { left_line += *j; left_line += " "; j++; } } /* -> Question 2... // Remove trailing spaces... left_line.erase(left_line.end()); right_line.erase(right_line.end()); */ left_output.push_back(left_line); right_output.push_back(right_line); } string::size_type max_length = 0; vector<string>::iterator j = left_output.begin(); while (j < left_output.end()) { max_length = max (max_length, (*j).size()); j++; } return max_length; } int main () { string input; vector< vector<string> > all_rotamers; while (getline(cin, input)) { vector<string> input_words; vector< vector<string> > input_rotamers; input_words = SplitStringBySpace (input); input_rotamers = GenerateRotamer (input_words); all_rotamers.insert (all_rotamers.end(), input_rotamers.begin(), input_rotamers.end()); } sort (all_rotamers.begin(), all_rotamers.end(), CompareWord); vector<string> left_out; vector<string> right_out; string::size_type left_offset = VectorToString (all_rotamers, left_out, right_out); cout << endl; for (int i = 0 ; i < left_out.size() ; i++) { cout << setw(left_offset+1) << left_out[i]; cout << "\t" << right_out[i] << endl; } cout << endl; } Now questions... 1- At line 71 in function transform, I had to include "::tolower" to convert the string to lowercase. Instead of "::tolower" when I put "tolower" (without the two semicolons) compiler (icpc) complained : 5-1.cpp(71): error: no instance of overloaded function "transform" matches the argument list argument types are: (__gnu_cxx::__normal_iterator<char *, std::basic_string<char, std::char_traits<char>, std::allocator<char>>>, __gnu_cxx::__normal_iterator<char *, std::basic_string<char, std::char_traits<char>, std::allocator<char>>>, __gnu_cxx::__normal_iterator<char *, std::basic_string<char, std::char_traits<char>, std::allocator<char>>>, <unknown-type>) transform (str_1.begin(), str_1.end(), str_1.begin(), tolower); // Question 1 ^ I saw many examples using tolower without the semicolons on internet. Why do you think is the reason of this complaint? (g++ also complains...) 2- At line 101, i tried to delete the trailing space resulting from string concatenation. The program compiles with the code, but the output I get from the program is a segmentation fault if i try to erase the last character in the string with string.erase(string.end). Why is the reason for this behavior? Thank you, Cihan
From: n00m on 30 Nov 2009 02:38 Weird. Must work. int main() { string s = "aBcDDeT"; s.erase(s.size() - 1); cout << s << endl; //aBcDDe transform(s.begin(), s.end(), s.begin(), tolower); cout << s << endl; //abcdde
|
Pages: 1 Prev: delete operator in class destructor Next: Define overloaded operators for structures? |