ilosć powtórzeń wyrazów w pliku

0

Witam Wszystkich
Potrzebuje pomocy i nie mam za bardzo pojęcia jak to ugryźć. Mianowicie program wyświetla wyniki powtórzeń, ale chciałbym posortować mapę od największej ilości powtórzeń i wyświetlić 20 wyników. poniżej kod:

    #include <iostream>  
    #include <fstream>  
    #include <sstream>  
    #include <map>  
    #include <string>  
      
    using namespace std;  
      
    class WordCounter  
    {  
    public:  
        int value;  
        WordCounter() : value( 0 ) {}  
          
        void operator++ (int) { value++; }  
    };  
      
      
    ostream& operator<<(ostream& st, WordCounter& wc )  
    {  
        return st << wc.value;  
    }  
      
    const string path = "/home/grzegorz/ownCloud/Nauka/wszib/sem6/WI/Zadania/Word Count/potop.txt";
      
    int main()  
    {  
        map<string, WordCounter> counter;  
      
        ifstream input;  
        input.open( path.c_str() );  
      
        if ( !input )  
        {  
            cout << "Error in opening file\n";  
            return 0;  
        }  
      
        string tok;       
        while ( true )  
        {  
            input >> tok;  
              
            if ( input )  
            {  
                counter[ tok ]++;  
            }  
            else break;       
        }  
      
        map< string, WordCounter,less<string> >::iterator it;  
      
        for ( it  = counter.begin();  
              it != counter.end();  
              it++ )  
	
        {  
            cout << (*it).first  
                 << "    "  
                 << (*it).second  
                 << endl;  
        }  
      
        return 0;  
    }   
0

Jak nie wiesz jak to ugryźć jak wszystko wiesz :p

chciałbym posortować mapę

std::sort

od największej ilości powtórzeń

std::greater + przeładuj operator w swojej strukturze / jakaś lambda

i wyświetlić 20 wyników

prosty for</del>

Tak, w ogóle to nie wiem po co ten wrapper na int (który powinien być size_t :p), ale może masz jakiś powód (:

0
 const string path = "[...]potop.txt";
...
cout << "Error in opening file Hamlet.txt\n";  

???

Mapa sortuje po kluczu, a nie wartości. Jak chcesz sortować po wartości to możesz np. wywalić wszystkie elementy do vectora i posortować po wartości.

0

Cały problem w tym, że nie mogę używać vectora :(

0

Możesz używać mapy, a nie możesz vectora? WTF?

0

No i dzięki za zwrócenie uwagi na błąd :))

0

no niestety, takie prikaz i już

0

<Durne>
Stwórz sobie multimapę <int, string, greater<int>>. Leć po wszystkich elementach pierwszej mapy, dodaj je do drugiej i voilà, masz posortowane po ilości wystąpień.
</Durne>

0
twonek napisał(a):

<Durne>
Stwórz sobie multimapę <int, string, greater<int>>. Leć po wszystkich elementach pierwszej mapy, dodaj je do drugiej i voilà, masz posortowane po ilości wystąpień.
</Durne>

Czy da się od razu zadać żeby wypisał tylko 20 pierwszych? W pythonie zrobiłem coś takiego i tam się udało :)

0

Jak będziesz leciał iteratorem podczas wypisywania zapamiętaj ile ywpisałeś i zakończ pętlę jak osiągniesz 20.

0

Drugim zadaniem jest zrobienie tego samego tylko bez użycia biblioteki STL. Od czego zacząć?

0

Struktura z string i int (albo char[] i int jeśli std::string też został zabroniony -_-)
Tablica takich struktur.
Wyszukiwanie binarne w tablicy takich struktur.
Sortowanie tablicy takich struktur.

0

Dzięki wielkie, będę próbował walczyć z tematem

0
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <boost/bimap/multiset_of.hpp>
#include <boost/assign/list_inserter.hpp>
#include <boost/range/adaptor/reversed.hpp>

#include <iostream>
#include <string>
using namespace std;

