Zweidimensionales Array sortieren
-
Hallo,
ich habe ein zweidimensionales Array, das ich gerne bzgl. einer der Spalten sortieren möchte.Alle Werte des Arrays sind long doubles.
Die Größe des Arrays ist mit ARRAYSIZE vorgegeben.
Die Dimension des Arrays entspricht "channels".Die Sortierung des Arrays soll aufsteigend oder absteigend hinsichtlich channel 3 stattfinden.
Hierbei ist:
#define ARRAYSIZE 50 // Anzahl der zu mittelnden Messwerte...könnte später größer werden...int channels = 4; // evtl. kann im späteren Verlauf noch ein channel hinzu kommen
long double tmpch[4]; // tmp-array - one value each channelBisher hatte ich versucht, die Sortierung relativ einfach mit C durchzuführen:
if (pet == ARRAYSIZE-1) // if actual position = end of array { for (int i=0; i<ARRAYSIZE-1; i++) // check all values { if (messwerte[3][i] > messwerte[3][i+1]) // arrange by channel 3 { for (int chan=0; chan < channels-1; chan++) { tmpch[chan] = messwerte[chan][i+1]; messwerte[chan][i+1] = messwerte[chan][i]; messwerte[chan][i] = tmpch[chan]; } if (i >= 1) { i--; } printf("i=%d\n",i); } } printf("\n\nFINISHED\n\n"); } } // end of endless for-loop
Ich denke jedoch, dass das ne Menge Overhead erzeugt. Außerdem klappt das noch nicht so ganz.
Da ich jedoch meine ersten Gehversuche in C++ machen möchte, wurde mir geraten, mir die Sortierung unter C++ anzusehen.
Kann mir vielleicht jemand ein Beispiel zur Sortierung unter C++ nennen? Oder mir Suchbegriffe für Google an den Kopf werfen?
-
Cysign schrieb:
#define ARRAYSIZE 50 // Anzahl der zu mittelnden Messwerte...könnte später größer werden...
Als erstes solltest du dir std::vector ansehen, damit geht alles viel einfacher.
typedef std::vector<double> channel; std::vector<channel> messwerte; // messwerte füllen mit push_back(...) std::sort(messwerte.begin(), messwerte.end());
-
Hi,
du bist im falschen Forum gelandet, du machst ja C.
-
Da du fragst, wie das in C++ besser geht:
#include <iostream> #include <array> #include <algorithm> using namespace std; template <typename ElementType, size_t compare_column> bool compare_by_column(ElementType const &lhs, ElementType const &rhs) { return lhs[compare_column] < rhs[compare_column]; } int main() { array<array<int, 3>, 4> foo = {{{{1,6,8}},{{4,2,7}},{{8,3,1}},{{9,3,4}}}}; cout << "Vorher:\n"; for (auto zeile : foo) { for (auto eintrag: zeile) cout << eintrag << ' '; cout << '\n'; } sort(foo.begin(), foo.end(), compare_by_column<array<int, 3>, 1>); cout << "\nNach zweiter Spalte sortiert:\n"; for (auto zeile : foo) { for (auto eintrag: zeile) cout << eintrag << ' '; cout << '\n'; } }
Das ginge übrigens auch in C wesentlich schöner. Nutze die Standardbibliothek! qsort bietet sich an.
-
Da der Code des TE nicht C++, sondern C zu sein scheint -- in C ginge das beispielsweise so:
#include <stdio.h> #include <stdlib.h> int compare_channel3(void const *lhs_v, void const *rhs_v) { double const *lhs = (double const *) lhs_v; double const *rhs = (double const *) rhs_v; return lhs[3] < rhs[3] ? -1 : (lhs[3] > rhs[3] ? 1 : 0); } int main(void) { int i; double werte[][4] = { { 1, 2, 3, 4 }, { 3, 1, 4, 1 }, { 1, 1, 2, 3 }, { 1, 4, 1, 2 }, { 2, 3, 4, 5 } }; qsort(werte, 5, sizeof(werte[0]), compare_channel3); /* <-- hier. */ for(i = 0; i < 5; ++i) { printf("%f %f %f %f\n", werte[i][0], werte[i][1], werte[i][2], werte[i][3]); } return 0; }
-
Man kann auch eine Indexmenge sortieren und die "Vertauschungen" erst am Ende vornehmen.
-
Danke für die schnelle Hilfe.
"qsort" habe ich mir vorhin angesehen, aber damit hab ichs nicht hinbekommen.
Da gabs ein undefinierbares Programmverhalten (nicht sortiert, komischer Wert, der weit über 300 Stellen hatte - das konnte kein long double mehr sein :D). Da ich jedoch nicht wusste, wie ich den Fehler eingrenzen konnte und kein Beispiel anhand eines mehrdimensionalen Arrays fand, hatte ichs mit meinem Codefetzen versucht.Dann will ich doch mal schaun, ob ich das hiermit gelöst bekomme
-
Hmmm...so ganz einfach ists für mich immer noch nicht.
Die C-Variante spuckt Werte aus, die nicht so ganz meiner Vorstellung entsprechen:n: 2091: 1669.000000 9783.000000 95.683952 180.000421 n: 2091: 1082.000000 9783.000000 95.586549 180.000421 n: 2091: 998.000000 9842.000000 95.810003 180.115012 n: 2091: 496.000000 9820.000000 95.701141 179.903018 n: 2091: 389.000000 9797.000000 95.626656 179.903018 n: 2091: 897.000000 9812.000000 95.534983 179.943125 n: 2091: 1016.000000 9797.000000 95.758436 179.845722 n: 2091: 1585.000000 9820.000000 96.021997 179.662376 n: 2091: 1729.000000 9775.000000 95.981890 179.903018 n: 2091: 1118.000000 9775.000000 95.981890 179.903018 n: 2091: 1183.000000 9797.000000 95.758436 179.834263 n: 2091: 597.000000 9842.000000 95.477687 179.943125 n: 2091: 1957.000000 9790.000000 95.758436 179.943125 n: 2091: 1747.000000 9775.000000 96.188155 179.834263 n: 2091: 1979.000000 9827.000000 95.643845 179.943125 n: 2091: 101.000000 9820.000000 95.850110 179.834263 n: 2091: 956.000000 9768.000000 95.867298 179.903018 n: 2091: 59.000000 9783.000000 95.964701 179.834263 n: 2091: 664.000000 9834.000000 95.575090 179.903018 n: 2091: 1251.000000 9775.000000 95.701141 179.943125 n: 2091: 221.000000 9768.000000 95.907405 179.845722 n: 2091: 203.000000 9797.000000 95.586549 180.212415 n: 2091: 974.000000 9797.000000 96.073563 179.845722 n: 2091: 622.000000 9805.000000 95.850110 179.903018 n: 2091: 453.000000 9761.000000 95.981890 179.553514 n: 2091: 329.000000 9783.000000 95.810003 179.845722 n: 2091: 2023.000000 9856.000000 95.683952 180.172308 n: 2091: 77.000000 9797.000000 95.810003 180.115012 n: 2091: 724.000000 9753.000000 96.033456 179.776967 n: 2091: 892.000000 9761.000000 95.420391 179.903018 n: 2091: 910.000000 9797.000000 95.810003 180.000421 n: 2091: 1413.000000 9878.000000 95.683952 180.097824 n: 2091: 1100.000000 9797.000000 95.850110 179.736860 n: 2091: 790.000000 9849.000000 95.643845 180.000421 n: 2091: 868.000000 9775.000000 95.701141 179.834263 n: 2091: 514.000000 9702.000000 96.130859 179.553514 n: 2091: 1160.000000 9768.000000 95.964701 179.845722 n: 2091: 1142.000000 9820.000000 95.867298 179.845722 n: 2091: 1999.000000 9790.000000 96.073563 179.662376 n: 2091: 933.000000 9805.000000 95.850110 179.834263 n: 2091: 598.000000 9761.000000 95.964701 179.943125 n: 2091: 748.000000 9812.000000 95.586549 179.943125 n: 2091: 1915.000000 9783.000000 95.683952 179.903018 n: 2091: 1201.000000 9805.000000 95.758436 179.943125 n: 2091: 1058.000000 9775.000000 96.073563 179.553514 n: 2091: 1040.000000 9886.000000 95.363095 180.212415 n: 2091: 183.000000 9775.000000 95.420391 179.845722 n: 2091: 808.000000 9775.000000 95.964701 179.834263 n: 2091: 766.000000 9790.000000 95.850110 179.903018 Sortiert!
int compare_chan3(void const *lhs_v, void const *rhs_v) { double const *lhs = (double const *) lhs_v; double const *rhs = (double const *) rhs_v; return lhs[3] < rhs[3] ? -1 : (lhs[3] > rhs[3] ? 1 : 0); }
for (;;) // read sensor data & save to array - endless loop { usleep(SLEEPVALUE); std::vector<int> values; CHECK_OAK_CALL(readInterruptReport(deviceHandle, values)); const double mult2 = 180 / M_PI * pow(10.00, channelInfos[2].unitExponent); const double mult3 = 180 / M_PI * pow(10.00, channelInfos[3].unitExponent); messwerte[0][pet] = values[0]; messwerte[1][pet] = values[1]; messwerte[2][pet] = values[2] * mult2; messwerte[3][pet] = values[3] * mult3; // messwerte[4][pet] = // Logging der Temperatur - wie auslesen??? // For analyzing realtime data uncomment lines // printf("Ch0:\t%.2Lf\n", messwerte[0][pet]); // frame // printf("Ch1:\t%.2Lf\n", messwerte[1][pet]); // acceleration // printf("Ch2:\t%.2Lf\n", messwerte[2][pet]); // zenith // printf("Ch3:\t%.2Lf\n", messwerte[3][pet]-KORREKTURWERT); // azimuth // printf("Ch4:\t%.2Lf\n", messwerte[3][pet]); // temp ++net; // total cycles pet=(pet+1) % ARRAYSIZE; // array position // analysis of measurements qsort(messwerte, ARRAYSIZE, sizeof(messwerte[0][0]), compare_chan3); for (int i=0; i<ARRAYSIZE-1; i++) { printf("n: %d: \t%Lf\t%Lf\t%Lf\t%Lf\n", net, messwerte[0][i], messwerte[1][i], messwerte[2][i], messwerte[3][i]); } printf("\n\nSortiert!\n\n"); } // end of endless for-loop // Cleanup CHECK_OAK_CALL(closeDevice(deviceHandle)); return 0; }
Während die C++-Variante gerne c++11-kompatibel kompiliert werden möchte:
g++ -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT oaklinux.o -MD -MP -MF .deps/oaklinux.Tpo -c -o oaklinux.o oaklinux.cpp In file included from /usr/include/c++/4.7/array:36:0, from oaklinux.cpp:17: /usr/include/c++/4.7/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options. make: *** [oaklinux.o] Error 1
Was mich vor das Problem stellt, dass ich nicht weiß, wie/wo ich das dem automake-Makefile / configure mitteilen soll...
Meine Vermutung wäre die Makefile.am im Projektordner. Und dann dort ein make ausführen, was die Make-Datei im src-Unterordner aktualisiert.
Aber ich hab da um ehrlich zu sein keinen Überblick
-
Mische nie C und C++! Das wurde dir schon gesagt in anderen Threads.
Die nötigen Stichworte, wie du dich über configure&make kundig machen kannst, wurden dir auch schon genannt, in anderen Threads.
Programmiere nicht durch das Zusammenkopieren von Code aus dem Internet, besonders nicht, wenn du ihn nicht verstehst. Das wurde dir auch schon gesagt in anderen Threads.
Wie soll man dir helfen, wenn du keine Hilfe annimmst? Ja, das sind Ratschläge, die jeweils viel Arbeit für dich sind. Aber je länger du sie nicht beachtest, desto mehr Arbeit wird es für dich, wenn du sie letztlich doch befolgst. Und irgendwann musst du sie befolgen, denn das was du derzeit versuchst, wird niemals funktionieren.
Derzeit pickst du dir nur die Hilfe heraus, die du hören möchtest. Sachen, die kleine Fehler an deinem Programm oberflächlich ausbessern. Dies behebt vielleicht jeweils deine unmittelbaren Fehler, führt aber dann direkt zum nächsten, weil das ganze Grundgerüst nicht stimmt.
-
Da muss ich dir Recht geben. Aber als Anfänger ist es schwer, den Überblick zu behalten. Mit deinen Erfahrungswerten würde ich mir vermutlich nichts anderes raten.
Leider ist das mit dem Sensor dringend und ich muss noch viele weitere Aspekte als die Programmierung bei meinem Problem lösen - sonst würde ich mir lieber die Zeit nehmen und mein frisch erworbenes C++-Buch wälzen.
Hinsichtlich configure und make habe ich leider bisher keine wirklich aufschlussreiche Seite gefunden, auch wenn du mir bereits die relevanten Suchbegriffe geliefert hast.
-
Cysign schrieb:
Leider ist das mit dem Sensor dringend und ich muss noch viele weitere Aspekte als die Programmierung bei meinem Problem lösen - sonst würde ich mir lieber die Zeit nehmen und mein frisch erworbenes C++-Buch wälzen.
Dann musst du eben jemanden dafür bezahlen. Mit deinen jetzigen Kenntnissen wird es nichts, das kann dir jeder hier bestätigen. Du wirst bloß weiter rumpfuschen und am Ende hast du weder dein Problem gelöst, noch irgendetwas gelernt. Man kann eben einfach nicht mal eben so ungelernt mit Werkzeugen arbeiten, deren Benutzung man normalerweise monatelang lernen müsste, und am Ende ein Ergebnis erwarten.
-
Jemandem, der nicht programmieren kann, würde ich bei Tabellenproblemen zu einer Software raten, die darauf spezialisiert ist. Gibt da glaube ich seit längerem eine von Microsoft und im Open-Source-Bereich versuchen sich glaube ich auch schon ein paar Jungs daran.
-
Versetzt und mit 4 Bier saß ich zuhause.
Und weil Cysign einen geraden Satz schreiben kann, hab' ich mich mal an einem kleinen Refactoring seines original Codes versucht.
Das Oak-Dingsbums hat schon ein fürchterliches C/C++ Gemisch in der Schnittstelle. Mangels Testmöglichkeiten bin ich nicht viel besser, aber etwas.
(Im Sinne von: von dieser Version zu OO ist es nur ein kleiner Sprung.)#include <array> #include <cmath> // M_1_PI (on my platform) #include <iostream> #include <stdexcept> #include <string> #include <thread> #include <vector> #include "OakHidBase.h" #include "OakFeatureReports.h" struct oak_exception : std::runtime_error{ typedef std::runtime_error base; oak_exception(const char* what) : base(what) {} }; struct oak_status{ explicit oak_status(Toradex::Oak::EOakStatus status){ if( status != Toradex::Oak::eOakStatusOK ) throw oak_exception(Toradex::Oak::getStatusString(status).c_str()); } }; typedef Toradex::Oak::DeviceInfo device_info_t; typedef Toradex::Oak::EOakLedMode led_mode_t; typedef Toradex::Oak::EOakReportMode report_mode_t; typedef int oak_device_handle; typedef std::vector<Toradex::Oak::ChannelInfo> channel_info_table; typedef unsigned rate_t; typedef std::array<double, 4> sample_t; std::ostream& operator<<(std::ostream& out, const sample_t& sample){ return out << sample[0] << ' ' << sample[1] << ' ' << sample[2] << ' ' << sample[3]; } oak_device_handle oak_open(const std::string& path = "/dev/usb/hiddev0"){ using namespace Toradex::Oak; oak_device_handle h; oak_status(openDevice(path, h)); return h; } void oak_close(oak_device_handle& h){ oak_status(Toradex::Oak::closeDevice(h)); } Toradex::Oak::DeviceInfo device_info(oak_device_handle h){ device_info_t info; oak_status(Toradex::Oak::getDeviceInfo(h, info)); return info; } report_mode_t report_mode(oak_device_handle h, bool persistent){ report_mode_t mode; oak_status(Toradex::Oak::getReportMode(h, mode, persistent)); return mode; } report_mode_t report_mode(oak_device_handle h, report_mode_t mode, bool persistent){ using namespace Toradex::Oak; const report_mode_t ret(report_mode(h, ret, persistent)); oak_status(setReportMode(h, mode, persistent)); if( report_mode(h, persistent) != mode ) throw oak_exception("Setting the report mode failed."); return ret; } led_mode_t led_mode(oak_device_handle h, bool persistent){ led_mode_t mode; oak_status(Toradex::Oak::getLedMode(h, mode, persistent)); return mode; } led_mode_t led_mode(oak_device_handle h, led_mode_t mode, bool persistent){ using namespace Toradex::Oak; const led_mode_t ret(led_mode(h, persistent)); oak_status(setLedMode(h, mode, persistent)); if( led_mode(h, persistent) != mode ) throw oak_exception("Setting the led mode failed."); return ret; } rate_t sample_rate(oak_device_handle h, bool persistent){ rate_t rate; oak_status(Toradex::Oak::getSampleRate(h, rate, persistent)); return rate; } rate_t sample_rate(oak_device_handle h, rate_t mode, bool persistent){ using namespace Toradex::Oak; const rate_t ret = sample_rate(h, persistent); oak_status(setSampleRate(h, mode, persistent)); if( sample_rate(h, persistent) != mode ) throw oak_exception("Setting the sample rate failed."); return ret; } rate_t report_rate(oak_device_handle h, bool persistent){ rate_t ret; oak_status(Toradex::Oak::getReportRate(h, ret, persistent)); return ret; } rate_t report_rate(oak_device_handle h, rate_t mode, bool persistent){ using namespace Toradex::Oak; const rate_t ret = report_rate(h, persistent); oak_status(setReportRate(h, mode, persistent)); if( report_rate(h, persistent) != mode ) throw oak_exception("Setting the report rate failed."); return ret; } channel_info_table channel_info(oak_device_handle h){ using namespace Toradex::Oak; channel_info_table infos; const int size = device_info(h).numberOfChannels; infos.resize(size); for ( int i=0; i<size; ++i ){ oak_status(getChannelInfo(h, i, infos[i])); } return infos; } sample_t sample(oak_device_handle h){ using namespace Toradex::Oak; std::vector<int> irq_reports; irq_reports.reserve(4); oak_status(readInterruptReport(h, irq_reports)); const channel_info_table infos = channel_info(h); const double mult2 = 180 * M_1_PI * pow(10.00, infos[2].unitExponent); const double mult3 = 180 * M_1_PI * pow(10.00, infos[3].unitExponent); return sample_t {{ static_cast<double>(irq_reports[0]) , static_cast<double>(irq_reports[1]) , irq_reports[2]*mult2 , irq_reports[3]*mult3 }}; } int main(){ typedef std::vector<sample_t> data_table; const std::chrono::milliseconds sleepval(230); const rate_t delay = 20; const int s_cnt = 100000; try{ oak_device_handle handle = oak_open(); report_mode(handle, Toradex::Oak::eReportModeAfterSampling); led_mode (handle, Toradex::Oak::eLedModeOff); report_rate(handle, delay); sample_rate(handle, delay); data_table samples; samples.reserve(s_cnt); for( int i=0; i<s_cnt; ++i ){ std::this_thread::sleep_for(sleepval); samples.emplace_back(sample(handle)); } oak_close(handle); for(auto s : samples) std::cout << s << '\n'; } catch(const oak_exception& e){ std::cerr << e.what() << '\n'; return -1; } }
-
Cysign schrieb:
qsort(messwerte, ARRAYSIZE, sizeof(messwerte[0][0]), compare_chan3);
Meintest du
qsort(messwerte, ARRAYSIZE, sizeof(messwerte[0]), compare_chan3);
?
Das Array besteht aus ARRAYSIZE Elementen der Größe sizeof(messwerte[0]), nicht aus ARRAYSIZE Elementen der Größe sizeof(messwerte[0][0]), nehme ich an. Ich gehe hier von der Vermutung aus, dass messwerte
double messwerte[ARRAYSIZE][5];
ist.
-
Also kompilieren kann ich die C++-Geschichte, indem ich in der Makefile bei den CXX-Flags ein -std=gnu++11 anhänge:
CXXFLAGS = -g -O2 -std=gnu++11
Ist das denn so gedacht? Ich bin davon ausgegangen, dass man in der configure etwas ändern muss und damit die Makefile automatisch angepasst generiert wird. Aber mir solls erstmal recht sein, dass ich nun c++11 kompilieren kann.
Gestern Abend habe ich noch eine Weile mit einem befreundeten Programmierer geskypet, der mir noch ein paar Sachen erklären konnte.
Als Webprogrammierer (Python, PHP,...) konnte er sich relativ schnell in die Syntax einlesen und mir anhand eines kleinen Beispielcodes ein Sortierung demonstrieren.Ein wichtiger Aspekt für mich war, dass der Datentyp vector eigentlich das ist, was ich mir von Anfang an als Array gewünscht hatte - ausgehend davon, dass ich nach Sachen wie push und pop in Arrays in diesem Zusammenhang gegoogelt hatte und nicht fündig wurde. Aber ohne mich näher diesbezüglich informiert zu haben, hatte ich das mit einem mathematischen Vektor assoziiert und nicht weiter verfolgt.
@Decimad: Danke für deinen konstruktiven Vorschlag.
Ich habe mal nach "Tabellenproblemen paar Jungs Open-Source-Bereich" gesucht, jedoch konnte ich nicht herausfinden, welches Programm du mir nahelegen möchtest, um einen Sensor in Echtzeit auszuwerten, Ausreißer zu analysieren, Werte zu filtertern, Korrekturwerte einzurechnen und einen präzisen Messwert auszugeben. Vielleicht bin ich auch einfach zu unerfahren, deine äußerst Hilfreiche Antwort richtig zu interpretieren... Dennoch vielen Dank für deine Mühen.@SeppJ: Genau das war Anfangs der Plan. Ich telefonierte also sämtliche Bekannte und Freunde ab, die auch nur annähernd etwas mit Programmierung zu tun haben könnten. Leider konnte mir niemand einen Programmierer empfehlen, der in dieser Hinsicht Erfahrungen hat und mir weiterhelfen kann.
Also habe ich mich selbst ran gemacht, den gewünschten Sensor zu untersuchen.
Und nachdem mein Code zur Analyse stand, konnte ich abwägen, dass der verwendete Sensor nicht für meinen Zweck tauglich ist. Ich hatte mehrmals mit dem Hersteller Kontakt, der das von mir angeprangerte Verhalten seines Sensors nicht kannte, es aber mit unterschiedlichen Sensoren der selben Modellreihe nachvollziehen, jedoch nicht erklären konnte.
Aus diesem Grund habe ich meine Versuche auf Basis des ersten Sensors eingestellt und befasse mich nun mit diesem Sensor, der scheinbar die Anforderungen erfüllen könnte - zumindest nach einer manuellen Auswertung der Daten nach zu urteilen.Die Ausgabe von Furbles Code liefert übrigens:
20 9768 95.8673 179.737 125 9812 95.4605 180 221 9761 95.7985 179.513 327 9731 95.9819 179.794 430 9805 95.7584 179.834 526 9739 95.684 179.611 633 9775 95.7985 180 739 9768 95.7985 180.172 835 9842 95.7412 180.098 939 9768 95.9074 179.777 1044 9783 95.81 179.737 1140 9797 95.81 179.834 1244 9820 95.684 180 1348 9731 95.9819 179.611 1444 9805 95.7584 179.777 714 9761 96.0335 179.68 810 9761 95.7011 179.794 923 9820 95.7985 179.834 1018 9746 95.7011 179.611 1114 9768 95.7011 179.903 1229 9775 96.0736 179.777 1325 9805 95.5865 179.834 1421 9805 95.7584 179.846 1533 9731 95.9246 179.622 1629 9820 95.8501 179.943 1725 9797 95.8501 179.777 1836 9820 95.7011 179.846 1934 9827 95.6267 179.903 2029 9820 95.7011 180.041 91 9797 95.7584 179.834 190 9768 95.7985 179.846 1493 9753 95.8501 179.622 1589 9746 95.8673 179.777 1688 9842 95.7985 180 1795 9842 95.6438 179.834 1891 9797 96.022 179.846 1990 9820 95.535 180 52 9827 95.4777 180.172 148 9768 95.7985 179.777 244 9827 95.4605 180.041 357 9812 95.5865 180.041 453 9768 95.6438 179.777 549 9812 95.8673 180 663 9761 95.5751 179.777 759 9775 95.8673 179.737 855 9797 95.9074 179.737 115 9805 95.7985 179.777 175 9761 95.8673 179.737 291 9820 95.535 179.903 387 9805 95.7011 179.846 483 9856 95.4777 179.943 595 9783 95.9647 179.68 690 9761 95.9819 179.68 786 9797 95.7584 179.68 900 9805 95.9819 179.943 996 9775 95.8673 179.777 1092 9753 95.9246 179.737 1206 9775 95.9074 179.846 1302 9797 96.2053 179.777 1398 9834 95.81 180.264 1511 9812 95.7584 179.834 1607 9820 95.7985 179.846 871 9790 95.7584 179.846 967 9842 95.4204 179.846 1068 9805 95.7985 179.777 1179 9827 95.6267 179.903 1274 9746 96.0335 179.622 1372 9775 95.9074 179.834 1484 9768 95.8673 179.903 1580 9768 96.0335 179.846 1676 9761 96.0908 179.834 1790 9790 95.7412 179.903 1886 9834 95.6438 180 1982 9783 96.0335 179.68 45 9746 95.5751 179.846 141 9790 95.7412 179.846 237 9797 96.022 179.834 1544 9790 96.2053 179.777 1586 9717 95.81 179.737 1700 9820 95.684 179.903 1796 9812 95.7011 179.903 1892 9805 95.9246 179.777 2005 9761 96.0908 179.737 53 9783 95.81 180 149 9768 95.8673 179.68 261 9797 96.1309 179.834 357 9761 95.9074 179.737 453 9820 95.7011 179.846 565 9768 95.5751 179.68 661 9790 95.5178 179.903 757 9783 95.8501 179.834 870 9775 95.8673 179.777 966 9783 95.6438 179.777 234 9790 95.9074 179.737 330 9805 95.7584 179.903 443 9820 95.4605 179.834 542 9812 95.684 180.115 638 9812 95.8673 179.737 743 9827 95.5751 179.903 844 9797 95.8501 179.846
Ich habe das Programm mehrmals ausgeführt und konnte keine Ausreißer mehr feststellen!
Großes Lob und Dank an Furble!Hinsichtlich SeppJs Beispiel:
array<array<int, 3>, 4> foo = {{{{1,6,8}},{{4,2,7}},{{8,3,1}},{{9,3,4}}}};
array<datentyp, größe> namedesarrays = ...
In wiefern unterscheidet sich dieses Array von einem Vector in der Möglichkeit der Sortierung? Könnte man beide Konstrukte (Array/Vector) auf die hier vorgeschlagene Art
sort(foo.begin(), foo.end(), compare_by_column<array<int, 3>, 1>);
sortieren?
Wäre es denn sinnvoller auf vector oder array zu setzen?
Ich möchte die Daten auslesen, eine kleine Menge (beispielsweise 50-200 Werte) sammeln, korrigieren.
Zum Korrigieren muss ich ein zweites Programm schreiben, das, nachdem der Sensor in verschiedene Positionen gebracht wurde, dort Messwerte aufnimmt und als Datei abspeichert.
Das eigentliche Programm liest später diese Werte aus der Datei ein und wertet die Winkel aus. Anhand der gespeicherten Werte aus der Datei wird nun eine Korrektur vorgenommen.
Noch zum Verständnis:
samples.reserve(s_cnt); ist quasi das malloc des C++.
But unlike arrays, their size can change dynamically, with their storage being handled automatically by the container. (http://www.cplusplus.com/reference/vector/vector/ )
Ich hatte das so verstanden, dass eine manuelle Reservierung in diesem Fall nicht nötig sei. Und muss der Speicher nicht wieder freigegeben (vgl. C free()) werden?
@Seldon:
qsort(messwerte, ARRAYSIZE, sizeof(messwerte[0][0]), compare_chan3);
Meintest du
qsort(messwerte, ARRAYSIZE, sizeof(messwerte[0]), compare_chan3);
?[/quote]
Das dachte ich auch zunächst. Jedoch hat array[] im Gegensatz zu array[][] immer ein "Segmentation fault (core dumped)" ausgegeben. Den Fehler kannte ich nur, wenn auf einen unexistenten Bereich eines Arrays zugegriffen wird - und so versuchte ich array[][] und dieser Fehler trat nicht mehr auf.
-
Cysign schrieb:
@Decimad: Danke für deinen konstruktiven Vorschlag.
Ich habe mal nach "Tabellenproblemen paar Jungs Open-Source-Bereich" gesucht, jedoch konnte ich nicht herausfinden, welches Programm du mir nahelegen möchtest, um einen Sensor in Echtzeit auszuwerten, Ausreißer zu analysieren, Werte zu filtertern, Korrekturwerte einzurechnen und einen präzisen Messwert auszugeben. Vielleicht bin ich auch einfach zu unerfahren, deine äußerst Hilfreiche Antwort richtig zu interpretieren... Dennoch vielen Dank für deine Mühen.Open Office, Libre Office, GNU R, usw.
Du brauchst keine eierlegende Wollmilchsau.
Unix Philosophie schrieb:
Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.
Schreib ein Programm, dass deinen Sensor ausliest. Datenauswertung machst du dann mit einem Datenauswertungsporgramm.
@SeppJ: Genau das war Anfangs der Plan. Ich telefonierte also sämtliche Bekannte und Freunde ab, die auch nur annähernd etwas mit Programmierung zu tun haben könnten. Leider konnte mir niemand einen Programmierer empfehlen, der in dieser Hinsicht Erfahrungen hat und mir weiterhelfen kann.
Wieso fragst du denn Freunde und Bekannte? Wenn du ein neues Auto brauchst, fragst du dann Freunde und Bekannte, ob sie dir eines bauen können? Und wenn nicht, dann baust du es selber? Nein, du gehst zu jemandem, der sich mit so etwas auskennt.
Hinsichtlich SeppJs Beispiel:
array<array<int, 3>, 4> foo = {{{{1,6,8}},{{4,2,7}},{{8,3,1}},{{9,3,4}}}};
array<datentyp, größe> namedesarrays = ...
In wiefern unterscheidet sich dieses Array von einem Vector in der Möglichkeit der Sortierung?
Gar nicht. Das ist doch das schöne an Programmierung im Stil der STL. Du bist vollkommen unabhängig vom Datentyp. Ich wählte ein statisches Array, weil du ein statisches Array hattest. Ich nahm (fälschlicherweise?) an, dass dahinter irgendein tieferer Sinn stand.
Könnte man beide Konstrukte (Array/Vector) auf die hier vorgeschlagene Art
sort(foo.begin(), foo.end(), compare_by_column<array<int, 3>, 1>);
sortieren?
Ja. Zumindest wenn der innere Typ array<int, 3> bleibt. Ansonsten musst du der compare_by_column-Funktion noch den richtigen Typen geben. Das kann man natürlich auch noch automatisieren.
Wäre es denn sinnvoller auf vector oder array zu setzen?
Das kommt drauf an. vector ist flexibel in der Länge, array nicht. In vector sollte immer die Standardwahl sein, wenn man davon abweicht, sollte man dies Begründen. Eine Begründung (besser: Die Begründung) für Array ist, dass man die Anzahl der Datensätze zur Compilezeit kennt.
Ich möchte die Daten auslesen, eine kleine Menge (beispielsweise 50-200 Werte) sammeln, korrigieren.
Klingt nach vector, da "kleine Menge" und "50-200" unspezifische Größen sind.
samples.reserve(s_cnt); ist quasi das malloc des C++.
vector ist das malloc des C++
.
-
SeppJ schrieb:
Wäre es denn sinnvoller auf vector oder array zu setzen?
Das kommt drauf an. vector ist flexibel in der Länge, array nicht. In vector sollte immer die Standardwahl sein, wenn man davon abweicht, sollte man dies Begründen. Eine Begründung (besser: Die Begründung) für Array ist, dass man die Anzahl der Datensätze zur Compilezeit kennt.
Ein starker Grund gegen das Array ist, dass es so schlecht movable ist. Einen
vector<array>
zu sortieren sollte man besser vermeiden, besser istvector<vector>
.SeppJ schrieb:
samples.reserve(s_cnt); ist quasi das malloc des C++.
vector ist das malloc des C++
.
Besser nicht, reserve macht nicht das, was du willst, denn die Grösse des Vektors bleibt gleich.
Du möchtest
resize
.
-
korrigendum schrieb:
Einen
vector<array>
zu sortieren sollte man besser vermeiden, besser istvector<vector>
.Dafür sollte man vector<vector> allgemein vermeiden. Falls die innere Datenstruktur zu teuer zu swappen ist, dann benutzt man, wie hier im Thread schon vorgeschlagen, eine Indexliste.
-
Wenn ich das Programm kompiliere, steht fest, aus wie vielen Werten ich mitteln möchte. Jetzt zum Testen wähle ich hier einen eher kleineren Wert (z.B. 50), damit ich schneller meine Testausgaben abgreifen kann. Später wird der Wert eher größer sein, um beim Mitteln einen möglichst aussagekräftigen Wert zu bekommen (eher um die 200 oder gar mehr).
Also beim Testen:
50(Werte) * 4-5(Kanäle)Hinterher, wenn alles funktionert:
z.B. 200 * 5 KanäleDeswegen hatte ich das bei meinen ersten Versuchen mit
#define ARRAYSIZE 50
gelöst, um lediglich einen Wert ändern zu müssen beim Testen.
Dass ich mir Tabellenkalkulationsprogrammen Daten auswerten kann, ist mir klar.
Aber in benötige später Werte, die bereits aussagekräftig sind - und dazu gehört die Relation der Daten auf Grund verschiedenen Kanäle.Und wenn ich ein Auto kaufen möchte, frage ich auch zunächst Freunde und
Bekannte - nämlich welchen Händler und welche Marke sie mir empfehlen können.
Das heißt ja nicht, dass sie mir das Auto bauen sollen. Wenn ich aber mangels Empfehlung und Erfahrung keinen Händler finde...muss ich das (Transport-)Problem eben anderst lösenBzgl. "zu teuer zu swappen" = zu aufwändig oder zu viel Overhead?
Und was sollte man hier als Richtwert nehmen?
-
Cysign schrieb:
Bzgl. "zu teuer zu swappen" = zu aufwändig oder zu viel Overhead?
Was ist denn da der Unterschied?
Und was sollte man hier als Richtwert nehmen?
Wenn es dir zu langsam ist und die andere Methode schneller ist
. Oder wenn du eine technischere Antwort möchtest: Wenn der Mehraufwand durch die Indirektion kleiner ist als die Mehrkosten des Swappens des Originaltyps gegenüber den Kosten des Swappens eines size_t. Oder wenn du willkürlich aus der Luft gegriffene Zahlen haben möchtest, die bei vielen Problemstellungen passen und bei anderen wiederum absolut nicht: Wenn sizeof(Datentyp) > 5*sizeof(size_t).