![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
динамический двумерный массви [D7, D2005, 2003]
Std © (2006-04-08 18:48:00)
uses
SysUtils;
var
arr:array of array of string;
r,i,j,n,q:integer;
str:string;
begin
randomize;
q:=1;
n:=0;
for I:=0 to 10 do
begin
r:=random(2);
if r<1 then
begin
SetLength(arr,10,q);
arr[i,n]:=inttostr(r);
inc(q);
inc(n);
end;
end;
for I :=0 to length(arr) do
begin
for j:= 0 to length('длинна подмасива') do
writeln(arr[j]);
end;
readln;
end.
вообщем нада создать массив массивов(двумерный массив) сколько в нем будет i-ых элементов известно(10), а вот сколько будет j-ых элементов заранее не известно. Вот чтото не могу я понять что и куда всунуть нада в код чтоб оно работало :(
Std (2006-04-10 11:41:00) [1]шото после _FloatToStr вообще после заятой не выводится ниче..
Rial (2006-04-10 02:42:00) [2]P. S.
Index:=DayOfWeek(Date)-1;
Исправь на
Index:=DayOfWeek(Date)-2;
Rial (2006-04-10 02:36:00) [3]
function _FloatToStr(Const E:Extended;Const P1,P2:Integer;Const FloatFormat:TFloatFormat):String;
Var Buffer:Array[0..63] of Char;
begin
SetString(Result, Buffer, FloatToText(Buffer, E, fvExtended,
FloatFormat, P1, P2));
end;
Тебе подойдет FloatFormat=ffFixed или ffNumber.
P1- количество значащих знаков до запятой,
P2- после запятой.
'100.00' =:= _FloatToStr(100.0,8,2,ffFixed);
Std (2006-04-10 01:18:00) [4]и еще вопрос где что подправить что бы число 100.00 так и выводилось а не 100 каквыводится в двнном случае?
Std (2006-04-10 00:57:00) [5]
> Откровенно говоря, не знаю таких. Откуда взял?
в deteutils есть, правда делфа 2006
> Готов поспорить. У меня календарь есть за 2004 г., он не
> врал никогда раньше:
> 15.08.2004-21.08.2004
ага, с 15.08.2004-21.08.2004 если первый день недели это воскресенье а последний суббота(это ISO, тобиш американский стандарт
а у нас все на так как и них, или у них не так как у нас). Я вот глянул только что виндовйы календарь за 2004 год так там 16.08.2004-22.08.2004
Rial (2006-04-10 00:44:00) [6]
> спасибо, но вот даты в результате не правильные выводятся.
> ..
> 22.08.2004-01.09.2004,100,113.48,95.96,106,55147898
> первые 3 интервала недель для этого файла вот такие:
> 16.08.2004-22.08.2004
> 23.08.2004-29.08.2004
> 30.08.2004-05.09.2004
>
> и в результирующем файле нету первой недели, и первого месяца
> тоесть файл с месяцвми начинается с 9 месяца(отсутствует
> 01.08.2004-31.08.2004)
> и отсутствует первая неделя
Извиняюсь, поторопился, исправил.
unit DatenSort;
Interface
Uses Classes,SysUtils,Dialogs,Math;
function BuildDatenSort(Const InputSL,WeekSL,MonthSL:TStringList):Boolean;
Implementation
{
Формат входных данных:
19082004,100.00,104.06,95.96,100.34,22351898
20082004,101.01,109.08,100.50,108.31,11428600
23082004,110.75,113.48,109.05,109.40,9137200
24082004,111.24,111.60,103.57,104.87,7631300
Формат выходных данных
16.08.2004-22.08.2004,100.00,109.08,95.961031,сумма_волумов_за_эту_неделю
}
{$WARNINGS OFF}
function BuildDatenSort(Const InputSL,WeekSL,MonthSL:TStringList):Boolean;
Const NumOfMonth=12;
NoInt=-1;
Var MonthData:Array [Boolean] of TDayTable;
//Ковертирование даты в индекс
function DateToIndex(Const Y,M,D:Int64):Int64;
Var N:Int64;
begin
N:=Y-1;
Result:=(N*365)+(N shr 2)+MonthData[(Y and 3)=0,M]+D;
end;
//Конвертация индекса в дату
function IndexToDateTime(Index:Int64):TDateTime;
Var Y,M,D:Int64;
Fl:Boolean;
begin
Y:=Trunc(Index/365.25);
Dec(Index,(Y*365)+(Y shr 2));
Inc(Y);
Fl:=((Y and 3)=0);
M:=1;
While (MonthData[Fl,M]<Index) do
Inc(M);
Dec(M);
D:=Index-MonthData[Fl,M];
TryEncodeDate(Y,M,D,Result);
end;
Const Delimeter=',';
Type TSingleData=record
nD,nM,nY:Word;
Index,iBW,iEW,iBM,iEM:Int64;
Date:TDateTime;
Open,High,Low,Close:Extended;
Volume:Int64;
end;
TVoidData=Array[0..0]of TSingleData;
ptVoidData=^TVoidData;
Var S,BufStr:String;
J,P,Len:Integer;
//Процедура поиска разделителя или конца строки
procedure FindDelimeter;
begin
J:=P;
While (P<=Len)and(S[P]<>Delimeter) do
Inc(P);
//Делаем выделение нужного участка и заменяем в нем символы "." на "," - формат
//действительного числа в Delphi/Pascal
BufStr:=StringReplace(Copy(S,J,P-J),'.',',',[rfReplaceAll]);
Inc(P);
end;
function FloToStr(Const E:Extended):String;
begin
Result:=StringReplace(FloatToStr(E),',','.',[rfReplaceAll]);
end;
Var WOpen,WHigh,WLow,WClose,MOpen,MHigh,MLow,MClose:Extended;
WVolume,MVolume:Int64;
procedure WriteToWeek(Const iBW,iEW:Int64);
begin
WeekSL.Add(DateToStr(IndexToDateTime(iBW))+'-'+DateToStr(IndexToDateTime(iEW))+
Delimeter+FloToStr(WOpen)+Delimeter+FloToStr(WHigh)+Delimeter+FloToStr(WLow)+
Delimeter+FloToStr(WClose)+Delimeter+IntToStr(WVolume));
end;
procedure WriteToMonth(Const iBM,iEM:Int64);
begin
MonthSL.Add(DateToStr(IndexToDateTime(iBM))+'-'+DateToStr(IndexToDateTime(iEM))+
Delimeter+FloToStr(MOpen)+Delimeter+FloToStr(MHigh)+Delimeter+FloToStr(MLow)+
Delimeter+FloToStr(MClose)+Delimeter+IntToStr(MVolume));
end;
Var I,L:Integer;
Size:Integer;
ptV:ptVoidData;
BB:Array[Boolean]of Word;
N,eW,eM:Int64;
begin
Result:=False;
Try
//Построение списка длин до указанного месяца
BB[True]:=0;
BB[False]:=0;
For I:=1 to NumOfMonth do begin
MonthData[True][I]:=BB[True];
MonthData[False][I]:=BB[False];
Inc(BB[True],MonthDays[True,I]);
Inc(BB[False],MonthDays[False,I]);
end;
L:=InputSL.Count;
//Сортировка дат по возрастанию
For I:=0 to L-1 do begin
S:=InputSL.Strings[I];
InputSL.Strings[I]:=Copy(S,5,4)+Copy(S,3,2)+Copy(S,1,2)+S;
end;
InputSL.Sort;
For I:=0 to L-1 do begin
S:=InputSL.Strings[I];
InputSL.Strings[I]:=Copy(S,9,Length(S)-8);
end;
//Выделение пемяти под массив
Size:=SizeOf(TSingleData)*L;
GetMem(ptV,Size);
Try
For I:=0 to L-1 do
With ptV^[I] do begin
S:=InputSL.Strings[I];//Кешируем строку
Len:=Length(S);
P:=1; //Позицию - на начало
//Выделяем дату
FindDelimeter;
nD:=StrToInt(Copy(BufStr,1,2));
nM:=StrToInt(Copy(BufStr,3,2));
nY:=StrToInt(Copy(BufStr,5,4));
TryEncodeDate(nY,nM,nD,Date);
Index:=DayOfWeek(Date)-1; //День недели, с нуля
N:=DateToIndex(nY,nM,nD); //Индекс даты
iBW:=N-Index; //Индекс начала недели
iEW:=iBW+6; //Индекс конца недели
Index:=N; //Индекс даты
iBM:=Index-nD+1; //Индекс начала месяца
iEM:=iBM+MonthDays[((nY and 3)=0),nM]-1; //Индекс конца месяца
//Выделяем Open
FindDelimeter;
Open:=StrToFloat(BufStr);
//Выделяем High
FindDelimeter;
High:=StrToFloat(BufStr);
//Выделяем Low
FindDelimeter;
Low:=StrToFloat(BufStr);
//Выделяем Close
FindDelimeter;
Close:=StrToFloat(BufStr);
//Выделяем Volume
FindDelimeter;
Volume:=StrToInt64(BufStr);
end;//Все, массив с данными готов !
eW:=0;
eM:=0;
WVolume:=NoInt;
MVolume:=NoInt;
For I:=0 to L-1 do
With ptV^[I] do begin
If(Index>eW)then begin
If (WVolume<>NoInt)then
With ptV^[I-1] do
WriteToWeek(iBW,iEW);
//Запоминаем начальные данные
WOpen:=Open;
WHigh:=High;
WLow:=Low;
WClose:=Close;
WVolume:=Volume;
//Запись следующей даты окончания
eW:=iEW;
end else begin//Рассчет статистики
WHigh:=Max(WHigh,High);
WLow:=Min(WLow,Low);
Inc(WVolume,Volume);
WClose:=Close;
end;
If(Index>eM)then begin
If (MVolume<>NoInt)then
With ptV^[I-1] do
WriteToMonth(iBM,iEM);
//Запоминаем начальные данные
MOpen:=Open;
MHigh:=High;
MLow:=Low;
MClose:=Close;
MVolume:=Volume;
//Запись следующей даты окончания
eM:=iEM;
end else begin//Рассчет статистики
MHigh:=Max(MHigh,High);
MLow:=Min(MLow,Low);
Inc(MVolume,Volume);
MClose:=Close;
end;
end;
With ptV^[L-1] do begin
If(Index<=eW)and(WVolume<>NoInt)then
WriteToWeek(iBW,iEW);
If(Index>eM)and(MVolume<>NoInt)then
WriteToMonth(iBM,iEM);
end;
Finally
FreeMem(ptV,Size);
end;
Except
Exit;
end;
Result:=True;
end;
{$WARNINGS ON}
end.
> З.Ы. неделя начинается понедельником. заканчивается воскресеньем
Здорово, а я то полчаса думал, как же так, вроде со вторника всегда начаналась !..
> и отсутствует первая неделя
> 16.08.2004-22.08.2004
>
Готов поспорить. У меня календарь есть за 2004 г., он не врал никогда раньше:
15.08.2004-21.08.2004
> startOfTheWeek EndOfTheWeek(для недели)
> StartOfTheMonth EndOfTheMonth(для месяца)
>
Откровенно говоря, не знаю таких. Откуда взял?
Всегда все ручками делаю, если что.
В SysUtils нет.
Std (2006-04-09 23:39:00) [7]а не проще было бы дату начала и дату конца недели находить как:
startOfTheWeek EndOfTheWeek(для недели)
StartOfTheMonth EndOfTheMonth(для месяца)
Std (2006-04-09 23:33:00) [8]спасибо, но вот даты в результате не правильные выводятся...
22.08.2004-01.09.2004,100,113.48,95.96,106,55147898
первые 3 интервала недель для этого файла вот такие:
16.08.2004-22.08.2004
23.08.2004-29.08.2004
30.08.2004-05.09.2004
и в результирующем файле нету первой недели, и первого месяца
тоесть файл с месяцвми начинается с 9 месяца(отсутствует 01.08.2004-31.08.2004)
и отсутствует первая неделя
16.08.2004-22.08.2004
З.Ы. неделя начинается понедельником. заканчивается воскресеньем
Rial (2006-04-09 22:03:00) [9]Вот, чуть не целый час делал.
Мудрено получилось, но таково уж задание.
Если это не то, что нужно, то уж извини ...
unit DatenSort;
Interface
Uses Classes,SysUtils,Dialogs,Math;
function BuildDatenSort(Const InputSL,WeekSL,MonthSL:TStringList):Boolean;
Implementation
{
Формат входных данных:
19082004,100.00,104.06,95.96,100.34,22351898
20082004,101.01,109.08,100.50,108.31,11428600
23082004,110.75,113.48,109.05,109.40,9137200
24082004,111.24,111.60,103.57,104.87,7631300
Формат выходных данных
16.08.2004-22.08.2004,100.00,109.08,95.961031,сумма_волумов_за_эту_неделю
}
{$WARNINGS OFF}
function BuildDatenSort(Const InputSL,WeekSL,MonthSL:TStringList):Boolean;
Const NumOfMonth=12;
NoInt=-1;
Var MonthData:Array [Boolean] of TDayTable;
//Ковертирование даты в индекс
function DateToIndex(Const Y,M,D:Int64):Int64;
Var N:Int64;
begin
N:=Y-1;
Result:=(N*365)+(N shr 2)+MonthData[(Y and 3)=0,M]+D;
end;
//Конвертация индекса в дату
function IndexToDateTime(Index:Int64):TDateTime;
Var Y,M,D:Int64;
Fl:Boolean;
begin
Y:=Trunc(Index/365.25);
Dec(Index,(Y*365)+(Y shr 2));
Inc(Y);
Fl:=((Y and 3)=0);
M:=1;
While (MonthData[Fl,M]<Index) do
Inc(M);
Dec(M);
D:=Index-MonthData[Fl,M];
TryEncodeDate(Y,M,D,Result);
end;
Const Delimeter=',';
Type TSingleData=record
nD,nM,nY:Word;
Index,iBW,iEW,iBM,iEM:Int64;
Date:TDateTime;
Open,High,Low,Close:Extended;
Volume:Int64;
end;
TVoidData=Array[0..0]of TSingleData;
ptVoidData=^TVoidData;
Var S,BufStr:String;
J,P,Len:Integer;
//Процедура поиска разделителя или конца строки
procedure FindDelimeter;
begin
J:=P;
While (P<=Len)and(S[P]<>Delimeter) do
Inc(P);
//Делаем выделение нужного участка и заменяем в нем символы "." на "," - формат
//действительного числа в Delphi/Pascal
BufStr:=StringReplace(Copy(S,J,P-J),'.',',',[rfReplaceAll]);
Inc(P);
end;
function FloToStr(Const E:Extended):String;
begin
Result:=StringReplace(FloatToStr(E),',','.',[rfReplaceAll]);
end;
Var I,L:Integer;
Size:Integer;
ptV:ptVoidData;
TmpDate:TDateTime;
BB:Array[Boolean]of Word;
N,eW,eM:Int64;
WOpen,WHigh,WLow,WClose,MOpen,MHigh,MLow,MClose:Extended;
WVolume,MVolume:Int64;
begin
Result:=False;
Try
//Построение списка длин до указанного месяца
BB[True]:=0;
BB[False]:=0;
For I:=1 to NumOfMonth do begin
MonthData[True][I]:=BB[True];
MonthData[False][I]:=BB[False];
Inc(BB[True],MonthDays[True,I]);
Inc(BB[False],MonthDays[False,I]);
end;
L:=InputSL.Count;
//Сортировка дат по возрастанию
For I:=0 to L-1 do begin
S:=InputSL.Strings[I];
InputSL.Strings[I]:=Copy(S,5,4)+Copy(S,3,2)+Copy(S,1,2)+S;
end;
InputSL.Sort;
For I:=0 to L-1 do begin
S:=InputSL.Strings[I];
InputSL.Strings[I]:=Copy(S,9,Length(S)-8);
end;
//Выделение пемяти под массив
Size:=SizeOf(TSingleData)*L;
GetMem(ptV,Size);
Try
For I:=0 to L-1 do
With ptV^[I] do begin
S:=InputSL.Strings[I];//Кешируем строку
Len:=Length(S);
P:=1; //Позицию - на начало
//Выделяем дату
FindDelimeter;
nD:=StrToInt(Copy(BufStr,1,2));
nM:=StrToInt(Copy(BufStr,3,2));
nY:=StrToInt(Copy(BufStr,5,4));
TryEncodeDate(nY,nM,nD,Date);
Index:=DayOfWeek(Date)-1; //День недели, с нуля
N:=DateToIndex(nY,nM,nD); //Индекс даты
iBW:=N-Index; //Индекс начала недели
iEW:=N+6; //Индекс конца недели
Index:=N; //Индекс даты
iBM:=Index-nD+1; //Индекс начала месяца
iEM:=iBM+MonthDays[((nY and 3)=0),nM]-1; //Индекс конца месяца
//Выделяем Open
FindDelimeter;
Open:=StrToFloat(BufStr);
//Выделяем High
FindDelimeter;
High:=StrToFloat(BufStr);
//Выделяем Low
FindDelimeter;
Low:=StrToFloat(BufStr);
//Выделяем Close
FindDelimeter;
Close:=StrToFloat(BufStr);
//Выделяем Volume
FindDelimeter;
Volume:=StrToInt64(BufStr);
end;//Все, массив с данными готов !
eW:=0;
eM:=0;
WVolume:=NoInt;
MVolume:=NoInt;
For I:=0 to L-1 do
With ptV^[I] do begin
If(Index>eW)then begin
If (WVolume<>NoInt)then
WeekSL.Add(DateToStr(IndexToDateTime(iBW))+'-'+DateToStr(IndexToDateTime(iEW))+
Delimeter+FloToStr(WOpen)+Delimeter+FloToStr(WHigh)+Delimeter+FloToStr(WLow)+
Delimeter+FloToStr(WClose)+Delimeter+IntToStr(WVolume));
//Запоминаем начальные данные
WOpen:=Open;
WHigh:=High;
WLow:=Low;
WClose:=Close;
WVolume:=Volume;
//Запись следующей даты окончания
eW:=iEW;
end else begin//Рассчет статистики
WHigh:=Max(WHigh,High);
WLow:=Min(WLow,Low);
Inc(WVolume,Volume);
WClose:=Close;
end;
If(Index>eM)then begin
If (MVolume<>NoInt)then
MonthSL.Add(DateToStr(IndexToDateTime(iBM))+'-'+DateToStr(IndexToDateTime(iEM))+
Delimeter+FloToStr(MOpen)+Delimeter+FloToStr(MHigh)+Delimeter+FloToStr(MLow)+
Delimeter+FloToStr(MClose)+Delimeter+IntToStr(MVolume));
//Запоминаем начальные данные
MOpen:=Open;
MHigh:=High;
MLow:=Low;
MClose:=Close;
MVolume:=Volume;
//Запись следующей даты окончания
eM:=iEM;
end else begin//Рассчет статистики
MHigh:=Max(MHigh,High);
MLow:=Min(MLow,Low);
Inc(MVolume,Volume);
MClose:=Close;
end;
end;
Finally
FreeMem(ptV,Size);
end;
Except
Exit;
end;
Result:=True;
end;
{$WARNINGS ON}
end.
Пример работы:
program MyProject;
uses
Classes,
DatenSort in 'DatenSort.pas';
Var InputSL,WeekSL,MonthSL:TStringList;
begin
InputSL:=TStringList.Create;
WeekSL:=TStringList.Create;
MonthSL:=TStringList.Create;
Try
InputSL.LoadFromFile('1.txt');
BuildDatenSort(InputSL,WeekSL,MonthSL);
WeekSL.SaveToFile('2.txt');
MonthSL.SaveToFile('3.txt');
Finally
InputSL.Free;
WeekSL.Free;
MonthSL.Free;
end;
end.
<1.txt>
19082004,100.00,104.06,95.96,100.34,22351898
20082004,101.01,109.08,100.50,108.31,11428600
23082004,110.75,113.48,109.05,109.40,9137200
24082004,111.24,111.60,103.57,104.87,7631300
25082004,104.96,108.00,103.88,106.00,4598900
26082004,104.95,107.95,104.66,107.91,3551000
27082004,108.10,108.62,105.69,106.15,3109000
30082004,105.28,105.49,102.01,102.01,2601000
31082004,102.30,103.71,102.16,102.37,2461400
01092004,102.70,102.97,99.67,100.25,4573700
02092004,99.19,102.37,98.94,101.51,7566900
03092004,100.95,101.74,99.32,100.01,2578800
07092004,101.01,102.00,99.61,101.58,2926700
08092004,100.74,103.03,100.50,102.30,2495300
09092004,102.53,102.71,101.00,102.31,2032900
Std (2006-04-09 12:05:00) [10]нее, <date> это просто одна дата в строке
<date>,<open>,<high>,<low>,<close>,<volume>
19082004,100.00,104.06,95.96,100.34,22351898
20082004,101.01,109.08,100.50,108.31,11428600
23082004,110.75,113.48,109.05,109.40,9137200
24082004,111.24,111.60,103.57,104.87,7631300
25082004,104.96,108.00,103.88,106.00,4598900
26082004,104.95,107.95,104.66,107.91,3551000
27082004,108.10,108.62,105.69,106.15,3109000
30082004,105.28,105.49,102.01,102.01,2601000
31082004,102.30,103.71,102.16,102.37,2461400
01092004,102.70,102.97,99.67,100.25,4573700
02092004,99.19,102.37,98.94,101.51,7566900
03092004,100.95,101.74,99.32,100.01,2578800
07092004,101.01,102.00,99.61,101.58,2926700
08092004,100.74,103.03,100.50,102.30,2495300
09092004,102.53,102.71,101.00,102.31,2032900
вот кусок файла
как видно в строке конкретный день
а при выводе необходимо вывести строку где указывается когда неделя начинается и когда заканчивается.
start должно быть число которое первое в этой неделе.
end это число последнего дня в неделе. остальные это максимальное(столбеца high) минимальное(столбца lov) и сумма за всю неделю(столбца volume)
для месяца выводить нада такую же строку но только start это первое число в месяце end последнее число в месяце
пример для приведенного куска файла:
недельная группировка
<date>,<open>,<high>,<low>,<close>,<volume>
16.08.2004-22.08.2004,100.00,109.08,95.961031,сумма_волумов_за_эту_неделю
23.08.2004-29.08.2004,110.75,108.62,103.57,106.15,сумма_волумов_за_эту_неделю
30.08.2004-05.09.2004,105.28,105.49,99.32,100.01,сумма_волумов_за_эту_неделю
06.09.2004-12.09.2004,101.01,103.03,99.61,102.31,сумма_волумов_за_эту_неделю
где:
<date> - дата начала и дата конца недели, <open>-первое число недели(по столбцу open), <high> - максимальное число недели(по столбцу high)
<low>-минимальное число недели(по столбцу low)
<close>-последнее число недели(по столбцу close), <volume> -- сумма всех волумов за неделю.
месячная группировка
<date>,<open>,<high>,<low>,<close>,<volume>
01.08.2004-31.08.2004,100.00,113.48,95.96,102.37,сумма_волумов_за_этот_месяц
01.09.2004-30.09.2004,102.70,103.03,97.99,102.31,сумма_волумов_за_этот_месяц
где:
<date> - дата начала и дата конца месяца, <open>-первое число месяца(по столбцу open), <high> - максимальное число месяца(по столбцу high)
<low>-минимальное число месяца(по столбцу low)
<close>-последнее число месяца(по столбцу close), <volume> -- сумма всех волумов за месяц.
сепаратор даты мне нужен был для:
я брал строку, выбирал из нее дату, переводил ее в дату в формате dd.mm.yyyy и искал (и вот с этим самым была проблема, если у юзера в системе стоит сепаратор времени / то прога выдет шо dd.mm.yyyy не является датой)
ws:=StartOfTheMonth(dat); we:=EndOfTheMonth(dat); а потом сверял со строкой, если эта строка входит диапазон тих дат то пытался записать в массив(так и не записал :( )
Это конешно ели будет использоватся такой метод как у меня, в других случаях думаю сепаратор не не важен...
Rial (2006-04-09 02:30:00) [11]Надеюсь, тут неискаженное условие (что- то я слышал о разделителях даты, а тут их нет).
Кстати, ести <date> есть дата начала и конца, то зачем <start> ?
Приведи пример формата сгруппированных срок для недель и месяцев.
Основная проблема должна была быть в вычислении даты начала недели с учетом года и месяца ...
Std (2006-04-09 02:29:00) [12]окей, если можно то завтра пж, буду очень благодарен
Rial (2006-04-09 02:17:00) [13]
> при группировке в месяц необходимо выводить строку в виде
> <date>,<start>,<high>,<low>,<end>,<volume>
> где <date> дата начала и дата конца недели
Так бы сразу все и выложил.
Тут все опять просто, но не сегодня и не в 2:16.
Std (2006-04-09 01:56:00) [14]опять не то немножко...
вобщем задание такое:
есть файл:
<date>,<open>,<high>,<low>,<close>,<volume>
19082004,100.00,104.06,95.96,100.34,22351898
20082004,101.01,109.08,100.50,108.31,11428600
23082004,110.75,113.48,109.05,109.40,9137200
24082004,111.24,111.60,103.57,104.87,7631300
25082004,104.96,108.00,103.88,106.00,4598900
26082004,104.95,107.95,104.66,107.91,3551000
27082004,108.10,108.62,105.69,106.15,3109000
30082004,105.28,105.49,102.01,102.01,2601000
необходимо сгруппировать данные по неделе и месяце.
при группировке в неделю выводится строка
<date>,<start>,<high>,<low>,<end>,<volume>
где <date> дата начала и дата конца недели
<start> число Первого дня недели
<high> максимальное из всех <high> за всю неделю
<low> минимальное число из всех <low> за всю неделю
<end> число последнего дня недели
<volume> сумма всех <volume> за неделю
при группировке в месяц необходимо выводить строку в виде
<date>,<start>,<high>,<low>,<end>,<volume>
где <date> дата начала и дата конца недели
<start> число Первого дня месяца
<high> максимальное из всех <high> за весь месяц
<low> минимальное число из всех <low> за весь месяц
<end> число последнего дня месяца
<volume> сумма всех <volume> за месяц
вот такую задачу потавил мне шеф...
если до понедельника не зделаю не видать мне отпуска еще неделю как минимум :(( а программированием я не часто занимаюся так что помогите пж...
Rial (2006-04-09 01:32:00) [15]А наличие различных сепараторов, если они состоят из одного символа,
ничего не изменит.
В этом можно убедиться, внимательно прочитав код.
Но суть задати немного бредовая получается.
Поэтому и код ужасно кривой получается у меня !..
В смысле, так, как ты ее хочешь реализовать.
Так что подумай над
> Std © (09.04.06 01:14) [15]
Rial (2006-04-09 01:29:00) [16]
Type TArr=Array of Array of String;
function PerformStr(Const S:String):String;
begin
Result:=Copy(S,7,4)+Copy(S,4,2)+Copy(S,1,2);
end;
function BuildSL(Out Arr:TArr;Const SL:TStringList;
Const FileName:String):Boolean;
Var FileSL:TStringList;//Данные фaйла
P,I,J,K,L,LL:Integer;
S:String;
begin
Result:=False;
FileSL:=TStringList.Create;
Try
Try
FileSL.LoadFromFile(FileName);
Except
Exit;
end;
L:=FileSL.Count;
For I:=0 to L-1 do begin
FileSL.Strings[I]:=PerformStr(Copy(FileSL.Strings[I],1,10))+FileSL.Strings[I];
end;
FileSL.Sort;
For I:=0 to L-1 do begin
S:=FileSL.Strings[I];
FileSL.Strings[I]:=Copy(S,9,Length(S)-8);
end;
LL:=SL.Count;
SetLength(Arr,L);
I:=0;
J:=0;
While (I<=L-1)and(J<=LL-1) do begin
P:=I;
S:=PerformStr(Copy(SL.Strings[J],12,10));
While (P<=L-1)and(PerformStr(Copy(FileSL.Strings[P],1,10))<=S)do
Inc(P);
If (P>I)then
SetLength(Arr[J],P-I);
For K:=0 to P-I-1 do
Arr[J][K]:=FileSL.Strings[I+K];
I:=P;
Inc(J);
end;
SetLength(Arr,J);
Finally
FileSL.Free;
end;
Result:=True;
end;//BuildSL
Var SL:TStringList;
Arr:TArr;
begin
SL:=TStringList.Create;
Try
SL.LoadFromFile('2.txt');
BuildSL(Arr,SL,'1.txt');
Finally
SL.Free;
end;
Входные файлы изменились
<1.txt>
02.01.2006,слово1,слово2,слово3
03.01.2006,слово1,слово2,слово3
11.01.2006,слово1,слово2,слово3
12.01.2006,слово1,слово2,слово3
05.01.2006,слово1,слово2,слово3
10.04.2006,слово1,слово2,слово3
11.04.2006,слово1,слово2,слово3
12.04.2006,слово1,слово2,слово3
18.04.2006,слово1,слово2,слово3
19.04.2006,слово1,слово2,слово3
<2.txt>
03.01.2006-09.01.2006
10.01.2006-16.01.2006
10.04.2006-16.04.2006
17.04.2006-23.04.2006
Размер кода возрос.
Надеюсь, это то, что тебе нужно.
Std (2006-04-09 01:14:00) [17]
> Надо это понимать так, что ты первый раз по датам составляешь
> список интервалов недель, а потом опять ищешь, к какому
> интервалу каждая дата относится ?
получается что так
> А не проще ли тогда на этапе построения этих интервалов
> и распределить даты?
насчет проще или нет не знаю, но вот быстрее будет работать точно, но вот как это реализовать хз.
да, и еще нада учесть что у юзера сепаратор даты может быть "." или ":" или "/"
Rial (2006-04-09 01:09:00) [18]
> повторяющиеся интервалы удаляются).
Вот это сбивает с толку.
Надо это понимать так, что ты первый раз по датам составляешь список интервалов недель, а потом опять ищешь, к какому интервалу каждая дата относится ?
А не проще ли тогда на этапе построения этих интервалов и распределить даты?
Std (2006-04-09 01:02:00) [19]даты войдут все, так как список недель формируется на основе дат(проверяется каждая дата и нходится для нее начало и конец недели, повторяющиеся интервалы удаляются).
ага, именно так и нада. поскольку потом нада будет достучатся до каждой грппы и производить определенные действия с каждой группой
Rial (2006-04-09 00:50:00) [20]Что будет с теми датами, которые не войдут ни в один из интервалов?
Я так и не нашел ответа на этот вопрос в условии задачи.
А ты воовще уверен, что тебе именно ТАК все нужно сделать ?..