int main(){
    using bimap_type = boost::bimaps::bimap<
        string, boost::bimaps::multiset_of<size_t>
    >;
    
    bimap_type bimap;
    
    boost::assign::insert(bimap)
        ("Ala", 3)
        ("Kot", 4)
        ("But", 4)
        ("Mleko", 2)
        ("Miska", 1);
    
    for(auto &pair : boost::adaptors::reverse(bimap.right)){
        cout << pair.first << ": " << pair.second << "\n";
    }
}

http://melpon.org/wandbox/permlink/AkVMXcreKrReGeO9

stdout

4: But
4: Kot
3: Ala
2: Mleko
1: Miska
0

Co powiecie odnośnie tego tworu :)
plik1.cpp

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include "words.h"

using namespace std;

WordCounts::WordCounts()
{
	//initializing values;
	string arrWordsTemp [100000] = {""};
	string arrWords [100000] = {""};
	counter = 0;
	temp = "";
}
void WordCounts::readFile()
{
	iFile.open ("/home/grzegorz/ownCloud/Nauka/wszib/sem6/WI/Zadania/Word Count/potop.txt");

	string word;
	if (iFile.is_open())
	{
		while (!iFile.eof())
		{
			iFile >> word;
			arrWordsTemp [counter] += word;
			counter++;
		}
	}
}

void WordCounts::populate()
{
	for (int x = 0; x < counter; x++)
	{
		for (int y = 0; y < arrWordsTemp[x].length(); y++)
		{
			if ( arrWordsTemp[x][y] >= 65 && arrWordsTemp[x][y] <= 90)
		{
			arrWordsTemp[x][y] = tolower(arrWordsTemp[x][y]);
		}

			if (arrWordsTemp[x][y] >= 97 && arrWordsTemp[x][y] <= 122)
			{
				list[x].word += arrWordsTemp[x][y];  
			}
			if (arrWordsTemp[x][y] >=48 && arrWordsTemp[x][y] <= 57)
			{
				list[x].word += arrWordsTemp[x][y];
			}
			
		}
	}

	//remove empty array subscripts
	for (int a = 0; a < counter; a++)
	{
		for (int b = 0; b < counter; b++)
		{
			if (list[b].word == "")
			{
				temp = list[b].word;
				list[b].word = list[b + 1].word;
				temp = "";
			}
		}
	}

}

void WordCounts::sort() //sort words in non-decreasing order
{
		for (int x = 0; x < counter - 1; x++)
	{
		for (int y = 0; y < counter - 1; y++)
		{
			if (list[y].word > list[y + 1].word)
			{
				temp = list[y].word;
				list[y].word = list[y + 1].word;
				list[y + 1].word = temp;
			}
		}
	}
}

void WordCounts::removeDuplicates()
{
		for(int i=0;i<counter;i++)
	{
		list[i].count=1;
	
		if (list[i].word == "")
		{
			counter = counter - 1;
		}
		}
		for(int i=1; i<counter;)
		{
			if(list[i-1].word == list[i].word)
			{
				list[i-1].count++;
				for(int j=i; j<counter-1;j++)
				{
					list[j].word=list[j+1].word;
				}

				counter=counter-1;
			}else
			{
			i++;
			}
		} 
		
}

void WordCounts::printList()
{
	cout << fixed << setw(15) << "WORD" << fixed << setw(27) << "REPEATED" << endl << endl;
	for (int x = 0; x < counter - 1; x++)
	{
		cout << fixed << setw(15) << list[x].word << fixed << setw(20) << list[x].count << " times" << endl;
	}
}

plik2.h

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>

using namespace std;

class WordCounts
{
public:
	//constructor
	WordCounts();
	
	void readFile();				//cyztanie pliku
	void printList();				//wypisanie 

	void populate();				//zapis do tablicy
	void sort();					//sort
	void removeDuplicates();			//usuwanie duplic i powt. sie wyrazow

private:
	struct wordRec					//struct slow 
	{
		string word;				
		int count;					 
	};
	
	wordRec list[200000];	//tablica zliczajaca.
	string arrWordsTemp[100000]; //przetrzymujaca slowa
	string temp;					//pomocnicza
	
