|
| øhh... varierende størrelse på et array Fra : Kåre Rasmussen |
Dato : 17-04-01 09:25 |
|
Hej allesammen.
Jeg havde ikke lige forventet at der ville blive så meget debat om mit
indlæg, så jeg starter lige en ny tråd, med en stor tak til alle de folk der
postede svar på mit indlæg.
Jeg fik i påsken leget med vector-funktionen, men det volder mig stadig lidt
problemer: Det jeg forsøger at løse med mit program er følgende (og
forklaringen er nok lidt lang).
Jeg har en mængde rådata på følgende form:
dato tid flow
(d-m-å) (t:m:s) (m/s)
01-01-99 00:00:01 3.55
..
01-01-99 01:01:05 2.56
..
01-01-99 03:05:45 1.22
..
..
02-01-99 00:00:04 1.23
..
02-01-99 01:10:23 1.23
Der er så en fil pr. uge og data for et år (52 uger), men mængden af data
kan varierer fra time til time.
Min opgave er at midle flow-data for hver time, hvilket jeg havde forstillet
mig gjort ved følgende.
Test på datoen
Test på tiden
Når dagen er 01 og tiden(timen) er 00, så skal flow summeres og tilsidst
midles
Når dagen er 01 og tiden(timen) er 01, så skal flow summeres og tilsidst
midles
Det nemmeste (som jeg ser det) er at hente hele filen ind i et array (ex:
LinieArray), så :
LinieArray[0]=01-01-99 00:00:01 3.55
LinieArray[1]=01-01-99 00:00:03 2.55
osv.
Herefter løbe alle elementerne i LinieArray igennem og i første omgang teste
på om ciffer 1 og 2 = 01, om ciffer 7 og 8 = 00 (dag 1, time 0). I de
tilfælde de er opfyldt skal flow-data summeres og skrives til en ny fil.
Derefter teste på om ciffer 1 og 2 = 01, om ciffer 7 og 8 = 01 (dag 1, time
1). I de tilfælde de er opfyldt skal flow-data summeres og skrives til en ny
fil.
osv.
Jeg er fuldstændig newbie så jeg ved minus om C++, men vil meget gerne lære
det, så alle forslag har interesse (det inkludere links mm.)
På forhånd tak
Kåre Rasmussen
| |
Bjarne Laursen (17-04-2001)
| Kommentar Fra : Bjarne Laursen |
Dato : 17-04-01 13:04 |
|
"Kåre Rasmussen" <kmra99@i4.auc.dk> wrote:
>Jeg har en mængde rådata på følgende form:
>
>dato tid flow
>(d-m-å) (t:m:s) (m/s)
>01-01-99 00:00:01 3.55
>Det nemmeste (som jeg ser det) er at hente hele filen ind i et array (ex:
>LinieArray), så :
>LinieArray[0]=01-01-99 00:00:01 3.55
>LinieArray[1]=01-01-99 00:00:03 2.55
Jeg kan nu ikke se nogen grund til at hente filen ind i et array
først. Specielt ikke hvis den er sorteret (altså i kronologisk orden).
Lav en variabel der husker tiden (de første 11 cifre) og en variabel
til den aktuelle opsummering. Du beregner så for hver linie du læser:
Hvis det er samme tid som før
- det nye flow lægges til den aktuelle opsummering
Hvis det er en anden tid (evt den første)
- Hvis der er en opsummring igang så gem den nu
- Sæt den nye tid, nulstil opsummering
- det nye flow lægges til den aktuelle opsummering
Efter du har læst hele filen:
- Hvis der er en opsummring igang så gem den nu
-Bjarne
| |
Mogens Hansen (17-04-2001)
| Kommentar Fra : Mogens Hansen |
Dato : 17-04-01 21:32 |
|
Hej Kåre,
"Kåre Rasmussen" <kmra99@i4.auc.dk> wrote in message
news:9bh5ao$a36$1@sunsite.dk...
> Hej allesammen.
>
> Jeg havde ikke lige forventet at der ville blive så meget debat om mit
> indlæg, så jeg starter lige en ny tråd, med en stor tak til alle de folk
der
> postede svar på mit indlæg.
Sådan kan det gå :)
>
> Jeg fik i påsken leget med vector-funktionen, men det volder mig stadig
lidt
> problemer: Det jeg forsøger at løse med mit program er følgende (og
> forklaringen er nok lidt lang).
>
Aha - jeg tror egentlig ikke at det er vector du har brug for, men snarere
map.
Du har dog haft glæden af at lære lidt om vector :)
Nu får du så chancen for at prøve en af de _meget_ nyttige containere i C++
Standard Library: map.
Mit bud på en løsning er:
du læser en linie ind af gange
finder ud af om det er gyldig data
lægger værdien for den pågældende dato sammen med den hidtidige som for
datoen
husker hvormange værdier der er for datoen indtil videre
indtil alle linier er læst
for alle datoer beregner du nu gennemsnittet (og bruger det til det du
vil)
Det gøres i nedenstående program.
Der er ikke noget fil tilgang - jeg har blot data på _meget_ velordnet form
Der er ikke nogen form for fejlhåndtering - det bør der naturligvis være.
#include <map>
#include <string>
#include <iostream>
#include <strstream>
#include <iomanip>
using namespace std;
namespace
{
// 1 2
// 0123456789012345678901
const char* DATA[]= { "01-01-99 00:00:01 3.55",
"01-01-99 01:01:05 2.56",
"01-01-99 03:05:45 1.22",
"02-01-99 00:00:04 1.23",
"02-01-99 01:10:23 1.23"
};
class avg_info
{
public:
avg_info(void) :
sum(0.0), count(0) {}
void add_value(double value_arg)
{
sum += value_arg;
++count;
}
double avg(void) const
{ return count ? sum/count : 0; }
private:
double sum;
unsigned count;
};
} // end of unnamed namespace
int main(int argc, char* argv[])
{
map<string, avg_info> result;
for(size_t i = 0; sizeof(DATA)/sizeof(DATA[0]) != i; ++i) {
string date(DATA[i], DATA[i]+8);
double value;
istrstream is(DATA[i]+18);
is >> value;
result[date].add_value(value);
}
for(map<string, avg_info>::iterator i = result.begin(); result.end() !=
i; ++i) {
cout << i->first << " " << setprecision(3) << i->second.avg() << endl;
}
return 0;
}
Det et testet på
Windows 2000 med Borland C++Builder V5
Red Hat Linux 7 med gcc 2.96
Det virker ikke med Visual C++ V6 pga. gammel opfattelse af scope af
variable i for-statements - det er dog nemt at kunne udenom.
Det tog 5-10 minutter at skrive og virkede så snart det compilerede.
Jeg håber det hjalp dig lidt, og at du syntes at C++ Standard Library er
nemt og nyttigt at bruge.
Venlig hilsen
Mogens Hansen
| |
|
|