Аргумент функции istream и vector

Рубрика: C++, Дата: 3 March, 2013, Автор:
Tags:

Напишите функцию, которая получает в качестве аргументов istream и vector<string>, а порождает map<string,vector<int> >, содержащий каждую строку и частоту ее вхождения. Прогоните программу на текстовом файле с количеством строк не менее 1000, разыскивая при этом не менее десяти слов.

Другими словами функция должна принимать массив слов и открытый поток файла и искать слова с массива. Вроде как бы все ясно, но что такое за фигня istream? Не все так просто, если бы я передал бы имя файла, то мне понятней было б, просто в функции прочитал бы файл, а так придется повозится.

Пока я вам полный код программы выложу, а дальше приведу свои комментарии по коду:

//function dl9 chtni9 i poicka v faile
#include <iostream>
using std::cout;
using std::endl;
using std::ios;
using std::cerr;
using std::istream;
#include <fstream>
using std::ifstream;
#include <vector>
using std::vector;
#include <string>
using std::string;
#include <map>
using std::map;
#include <cstdlib>
using std::exit;
#include <cstring>
using std::strtok;
using std::strlen;
using std::strcpy;


map<string,vector<int> > f(vector<string>,istream &);

int main()
{
	vector<string> v;
	v.push_back("Hellow");
	v.push_back("world");
	
	//otkruvaem fail
	ifstream r("Char_queuev.h",ios::in);
	if(!r)
	{
		cerr <<"don't open file"<<endl;
		exit(1);
	}
	
	
	//exit(1);
	map<string,vector<int> > mas;
	mas=f(v,r);
	//popropyem vuvecti mas cherez iteratoru
	map<string,vector<int> >::iterator itmas=mas.begin();
	for(;itmas!=mas.end();++itmas)
	{
		//cozdaem iterator dl9 vectora int
		vector<int> a;
		vector<int>::iterator itvc=(*itmas).second.begin();
		for(;itvc!=(*itmas).second.end();++itvc)
		{
			cout <<(*itmas).first<<' '<<*itvc<<endl;
		}
	}
	
	return 0;
}


map<string,vector<int> > f(vector<string> v, istream &r)
{
	//chitaem fail
	char k;
	string str="";
	map<string,vector<int> >result;//rezyl6tat
	while(r.get(k))
	{
		str+=k;
	}
	//cout <<str<<endl;//naxoditc9 tekct faila
	//razbivaem na leksemu i ocychestvl9em poick
	char* leksema=strtok((char*)str.data(),"\n");
	vector<string> massS;//vector ctrok
	
	while(leksema!=NULL)
	{
		massS.push_back(leksema);
		//cout <<"leksema= "<<leksema<<endl;
		leksema=strtok(NULL,"\n");
	}
	
	vector<string>::iterator itv=v.begin();
	for(;itv!=v.end();++itv)
	{
		cout <<*itv<<endl;
		//cozdaem vektor int
		vector<int> znach;//pyctoi
		//vuvod cherez iteratoru
		vector<string>::iterator it=massS.begin();
		int count=0;//cchetchik ctrok
		for(;it!=massS.end();++it)
		{
			leksema=strtok((char*)(*it).data()," ");
			znach.push_back(0);//dobavl9em element kotorui raven 0
			while(leksema!=NULL)
			{
				if(strcmp(leksema,(*itv).data())==0)
				{
					znach[count]++;//inkrementiryem
				}
				//cout <<"leksema= \""<<leksema<<"\""<<endl;
				leksema=strtok(NULL," ");
			}
			count++;
		}
		
		result[*itv]=znach;//dobavl9em element
	}
	
	return result;
}

поток как оказалось istream это как бы ключевое слово мы можем передать и ifstream и еще там вроде два потока не помню. istream это как бы обособленное слово для всех типов выводов, в даном примере мы например под типом istream передали тип ifstream вывод из файла. Нужно его определять в <iostream> то есть под директивой #include <iostream> добавить using istream; вот так то.

Идем дальше. Да и еще пару замечаний оказывается эти потоки можно токо по ссылке передавать, как я не пытался их передать по значению ничо не получалось ошибка была. Поэтому пришлось ссылочку втулить istream&.

функция возвращает ассоциативный массив слов, где каждому слову соответствует еще один массив в котором элементы это строки, а значения частота появления слова в строке. Ну программка моя не правильно работает. она строки пустые например не учитывает. Если у нас есть в файле пустая строка, то там нету такого чтоб в массиве она была отражена, например строка такая то значение 0, нету такого ее просто нету, массив возвращается токо для существующих строк. Мне просто лень было делать как нада. поэтому я побыстряку сделал.

Вообще я не понимаю зачем нужно возвращать массив строк значением ассоциативного массива? Можно же ведь было просто значение передать? Можно! Ну так нафиг оно над? Мне это ничо не дает, яб лучше вернул бы map<string,int> намного лучше и краше и менее запутано чем map<string,vector<int> > – гамно какое то.

Ну чо еще сказать? Хотел было много понаписать, а щас все с головы повылетало 🙂

В задачке написано нужно проверить на файле со 1000   строками минимум и для 10 слов, но я это пропустил да лень. Проверял на файле с 31 строкой и для 2 слов все работает.

Да долго над ней мучился почти два дня но все рамно сделал да мега хакер :).

Комментарии:


Оставить комментарий

Your email address will not be published. Required fields are marked *