Just another zu demonstrieren, wahrscheinlich viel schneller, Art und Weise, Dinge zu tun alles, was in ein Array betrachten zu lesen und mit einem benutzerdefinierten Iterator der Umwandlung zu tun.
class ToHexIterator : public std::iterator<std::input_iterator_tag, int>{
char* it_;
char* end_;
int current_;
bool isHex(const char c){
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
char toUpperCase(const char c){
if (c >= 'a' && c <= 'f'){
return (c - 'a') + 'A';
}
return c;
}
int toNibble(const char c){
auto x = toUpperCase(c);
if (x >= '0' && x <= '9'){
return x - '0';
}
else {
return (x - 'A') + 10;
}
}
public:
ToHexIterator() :it_{ nullptr }, end_{ nullptr }, current_{}{} //default constructed means end iterator
ToHexIterator(char* begin, char* end) :it_{ begin }, end_{ end }, current_{}{
while (!isHex(*it_) && it_ != end_){ ++it_; }; //make sure we are pointing to valid stuff
++(*this);
}
bool operator==(const ToHexIterator &other){
return it_ == nullptr && end_ == nullptr && other.it_ == nullptr && other.end_ == nullptr;
}
bool operator!=(const ToHexIterator &other){
return !(*this == other);
}
int operator*(){
return current_;
}
ToHexIterator & operator++(){
current_ = 0;
if (it_ != end_) {
while (isHex(*it_) && it_ != end_){
current_ <<= 4;
current_ += toNibble(*it_);
++it_;
};
while (!isHex(*it_) && it_ != end_){ ++it_; };
}
else {
it_ = nullptr;
end_ = nullptr;
}
return *this;
}
ToHexIterator operator++(int){
ToHexIterator temp(*this);
++(*this);
return temp;
}
};
Der grundlegende Anwendungsfall würde wie folgt aussehen:
char in[] = "1,3,8,b,e,ff,10,--";
std::vector<int> v;
std::copy(ToHexIterator{ std::begin(in), std::end(in) }, ToHexIterator{}, std::back_inserter(v));
Beachten Sie, dass es schneller sein kann, eine Nachschlagetabelle zu verwenden, um die ascii zu tun knabbern Umwandlung verhexen.
Geschwindigkeit kann sehr abhängig von Compiler-Optimierung und Plattform sein, aber da einige der istringstream-Funktionen als virtuals oder Zeiger auf Funktionen (abhängig von der Standard-Bibliothek-Implementierung) implementiert sind, hat der Optimierer Probleme mit ihnen. In meinem Code gibt es keine victuals oder Funktionszeiger, und die einzige Schleife ist in der std :: copy-Implementierung, mit der der Optimierer vertraut ist. Es ist auch im Allgemeinen schneller zu loopen, bis zwei Adressen gleich sind, anstatt zu loopen, bis die Sache, auf die ein Zeiger hinweist, gleich ist.Am Ende des Tages ist alles Spekulationen und Voodoo aber auf MSVC13 auf meiner Maschine etwa 10x schneller. Hier ist ein Live-Beispiel http://ideone.com/nuwu15 auf GCC, das irgendwo zwischen 10x und 3x liegt, abhängig vom Lauf und abhängig davon, welcher Test zuerst geht (wahrscheinlich wegen einiger Caching-Effekte).
Alles in allem gibt es zweifellos mehr Platz für Optimierung etc. und jeder, der auf dieser Abstraktionsebene sagt "meins ist immer schneller", verkauft Schlangenöl.
Update: eine Kompilierung mit generierten Tabelle erhöht die Geschwindigkeit weiter sehen: http://ideone.com/ady8GY (beachten Sie, dass ich die Größe der Eingabezeichenfolge erhöhtes Rauschen zu verringern, so dass diese auf das obige Beispiel nicht direkt vergleichbar ist)
Sie sollten wahrscheinlich den relevanten Teil Ihres nicht funktionierenden Codes posten, damit die Leute hier Ihnen bei der Behebung helfen können. –
Verwenden Sie ['std :: istringstream '] (http://en.cppreference.com/w/cpp/io/basic_istringstream) in Verbindung mit dem [' std :: hex'] (http: //en.cppreference. com/w/cpp/io/manip/hex) E/A-Manipulator. Das Überspringen der Zeichen ',' kann als [hier gezeigt] (http://stackoverflow.com/a/24520662/1413395) erfolgen. –
@PaulR Ich habe gerade den Schnitt gemacht. – user3330644