Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 08.07.2019, 11:52
vers0 vers0 вне форума
Прохожий
 
Регистрация: 21.12.2013
Адрес: Донецк
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Разбитие многозначного числа на отдельные цифры

Доброго времени суток.
Суть вопроса такова: Имеется переменная A0, которая равна, например, 63 (положительное, целое). Как разбить данное число на два 6 и 3 и присвоить их переменным A1 и A2?
Поиски привели к исходинкам на Паскале:
Код:
var
  s:string;
  a,t,i,sum:integer;
begin
  sum:=0;
  readln(a); {ввод числа}
  str(a,s);    {перевод из числа в строку}
  for i:=1 to length(s) do
   begin
     val(s[i],t,err);   {перевод i-того символа строки в число}
     sum:=sum+t;
   end;
  writeln(sum);
end.

Суть ясна, перевод в строчный. Но здесь идет сумма этих цифр, как занести именно в переменные? Да и на Делфи вроде как inttostr используется при переводе в строчное.
Ответить с цитированием
  #2  
Старый 08.07.2019, 20:53
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Есть вараинты.
1. Через строку:
Код:
var
  A : Array Of Integer;
  S : String;
  C : Char;
  InNmb, I, L : Integer;
begin
  InNmb := 63;
  S :- IntToStr(InNmb);
  L := Length(S);
  // инвертрируем строку если нам нужен младший разряд в младшем элементе
  For I := 1 To (L div 2) Do
    Begin
      C := S[i];
      S[i] := S[L-I+1];
      S[L-I+1] := C;
    End;
  // Заполняем массив
  SetLength(A,L);
  For I := 1 To L Do
    A[I-1] := StrToInt(S[i]);
end;

2. Через деление
Код:
var
  A : Array Of Integer;
  InNmb : Integer;
begin
  InNmb := 63;
  SetLength(A,0);
  While InNmb > 0 Do
   Begin
     SetLength(A,Length(A)+1);
     A[High(A)] := InNmb mod 10;
     InNmb := InNmb div 10;
   End;
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
vers0 (10.07.2019)
  #3  
Старый 09.07.2019, 14:18
vers0 vers0 вне форума
Прохожий
 
Регистрация: 21.12.2013
Адрес: Донецк
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
2. Через деление
Код:
var
  A : Array Of Integer;
  InNmb : Integer;
begin
  InNmb := 63;
  SetLength(A,0);
  While InNmb > 0 Do
   Begin
     SetLength(A,Length(A)+1);
     A[High(A)] := InNmb mod 10;
     InNmb := InNmb div 10;
   End;

Извините, может, будет глупый вопрос, но все же (мало знаком с данной темой):
После While InNmb > 0 Do идет деление и соответственно "выяснение" из каких цифр состоит InNmb, а вот как потом разнести эти цифры по переменным A1 и A2?
Или строка SetLength(A,Length(A)+1); как раз и заполняет A+1 и т.д.? но тогда в var почему они не обозначены?

Последний раз редактировалось vers0, 09.07.2019 в 14:21.
Ответить с цитированием
  #4  
Старый 09.07.2019, 19:02
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Это не строка, а массив. Т.к. заранее не известна длинна числа (кол-во разрядов), я использовал массив для сохранения результатов. Если ты уверен, что будети только 2 разряда, то после цикла можно записать так:
Код:
A1 := A[0];
A2 := A[1];
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
vers0 (10.07.2019)
  #5  
Старый 10.07.2019, 09:12
vers0 vers0 вне форума
Прохожий
 
Регистрация: 21.12.2013
Адрес: Донецк
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Это не строка, а массив. Т.к. заранее не известна длинна числа (кол-во разрядов), я использовал массив для сохранения результатов. Если ты уверен, что будети только 2 разряда, то после цикла можно записать так:
Код:
A1 := A[0];
A2 := A[1];

