Паскаль, сгенерировать строку чисел

У меня проблема с паскалем: сгенерировать первые n чисел в следующей последовательности: 1,1,2,2,2,3,3,3,3,4,4,4,4,4,... Я написал код для них, но проблема в том, что он не работает так, как я хочу.

var
s,c: string;
n,i,j: integer;
begin
 s:='';
 readln(n);
 begin
  for i := 1 to n do
   begin
    if ( length(s)/2 -1 >= n) then
    begin
     Break;
    end;
    for j := 1 to i + 1 do
    begin
     str(i,c);
     s:= s + c+',';
    end;

 end;
end; 

person Reginald    schedule 17.09.2012    source источник


Ответы (4)


Вот более короткая версия, в которой также удалена лишняя запятая в конце: Это полноценная консольная программа (с добавлением подсказки о количестве элементов):

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  i, j: Integer;
  s: string;
  nItems: Integer;
begin
  s := '';
  Write('Enter # of elements: ');
  ReadLn(nItems);
  for i := 1 to nItems do
    for j := 1 to i + 1 do
    begin
      s := s + IntToStr(i) + ',';
    end;
  System.Delete(s, Length(s), 1); { Remove final comma )
  WriteLn(s);
  ReadLn;
end.
person Ken White    schedule 17.09.2012

Я решил свой вопрос, вот правильный код, было бы неплохо, если бы вы его улучшили.

var
s,c: string;
n,i,j: integer;
begin
 s:='';
 readln(n);
 begin
  for i := 1 to n do
   begin

    for j := 1 to i + 1 do
    begin
     if ( length(s) > n*2  ) then
    begin
     Break;
    end;
     str(i,c);
     s:= s + c+',';
    end;

   end;
  end;
 Delete(s,length(s)-2,length(s));
 write(s);
 readln;
 end.
person Reginald    schedule 17.09.2012

Я бы изменил способ работы вашего внешнего цикла, поэтому i указывает, в какой позиции вы находитесь, и ввел второе число element, которое представляет текущий элемент. Затем увеличивайте element всякий раз, когда внутренний цикл завершается.

s:='';
readln(n);
element:=1;
begin
  for i := 1 to n do
  begin
    for j := 1 to i + 1 do
    begin
     str(element,c);
     s:= s + c+',';
    end;
    element:=element+1;
  end;
end;
person CodesInChaos    schedule 17.09.2012

Вы можете изменить свой внутренний цикл:

    for j := 1 to i + 1 do
    begin
     if ( length(s) > n*2  ) then
    begin
     Break;
    end;
     str(i,c);
     s:= s + c+',';
    end;

Во-первых, я бы посоветовал вам всегда делать отступы для ясности, поэтому

    for j := 1 to i + 1 do
    begin
     if ( length(s) > n*2  ) then
       begin
        Break;
       end;
     str(i,c);
     s:= s + c+',';
    end;

во-вторых, вам нужны только begin и end, чтобы превратить несколько операторов в один оператор, поэтому, поскольку у вас есть только break, они избыточны - просто используйте break напрямую:

    for j := 1 to i + 1 do
    begin
     if ( length(s) > n*2  ) then Break;
     str(i,c);
     s:= s + c+',';
    end;

Затем обратите внимание, что вы слишком часто пересчитываете это c:

    str(i,c);
    suffix = c + ',';
    for j := 1 to i + 1 do
    begin
     if ( length(s) > n*2  ) then Break;
     s:= s + suffix;
    end;

Я не очень люблю использовать break, потому что он подозрительно похож на goto, поэтому, возможно, вы могли бы изменить его на блок repeat ... until:

    str(i,c);
    suffix = c + ',';
    j := 1;
    repeat 
      s := s + suffix;
      j := j + 1;
    until (j > i+1) or (length (s) > n*2);

(Обратите внимание, что repeat и until сопровождаются неявными begin и end, поэтому вам не нужно их вводить.)
Теперь вы можете возразить, что я уменьшил ясность, сделав менее очевидным, что цикл просто увеличивает j. В этом случае я не чувствую, что вы предпочитаете, но если вы часто используете break, подумайте, что лучше для вас while или repeat.

Ваше условие о length (s) > n*2 меня озадачивает (и никто другой не включил его в свою версию вашего кода). Вы, кажется, хотите сократить его по какой-то причине. Ты уверен? Я не. Ниже приведена таблица вывода, который вы получаете без ограничения, затем первые n*2 элементов вывода и первые n*2 символа строки, чтобы вы могли проверить. Для чего было предназначено заявление break?

n:      1
output: 1,1
length: 2
n*2:    2
first n*2 numbers:    1,1
first n*2 characters: 1,

n:      2
output: 1,1,2,2,2
length: 5
n*2:    4
first n*2 numbers:    1,1,2,2
first n*2 characters: 1,1,

n:      3
output: 1,1,2,2,2,3,3,3,3
length: 9
n*2:    6
first n*2 numbers:    1,1,2,2,2,3
first n*2 characters: 1,1,2,

n:      4
output: 1,1,2,2,2,3,3,3,3,4,4,4,4,4
length: 14
n*2:    8
first n*2 numbers:    1,1,2,2,2,3,3,3
first n*2 characters: 1,1,2,2,

n:      5
output: 1,1,2,2,2,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5
length: 20
n*2:    10
first n*2 numbers:    1,1,2,2,2,3,3,3,3,4
first n*2 characters: 1,1,2,2,2,

n:      6
output: 1,1,2,2,2,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6
length: 27
n*2:    12
first n*2 numbers:    1,1,2,2,2,3,3,3,3,4,4,4
first n*2 characters: 1,1,2,2,2,3,
person AndrewC    schedule 17.09.2012