efekt_motyla Temat założony przez niniejszego użytkownika |
» 2016-08-24 23:09:23 Dziękuję! :) Wszystko działa :) Tak jak doszedłeś wcześniej, chciałem zrobić program dla współrzędnych a dokładnie [x,y,z]. Dopisałem tylko zeta :). #include <iostream> #include <fstream> #include <vector>
template < typename T > void interpolate( std::vector < T >& numbers ) { for( auto i = 0u; i + 1 < numbers.size(); i++ ) { if( numbers[ i + 1 ] == 0 ) { auto beginVal = numbers[ i ]; auto index = i; while( numbers[ ++i ] == 0 ) continue; auto endVal = numbers[ i ]; auto diff = i - index; i = index; while( numbers[ ++i ] == 0 ) numbers[ i ] = beginVal +( endVal - beginVal ) / diff *( i - index ); } } }
int main() { std::ifstream in( "liczby.txt" ); std::vector < double > x; std::vector < double > y; std::vector < double > z; for( int i, j, k; in >> i >> j >> k; ) { x.push_back( i ); y.push_back( j ); z.push_back( k ); } interpolate( x ); interpolate( y ); interpolate( z ); for( auto i = 0u; i < x.size() && i < y.size(); ++i ) std::cout << "Klatka: " << i << " [" << x[ i ] << ", " << y[ i ] << ", " << z[ i ] << "]" << std::endl; return 0; }
I jest super; ).dzi ę kuje
Jeszcze ostatnia sprawa , ponieważ chciałbym zera zamienić na pustą linijkę, to za pomocą jakiej funkcji to zrobić ? Pustą linijkę wczytać jako: " " ?? |
|
Gibas11 |
» 2016-08-25 00:23:09 To uzna linię za pustą, jeśli jest w niej tylko ciąg znaków „EMPTY”. Bez jakiejkolwiek kontroli poprawności danych na wyjściu. #include <algorithm> #include <iostream> #include <fstream> #include <sstream> #include <string> #include <vector>
template < typename T > void interpolate( std::vector < T >& numbers, std::vector < size_t >& emptyLines ) { for( auto i = 0u; i + 1 < numbers.size(); i++ ) { if( std::find( emptyLines.begin(), emptyLines.end(), i + 1 ) != emptyLines.end() ) { auto beginVal = numbers[ i ]; auto index = i; while( std::find( emptyLines.begin(), emptyLines.end(), ++i ) != emptyLines.end() ) continue; auto endVal = numbers[ i ]; auto diff = i - index; i = index; while( std::find( emptyLines.begin(), emptyLines.end(), ++i ) != emptyLines.end() ) numbers[ i ] = beginVal +( endVal - beginVal ) / diff *( i - index ); } } }
int main() { std::ifstream in( "liczby.txt" ); std::vector < double > x; std::vector < double > y; std::vector < double > z; std::vector < size_t > emptyLines; std::string line; for( size_t i = 0u; getline( in, line ); ++i ) { double X, Y, Z; if( line == "EMPTY" ) { emptyLines.push_back( i ); X = Y = Z = 0; } else { std::stringstream stream( line ); stream >> X >> Y >> Z; } x.push_back( X ); y.push_back( Y ); z.push_back( Z ); } interpolate( x, emptyLines ); interpolate( y, emptyLines ); interpolate( z, emptyLines ); for( auto i = 0u; i < x.size() && i < y.size(); ++i ) std::cout << "Klatka: " << i << " [" << x[ i ] << ", " << y[ i ] << ", " << z[ i ] << "]" << std::endl; return 0; }
Wprawdzie mógłbym nie wrzucać niepotrzebnych zer do vectora i dodawać je tam potem, ale i tak trzeba koniec końców zaalocować tą pamięć i za dużo z tym zachodu, żebym się w tym grzebał o tej godzinie. :P |
|
efekt_motyla Temat założony przez niniejszego użytkownika |
» 2016-08-25 21:59:44 no tak :). Właśnie zapomniałem napisać, że jeżeli np "x" jest pusty , to i "y" oraz "z" także. Czyli uznajemy całą linię za pustą (pomijając fakt że co jeśli x jest pusty a y i z mają wartosci*(taki przypadek wykluczam,) ). Analizuje kod który mi wysłałeś, gdzieś musi być błąd ponieważ na wyjściu dostaje powtarzające się liczby.
np dla:
12 12 20 13 14 21 14 14 22
18 18 26 19 19 27 20 20 28
otrzymuję wynik:
Klatka: 0 [12, 12, 20] Klatka: 1 [13, 14, 21] Klatka: 2 [14, 14, 22] Klatka: 3 [14, 14, 22] Klatka: 4 [14, 14, 22] Klatka: 5 [14, 14, 22] Klatka: 6 [18, 18, 26] Klatka: 7 [19, 19, 27] Klatka: 8 [20, 20, 28]
Process returned 0 (0x0) execution time : 0.023 s Press any key to continue.
|
|
Gibas11 |
» 2016-08-25 23:01:36 Przeczytaj dokładnie mój kod. :P Linia jest uznawana za pustą nie gdy jest pusta (a jak ktoś da tam spację? ;-;), tylko kiedy znajduje się w niej tylko słowo „EMPTY”. //edit: 12 12 20 13 14 21 14 14 22 EMPTY EMPTY EMPTY 18 18 26 19 19 27 20 20 28
Wynik: Klatka: 0 [12, 12, 20] Klatka: 1 [13, 14, 21] Klatka: 2 [14, 14, 22] Klatka: 3 [15, 15, 23] Klatka: 4 [16, 16, 24] Klatka: 5 [17, 17, 25] Klatka: 6 [18, 18, 26] Klatka: 7 [19, 19, 27] Klatka: 8 [20, 20, 28]
|
|
efekt_motyla Temat założony przez niniejszego użytkownika |
» 2016-08-25 23:58:10 Odrazu się za czytanie kodu, a nie przeczytałem tego co powyżej napisałęś... :) . Fajnie działa, dziękuje ! :)
zamieniłem
line == Empty na line == "" || linie==" " || line==" "
hehe ;) i jest tak jak chciałem :) Dziękuje jeszcze raz, no i dodatkowo dowiedziałem się do czego służą kontenery oraz typ zmiennej 'auto' o którym wcześniej nie słyszałem.
Pozdrawiam. |
|
efekt_motyla Temat założony przez niniejszego użytkownika |
Interpolacja Lagrange'a » 2016-09-01 23:11:44 Dobry wieczór. Mam jeszcze jedno pytanie . Po interpolacji liniowej chciałem zrobić program, który liczyłby mi interpolacje lagrange'a. Zrobiłem to dla 4 skrajnych punktów, a dokładnie dla dwóch punktów znajdujących się "poniżej " niewiadomych oraz wziołem dwa punkty "powyżej" niewiadomych. W programie zakładamy, że brakuje mi całej linijki ( czyli jeśli nie ma x to nie ma tez y oraz z (jak poprzednio :) ) ). Punktem zaczepienia jest dla mnie sekunda. (zamiast pustej linijki wstawiłem zera.... (poniżej wyjaśniam dlaczego :) ) ) czyli na przykład dla współrzędnych: sekunda x y z 0 12 111 1000 1 13 122 2000 2 14 133 3000 3 0 0 0 4 0 0 0 5 0 0 0 6 0 0 0 7 0 0 0 8 0 0 0 9 0 0 0 10 0 0 0 11 23 232 12000 12 24 243 13000 13 25 154 14000 będą to punkty: A=(1,13), B=(2,14), C=(11,23), D=(12,24) , tak wyliczę x. Następnie mając x wyliczę w podobny sposób y oraz z. Chodzi o to czy tak można obliczyć współrzędne za pomocą interpolacji lagrage'a ??? Jeśli moje myślenie jest poprawne to , chciałbym po raz kolejny proszę o pomoc związaną z czytaniem linijek... :). Mianowicie chciałbym aby to wyglądało tak : zamiast zer są spacje (lub Empty, tak jak pomogłeś mi ostatnio :) ) , ale .... musi zostać ta pierwsza kolumna z sekundami (to ona rana jest jako punkt zachaczenia. Proszę o pomoc jeszcze raz. ( Czy to będzie coś z zamianą stringa na inta w czyaniu linii ???) To program który zrobiłem (raczej przerobiłem program który wczesniej pomógł mi napisać użytkownik Gibas11 (dziękuję !)) #include <iostream> #include <fstream> #include <vector>
template < typename T > void interpolacja( std::vector < T >& czas, std::vector < T >& x ) { for( auto i = 0u; i + 1 < x.size(); i++ ) { if( x[ i + 1 ] == 0 ) { auto czas1 = czas[ i - 1 ]; auto czas2 = czas[ i ]; auto punktA = x[ i - 1 ]; auto punktB = x[ i ]; auto index = i; while( x[ ++i ] == 0 ) continue; auto czas3 = czas[ i ]; auto czas4 = czas[ i + 1 ]; auto punktC = x[ i ]; auto punktD = x[ i + 1 ]; double diff = i - index; i = index; while( x[ ++i ] == 0 ) x[ i ] =( punktA *(( czas[ i ] - czas2 ) *( czas[ i ] - czas3 ) *( czas[ i ] - czas4 ) ) /(( czas1 - czas2 ) *( czas1 - czas3 ) *( czas1 - czas4 ) ) ) + ( punktB *(( czas[ i ] - czas1 ) *( czas[ i ] - czas3 ) *( czas[ i ] - czas4 ) ) /(( czas2 - czas1 ) *( czas2 - czas3 ) *( czas2 - czas4 ) ) ) + ( punktC *(( czas[ i ] - czas1 ) *( czas[ i ] - czas2 ) *( czas[ i ] - czas4 ) ) /(( czas3 - czas1 ) *( czas3 - czas2 ) *( czas3 - czas4 ) ) ) + ( punktD *(( czas[ i ] - czas1 ) *( czas[ i ] - czas2 ) *( czas[ i ] - czas3 ) ) /(( czas4 - czas1 ) *( czas4 - czas2 ) *( czas4 - czas3 ) ) ); } } }
int main() { std::ifstream in( "liczby.txt" ); std::vector < double > sekunda; std::vector < double > x; std::vector < double > y; std::vector < double > z; for( int i, j, k, l; in >> i >> j >> k >> l; ) { sekunda.push_back( i ); x.push_back( j ); y.push_back( k ); z.push_back( l ); } interpolacja( sekunda, x ); interpolacja( x, y ); interpolacja( y, z ); for( auto r = 0u; r < sekunda.size() && r < x.size(); ++r ) std::cout << sekunda[ r ] << " " << x[ r ] << " " << y[ r ] << " " << z[ r ] << std::endl; return 0; }
|
|
Gibas11 |
» 2016-09-01 23:43:59 for( std::string line; getline( in, line ); ) { int i, j, k, l; std::stringstream lineStream( line ); lineStream >> i; if( lineStream.str().find( "EMPTY" ) != std::string::npos ) j = k = l = 0; else lineStream >> j >> k >> l; sekunda.push_back( i ); x.push_back( j ); y.push_back( k ); z.push_back( l ); }
Kod na tyle krótki, że raczej się połapiesz. Nie dam dokładnych komentarzy bo lecę spać. :P W skrócie, ładuję stringa do strumienia, pobieram liczbę pozbywając się jej, sprawdzam czy w reszcie jest ciąg "EMPTY" i jeśli nie to wczytuję z tego samego strumienia kolejne liczby. Pamiętaj o #include <sstream> na początku. Plik, którego użyłem do testów wyglądał tak: 0 12 111 1000 1 13 122 2000 2 14 133 3000 3 EMPTY 4 EMPTY 5 EMPTY 6 EMPTY 7 EMPTY 8 EMPTY 9 EMPTY 10 EMPTY 11 23 232 12000 12 24 243 13000 13 25 154 14000
I dał takie wyniki: 0 12 111 1000 1 13 122 2000 2 14 133 3000 3 15 144 4000 4 16 155 5000 5 17 166 6000 6 18 177 7000 7 19 188 8000 8 20 199 9000 9 21 210 10000 10 22 221 11000 11 23 232 12000 12 24 243 13000 13 25 154 14000
//edit: Poprawiłem błąd. ;-; Poprzedni nie wyłapywał „pustości” linii i zostawiał dane z poprzedniego obiegu pętli poza pierwszą zmienną. Zawiła sprawa, ale już chyba działa. :D |
|
efekt_motyla Temat założony przez niniejszego użytkownika |
» 2016-09-02 00:06:37 Hmm tylko wtedy liczy samego x-a a y i z są błędne ponieważ cały czas się powtarzają w pustych miejscach :) |
|
1 « 2 » 3 4 |