Да, количество разрядов будет известно. Спасибо за пример и помощ.
Ответить с цитированием
  #6  
Старый 20.07.2019, 16:07
vers0 vers0 вне форума
Прохожий
 
Регистрация: 21.12.2013
Адрес: Донецк
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Это не строка, а массив. Т.к. заранее не известна длинна числа (кол-во разрядов), я использовал массив для сохранения результатов. Если ты уверен, что будети только 2 разряда, то после цикла можно записать так:
Код:
A1 := A[0];
A2 := A[1];

Если написать A1 := A[0];, то A1 присваивается сумма двух чисел из которых состоит значение InNmb. Т.е. InNmb=27, а A1=9, при этом A2=48827616

Как присвоить A1=2, а A2=7 ??

Последний раз редактировалось vers0, 20.07.2019 в 16:10.
Ответить с цитированием
  #7  
Старый 20.07.2019, 21:14
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

У меня, вроде, все правильно работает.
Только надо инвертировать разряды.
Видимо ты пытаешься как-то добраться до массива неправильно, вот и получаешь какой-то мусор.
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  A : Array Of Integer;
  InNmb : Integer;
  A1, A2 : Integer;
begin
  InNmb := 27;
  SetLength(A,0);
  While InNmb > 0 Do
    Begin
      SetLength(A,Length(A)+1);
      A[High(A)] := InNmb mod 10;
      InNmb := InNmb div 10;
    End;
  A1 := A[1];
  A2 := A[0];
  ShowMessage(Format('A1=%d, A2=%d',[A1,A2]));
end;
На выходе показывает 'A1=2 A2=7'.
Ответить с цитированием
  #8  
Старый 21.07.2019, 12:42
vers0 vers0 вне форума
Прохожий
 
Регистрация: 21.12.2013
Адрес: Донецк
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
У меня, вроде, все правильно работает.
Только надо инвертировать разряды.
Видимо ты пытаешься как-то добраться до массива неправильно, вот и получаешь какой-то мусор.
На выходе показывает 'A1=2 A2=7'.

Код тот же, единственное InNmb заменено на s1 и A1,A2 выводятся через Edit3.Text:=IntToStr(A1);

Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
s1:=d1+m1+y1;

begin
  SetLength(A,0);
  While s1 > 0 Do
   Begin
     SetLength(A,Length(A)+1);
     A[High(A)] := s1 mod 10;
     s1 := s1 div 10;
   End;
A1 := A[0];
A2:=A[1];
Edit3.Text:=IntToStr(A1);
Edit4.Text:=IntToStr(A2);
end;
end;

Самое интересное, что сумма в А1 всегда верная, какие бы входные данные не передавались. A1, A2, S1 фигурируют только в этой процедуре, больше ни где.

Последний раз редактировалось vers0, 21.07.2019 в 12:45.
Ответить с цитированием
  #9  
Старый 21.07.2019, 18:57
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Значит что-то не так.
1. Сделай все переменные, включая массив A, локальным (если возможно).
2. Массив A должен быть именно динамическим (проверь его описание).
3. Проверь типы данных. В моем примере они все Integer.
4. Убедись, что никакой другой код "не встревает" во время вычисления (не сохраняет в эти переменные ничего).

Косяк явно у тебя, я проверил свой код и он работает абсолютно правильно.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
vers0 (21.07.2019)
  #10  
Старый 21.07.2019, 19:29
vers0 vers0 вне форума
Прохожий
 
Регистрация: 21.12.2013
Адрес: Донецк
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Значит что-то не так.
Косяк явно у тебя, я проверил свой код и он работает абсолютно правильно.
Я понял, будем искать.

Действительно отдельно код работает корректно, а в моем коде выводит косяк.
1. Сделал локально все переменные (s1 глобально, но сделал локальную s0 (s0:=s1))
2. Массив Array Of Integer
3. Все переменные Integer, включая d1, m1, y1
4. Сначала идет строка s1:=d1+m1+y1; потом s0:=s1; потом массив. Больше эти переменные вообще нигде не встречаются на данный момент.