	int counter;					//ilosc powtorzen
	ifstream iFile;					// operacji na pliku

};

main.cpp

#include<iostream>
#include<iomanip>
#include<fstream>
#include"words.h"
int main()
{
	WordCounts para;
	para.readFile();
	para.populate();
	para.sort();
	para.removeDuplicates();
	para.printList();

	return 0;
} 

Przy kompilacji wywala mi naruszenie ochrony pamięci. Nie mogę namierzyć błędu. need help :). dzięki

1

A gdzie komunikat błędu?

//initializing values;
string arrWordsTemp [100000] = {""};
string arrWords [100000] = {""};

To nie jest żadna inicjalizacja, tylko tworzenie zmiennej lokalnej o takiej samej nazwie jak pole klasy. Poza tym stringi domyślnie się tworzą puste, więc nie ma po co robić cyrków z inicjalizacją.

0

Zrobiłem coś takiego:

#include <iostream>
#include <string>
#include <fstream>
#include <ctime>
#include <cstdio>

using namespace std;

const long long int MAKS=3000000;
string words[MAKS];
long long int instances[MAKS];
long long int count=0;

void insert(string input)
{
	for(int i=0; i<count; i++)
		if (input == words[i]){
			instances[i]++;
			return;
		}
	if(count < MAKS){
		words[count]=input;
		instances[count]=1;
		count++;
	} else
		cerr << "Za duzo slow w pliku wsadowym";
}


int findTop(string &word){
	
	long long int topCount = instances[0];
	long long int topIndeks = 0;	
	
	for(int i = 1; i<count; i++)
		if(instances[i] > topCount) {
			topCount = instances[i];
			topIndeks = i;
		}
	
	instances[topIndeks] = 0;
	word=words[topIndeks];

	return topCount;
}

int main()
{

	clock_t start = clock();

	string word;
	ifstream data("potop.txt");
	
	while(data >> word)
		insert(word);

	long long int topCount=1;

	for(int i=0; i<20; i++)
		cout << findTop(word) << " " << word << endl;

	printf( "Czas wykonywania programu w języku cpp: %lu sekund\n", (clock() - start) / 1000000 );
		
}

Nie wiem dlaczego do tablicy z powtórzeniami pakuje mi znak '-'. Pytanko jak go wyeliminować. Proszę o pomoc

0

Co to znaczy "pasuje"? To, że się tam wpisuje?
Jeżeli tak to przecież takie coś data >> word łyka wszystko, aż do białego znaku.
Czyli masz w pliku:
Ala ma kota - bartka.
to data >> word wczyta takie "słowa"
Ala
ma
kota

bartka.

Potrzebujesz walidacji czy słowo to na pewno słowo. Nie wiem jak bardzo musisz się w to zagłębiać. Co zrobisz z takim czymś? "A bartek jest koloru czerwono-niebieskiego i waży 12.5kg"

0

Faktycznie moje przeoczenie data>>word.
Co do interpretacji tekstu to czerwono-niebieskiego jest jak najbardziej słowem, wyrazem natomiast 12.5kg już nie jest.

Pojedyncze znaki jak a,i,w,z itd są wyrazami dlatego forem nie mogę po prostu skasować '-' z tablicy bo usunie mi pojedyńcze wyrazy.

0

Jeśli chodzi o output to wygląda następująco:
14251 -
12580 i
9035 się
7642 w
7354 nie
6324 na
5801 z
4207 do
3852 to
3662 że
3007 a
1950 za
1848 bo
1832 pan
1740 po
1689 ale
1650 jak
1635 o
1453 go
1431 co
Gdyby nie ten znak '-' wszystko by było pięknie

0

Twoje rozwiązanie na razie to format "brute force" / "naiwna".
Jeśli działa to na pierwszą lekcję programowania spoko.
Jeśli jesteś na studiach informatycznych, to raczej zainteresuj się jakimiś bardziej zaawansowanymi strukturami.

Np. Trie: http://exceptional-code.blogspot.com/2011/07/coding-up-trie-prefix-tree.html

1 użytkowników online, w tym zalogowanych: 0, gości: 1