Häufigkeit Zeichen aus Datei/String
-
...
-
Danke. Man lernt die aus und das ist wohl an mir vorbei gegangen
-
Mein GCC hat leider noch kein 11
-
Swordfish schrieb:
Jolle schrieb:
Was hat es mit "auto it" auf sich, kann mein compieler leider nichts mit anfangen.
C++11 – Part 1: Automatic Types
Dann eben
char ch = max_element(test.begin(), test.end())->first;
Bin eben erst dazu gekommen es auszuprobieren. Bei deinem Code gibt er leider einfach das letzte Zeichen aus nicht das was am meisten in der map vorkam.
-
#include <fstream> #include <iostream> #include <vector> #include <string> #include <set> struct CharCount { explicit CharCount(unsigned char c, std::size_t count) : c(c), count(count) { } unsigned char c; std::size_t count; }; bool operator < (CharCount const& lhs, CharCount const& rhs) { return lhs.count < rhs.count; } std::string getStreamContent(std::ifstream & str) { std::string fileContent; std::string tmp; while ( std::getline(str, tmp) ) { fileContent += tmp + "\n"; tmp.clear(); } return fileContent; } std::set<CharCount> countChars(std::string const& strContent) { std::vector<std::size_t> countings(std::numeric_limits<unsigned char>::max(), 0); for(auto c : strContent) { countings[static_cast<std::size_t>(c)]++; } std::set<CharCount> frequenzy; for(std::size_t i = 0; i < countings.size(); ++i) { frequenzy.insert(CharCount(static_cast<char>(i), countings[i])); } return frequenzy; } int main() { std::string filename; std::cout << "Dateiname: "; std::getline(std::cin, filename); std::ifstream file(filename.c_str()); if ( !file ) { std::cerr << "Datei gibt es nicht" << std::endl; return -1; } std::string fileContent = getStreamContent(file); auto frequenzy = countChars(fileContent); for(auto cc : frequenzy) { std::cout << "\"" << cc.c << "\"" << "(" << static_cast<std::size_t>(cc.c) << ") -> " << cc.count << std::endl; } std::cin.get(); return 0x0; }
wäre eine halbwegs flexible Möglichkeit
-
...
-
Habe es jetzt hiermit gelöst
typedef map<char, int> test;
struct less_value {
bool operator()(test::value_type const& l, test::value_type const& r) {
return l.second < r.second; // second ist der Wert eines Map-Elementpaars
}
};
-
Warum eine Klasse mit operator(), aber ganz ohne Member? Das ist eine Funktion!
-
Ich habe hier mal noch ein abstrakte Lösung:
#include <algorithm> #include <fstream> #include <iostream> #include <iterator> #include <map> #include <string> #include <utility> using namespace std; struct most_occurrence { template <typename T> bool operator()(const T& lhs, const T& rhs) { return lhs.second < rhs.second; } }; template<typename Iter> typename map<typename iterator_traits<Iter>::value_type,unsigned> all_occurrences(Iter begin, Iter end) { map<typename iterator_traits<Iter>::value_type,unsigned> count; for(Iter it=begin; it!=end; ++it) { ++count[*it]; } return count; } int main() { ifstream file("test.txt"); const string content( (istreambuf_iterator<char>(file)), (istreambuf_iterator<char>()) ); const map<char,unsigned> occurrences = all_occurrences( content.begin(), content.end() ); const pair<char,unsigned> most = *max_element( occurrences.begin(), occurrences.end(), most_occurrence() ); for(map<char,unsigned>::const_iterator it=occurrences.begin(); it!=occurrences.end(); ++it) { cout << it->first << ": " << it->second << 'x' << '\n'; } cout << most.first << " kommt auf haeufigsten vor: " << most.second << 'x' ; }
-
SeppJ schrieb:
Warum eine Klasse mit operator(), aber ganz ohne Member?
Sowas lässt sich viel leichter inlinen.
-
SeppJ schrieb:
Warum eine Klasse mit operator(), aber ganz ohne Member? Das ist eine Funktion!
Will
max_element
nicht einen Functor?
-
duh schrieb:
Sowas lässt sich viel leichter inlinen.
Nein.
out schrieb:
Will
max_element
nicht einen Functor?Nein, max_element will irgendetwas aufrufbares. Irgendetwas, so dass der Code
comp(a,b)
etwas sinnvolles ergibt.
-
SeppJ schrieb:
duh schrieb:
Sowas lässt sich viel leichter inlinen.
Nein.
out schrieb:
Will
max_element
nicht einen Functor?Nein, max_element will irgendetwas aufrufbares. Irgendetwas, so dass der Code
comp(a,b)
etwas sinnvolles ergibt.Wie würde es denn ohne Functor gehen?
template <typename T> bool most_occurrence(const T& lhs, const T& rhs) { return lhs.second < rhs.second; } // Error: Funktions-template "bool most_occurrence(const T &,const T &)" kann nicht als Funktionsargument verwendet werden. const pair<char,unsigned> most = *max_element( occurrences.begin(), occurrences.end(), most_occurrence );
-
...
-
@out: Mit deinem template würde das auch gehen, du musst es aber natürlich noch instanzieren.
-
Danke swordfish so klappts auch wunderbar! Jetzt noch der Rest und die häufigkeitsanalyse für den caeser code ist fertig.
-
Ich erinnere noch kurz an cooky451s Vorschlag:
cooky451 schrieb:
Bei 8 bit kannste auch nen unsigned arr[256] = {} nehmen.
#include <algorithm> #include <iostream> int main(){ int histogram[256]={0}; histogram['y']=2; histogram['q']=1; histogram['e']=47; histogram['u']=19; const char ch = std::max_element(histogram, histogram+256) - histogram; if(31<ch && ch<256) std::cout << '\'' << ch << "\'\n"; }
Für die Puristen...
-
von mir noch der Hinweis: char zuerst auf unsigned char casten und dann weiterarbeiten
wenn mann z.B. char auf unsigned int castet, schiebt der Compiler noch einen unerwünschten cast dazwischen: char -> int -> unsigned int
(für Zeichen > 127)
-
Noch eine Frage...
Kennt jemand das Zeichen " „ ", wenn ich es caste wird mir es als -124 dargestellt. In der ASCII Tabelle finde ich es irgendwie nicht, aber c++ stellt es dar wenn man eine -124 als char ausgibt.
Danke
-
Das ist auch nicht ASCII, sondern Windows-1252 (Zeichen 132, weil -124 = 132 (mod 256)). Es handelt sich dabei um eine spezielle Kodierung, die von der Windows-Konsole verwendet wird, wenn man sie nicht anders zwingt. Und eigentlich auch so ziemlich nur da.