Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.17.184.90] |
|
Сообщ.
#1
,
|
|
|
Доброе время суток. Всем привет!
Вопрос такой:"Парсинг последовательности строка вида -> в список тип integer -> как лучше и легче реализовать? " Пользователь к примеру задает строку -> "1,6,9-13,15,16,21-25,30" На выходе должен быть список тип integer 1 6 9 10 11 12 13 15 16 21 22 23 24 25 30. "Как лучше и легче реализовать?" Для запятых можно что-то вроде function MakeRange(S1:String):String; var a: array[ 1..MAX_PATH ] of string; j,k:integer; begin j:=0; while s1 <> '' do begin inc(j); a[j] := Trim( Parse( s1, #44 ) ); s1 := Trim( s1 ); end; for k:=1 to j do Result:=Result+' '+ a[k] end; //На выходе: 1 6 9-13 15 16 21-25 30 А вот для #45 тире - "пока ничего не идет на ум" Заранее спасибо |
Сообщ.
#2
,
|
|
|
Превратить строку с помощью CommaText в список строк
Пройти по этому списку. Превратить каждую строку в список с помощью DelimitedText с Delimiter-тире (можно и просто извлечь части до и после тире с помощью Pos и Copy) Если результат длиной 1 - вывести, как есть, иначе сделать цикл от первого до второго занчения. |
Сообщ.
#3
,
|
|
|
l := TList<Integer>.Create; for s in Split(SrcStr, ',') do begin ranges := Split(s, '-'); if Length(ranges) = 1 then EndRange := StrToInt(ranges[0]) else if Length(ranges) = 2 then EndRange := StrToInt(ranges[1]) else Error; for i := StrToInt(ranges[0]) to EndRange do l.Add(i); end; |
Сообщ.
#4
,
|
|
|
uses Generics.Collections; to Fr0sT Такой вариант наиболее короткий! Добавлено Сделал вот так, пока только строка. uses... ,KOL; ... function Parse( var S : String; const Separators : String ) : String; var Pos : Integer; begin Pos := IndexOfCharsMin( S, Separators ); if Pos <= 0 then Pos := Length( S )+1; Result := Copy( S, 1, Pos-1 ); Delete( S, 1, Pos ); end; function Parse2(var S: string; const Separators: string): string; var P: Integer; begin P := Pos(Separators, S); if P = 0 then begin Result := S; S := ''; end else begin Result := Copy( S, P+ Length(Separators), Length(S)- P+ Length(Separators) ); end; end; function HasTire(S: string):Boolean; var P: Integer; begin Result := False; P := Pos('-', S); if P <> 0 then Result := True; end; function MakeRange(S1:String):String; var a: array[ 1..MAX_PATH ] of string; j,k:integer; i,b,c:integer; // Str:String; begin j:=0; while s1 <> '' do begin inc(j);//if a[j]<>'' then inc(j); a[j] := Parse( s1, #44 ); if HasTire(a[j]) then Begin b:=Str2Int( Parse( a[j],#45) ); c:=Str2Int( Parse2( a[j],#45) ); for I := b to c do begin a[j]:= Int2Str(i); if i = c then continue; //no empty string in massive inc(j); end; //Restore row in b-c End;// HasTire // Msgok(s1); end; for k:=1 to j do Result:=Result+' '+ a[k] //Str:=''; // for k:=1 to j do // str := str + 'a[ '+Int2Str(k)+' ] '+ a[k]+#10#13; // Msgok(Str) end; procedure TForm1.Button1Click(Sender: TObject); begin label1.Caption:= MakeRange(Edit1.Text) // Edit1.Text:= MakeRange(Edit1.Text) end; For VCL function Parse(var S: string; const Separators: string): string; var P: Integer; begin P := Pos(Separators, S); if P <= 0 then P := Length( S )+1; Result := Copy( S, 1, P-1 ); Delete( S, 1, P ); end; function Parse2(var S: string; const Separators: string): string; var P: Integer; begin P := Pos(Separators, S); if P = 0 then begin Result := S; S := ''; end else begin Result := Copy( S, P+ Length(Separators), Length(S)- P+ Length(Separators) ); end; end; function HasTire(S: string):Boolean; var P: Integer; begin Result := False; P := Pos('-', S); if P <> 0 then Result := True; end; function MakeRange(S1:String):String; var a: array[ 1..MAX_PATH ] of string; j,k:integer; i,b,c:integer; begin j:=0; while s1 <> '' do begin inc(j); //inc(j); a[j] := Parse( s1, #44 ); if HasTire(a[j]) then Begin b:=StrToInt( Parse( a[j],#45) ); c:=StrToInt( Parse2( a[j],#45) ); for I := b to c do begin a[j]:= IntToStr(i); if i = c then continue; //no empty string in massive inc(j); end; //Restore row in b-c End;// HasTire end; for k:=1 to j do Result:=Result+' '+ a[k] end; procedure TForm1.Button1Click(Sender: TObject); begin label1.Caption:= MakeRange(Edit1.Text) end; |
Сообщ.
#5
,
|
|
|
HasTire это вот прям пять баллов )))
|
Сообщ.
#6
,
|
|
|
Цитата Fr0sT @ HasTire это вот прям пять баллов ))) Без юмора никак нельзя жить |
Сообщ.
#7
,
|
|
|
Держите друзья хардкор от Масты
uses Spring.Collections; function StringToListNums(AStrNums: string): IList<integer>; begin Result := TCollections.CreateList<integer>( TEnumerable.SelectMany<TPair<integer,integer>, integer>( TEnumerable.Select<IEnumerable<string>, TPair<integer,integer>>( TEnumerable.Select<string, IEnumerable<string>>( TCollections.CreateList<string>(SplitString(AStrNums, ',')), function(s: string): IEnumerable<string> begin Result := TCollections.CreateList<string>(SplitString(Trim(s), '-')); end ), function (x: IEnumerable<string>): TPair<integer,integer> begin Result:= TPair<integer,integer>.Create( Integer.Parse(x.First), Integer.Parse(x.Last) ); end ), function (p: TPair<integer,integer>): IEnumerable<integer> begin Result := TEnumerable.Range(p.Key, p.Value - p.Key + 1); end ) ); end; |