d1, m1, y1 принимают значения по case combobox1.ItemIndex of и т.д. Может здесь загвоздка?

P.S. даже после ввода промежуточных переменных ничего не поменялось...
d0:=StrToInt(d1);
m0:=StrToInt(m1);
y0:=StrToInt(y1);
s1:=d0+m0+y0;

Последний раз редактировалось vers0, 21.07.2019 в 20:04.
Ответить с цитированием
  #11  
Старый 21.07.2019, 22:27
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

ok, попробуй сделать отдельной функцией и вызывай ее:
Код:
procedure SplitNumber(InNmb : Integer; var A1 : Integer; var A2 : Integer);
var
  A : Array Of Integer;
begin
  SetLength(A,0);
  While InNmb > 0 Do
    Begin
      SetLength(A,Length(A)+1);
      A[High(A)] := InNmb mod 10;
      InNmb := InNmb div 10;
    End;
  A1 := A[1];
  A2 := A[0];
end;

тогда у себя в коде делаешь примерно так:
Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
  s1:=d1+m1+y1;
  SplitNumber(s1,A1,A2);
  ShowMessage(Format('S1=%d, A1=%d, A2=%d',[S1,A1,A2]));
end;
Ну и пришли что там вывелось.

ЗЫ. Если правильно помню, то если нажать в сообщении Ctrl+C, то в буфер обмена скопируется текст сообщения.
Ответить с цитированием
  #12  
Старый 22.07.2019, 10:45
x128 x128 вне форума
Новичок
 
Регистрация: 03.02.2010
Сообщения: 64
Репутация: 133
По умолчанию

Что-то вы сильно увлеклись... vers0, если число всегда двузначное, то пляски вокруг массивов ненужны, lmikle предложил универсальное решение для любых чисел, тебе нужно просто взять результат целочисленного деления на 10 и остаток от деления.
27 div 10 = 2
27 mod 10 = 7
Ответить с цитированием
  #13  
Старый 22.07.2019, 19:36
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от x128
Что-то вы сильно увлеклись... vers0, если число всегда двузначное, то пляски вокруг массивов ненужны, lmikle предложил универсальное решение для любых чисел, тебе нужно просто взять результат целочисленного деления на 10 и остаток от деления.
27 div 10 = 2
27 mod 10 = 7

Ну, в принципе, что-то в этом есть
Действительно, если число всегда двухзначное, то такое решение сработает вполне.
Ответить с цитированием
  #14  
Старый 23.07.2019, 18:30
vers0 vers0 вне форума
Прохожий
 
Регистрация: 21.12.2013
Адрес: Донецк
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Ну и пришли что там вывелось.

ЗЫ. Если правильно помню, то если нажать в сообщении Ctrl+C, то в буфер обмена скопируется текст сообщения.

---------------------------
Project1
---------------------------
S1=9, A1=48958688, A2=9
---------------------------
OK
---------------------------

В итоге ничего не поменялось

---------------------------
Project1
---------------------------
d0=3, m0=1, y0=5, S1=9, A1=49941728, A2=9
---------------------------
OK
---------------------------

Последний раз редактировалось vers0, 23.07.2019 в 18:33.
Ответить с цитированием
  #15  
Старый 23.07.2019, 19:34
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Э, чувак. Ну вот же в сообщении все понятно. Никаких 27 у тебя на входе в разбиение нет. S1 у тебя равно 9, в обоих случаях. Тогда и понятно появление большого числа во второй переменной - там просто происходит выход за границу массива и читается просто какой-то случайный мусор. Если постаишь в опциях компилятора вкл соотв. проверку, на этом месте получишь исключение. Так что код работает правильно, просто кое-кто подсовывает данные, нарушающие входные условия, соответвенно, получаешь мусор на выходе.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 21:32.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter