#string #ada
Вопрос:
Если я создам подпрограмму типа функция , которая, например, прикажет вам ввести строку определенной длины, и вы введете Overflow
, она должна будет ввести последнюю половину строки, так что в данном случае это будет так flow
. Но, с другой стороны, если я наберу нечетное количество символов, как Stack
предполагается, это будет последняя половина строки средняя буква, так что в данном случае это будет «ack».
Позвольте мне сделать это более понятным (текст, выделенный жирным шрифтом, является пользовательским вводом):
Введите строку длиной не более 7 символов: Candy
Другая половина строки-это: ndy
with Ada.Text_IO; use Ada.Text_IO; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; function Split_String (S : in String) return String is begin Mid := 1 (S'Length / 2); return S(Mid .. S'Last); end Split_String; S : String(1 .. 7); I : Integer; begin Put("Type a string that's no longer than 7 characters: "); Get_Line(S, I); Put(Split_String(S)); end Split;
Позвольте мне рассказать вам, о чем я думал. Поэтому я делаю а Get_Line
, чтобы посмотреть, сколько символов содержит строка. Затем я ввел I
свою подпрограмму, чтобы определить, можно ли ее равномерно разделить на два или нет. Если его можно разделить на два, то остальное должно быть равно 0, таким образом, это будет означать, что ввод другой половины строки СРЕДНИЙ СИМВОЛ в этом нет необходимости. Если во всех остальных случаях он не делится на два, я должен ввести другую половину строки средний символ. Но теперь я наткнулся на большую проблему в своей основной программе. Я не знаю, как напечатать вторую половину строки. Если строка содержит 4 слова, я могу просто ввести их, Put(S(3 .. 4);
но дело в том, что я не знаю общей формулы для этого. Помощь приветствуется! 🙂 Хорошего вам дня!
Комментарии:
1. Если длина вашей строки содержит 6 символов, то вы хотите вывести срез (4..6). Если длина строки равна 5, то вы хотите вывести (3..5). В обоих случаях начальный символ для вывода в последней «половине» строки равен (длина / 2) 1.
2. Да, я знаю это, но как мне перевести это в код? Какой код нужно написать для ПОСЛЕДНЕЙ половины строки? Например, это что-то вроде, если Split_String(I) = True, затем Положить(S(Length’Last/2), если Split_String(I) = False, затем положить(S(Length’Last/2) 1 конец, если;
3. Для непустой строки мы знаем, что «Длина = Последняя-Первая 1″ и переставили ‘Первая = Последняя длина 1».
4. Я обновил свой код (см. Сообщение), но он все равно не будет работать, и отчасти очевидно, почему он не работает, потому что я печатаю только последний символ. Я не знаю, как напечатать вторую половину, потому что, как бы я это ни делал, она не будет соответствовать.
5. Если вы проиндексируете строку, такую как ваша S, с помощью одного индекса, такого как S’Last, вы получите один символ-символ в этом индексе. Чтобы получить подстроку, вы должны использовать диапазон N .. M в качестве «индекса»-на самом деле это называется «срезом» массива строк. Поэтому вам следует сделать что-то вроде Put(S(3..4)), но с заменой 3 и 4 выражениями, которые вычисляют индексы первого и последнего символа во второй половине строки. В вашем случае и то, и другое можно вычислить по значению I.
Ответ №1:
Вам нужен более общий подход к вашей проблеме. Кроме того, постарайтесь понять, как Get_Line
это работает для вас.
Например, если объявить входную строку большого размера, например
Input : String (1..1024);
У вас будет строка достаточно большая, чтобы работать с любыми вероятными входными значениями. Далее вам нужна переменная, указывающая, сколько символов на самом деле было прочитано Get_Line
.
Length : Natural;
Данные, возвращаемые Get_Line
затем, будут находиться в срезе входной строки, обозначенной как
Input (1 .. Length);
Передайте этот срез в свою функцию, чтобы вернуть вторую половину строки.
function last_half(S : string) return string; last_half(Input(1..Length));
Теперь все, что вам нужно, — это вычислить последнюю половину строки, переданной функции last_half
. Функция выведет фрагмент переданной ей строки. Чтобы найти первый индекс последней половины входной строки, необходимо выполнить вычисление
mid : Positive := 1 (S'length / 2);
Затем просто верните строку S(mid .. S'Last)
.
Похоже, что цель этого упражнения-научиться использовать срезы массива. Сосредоточьтесь на том, как срезы работают для вас в задаче, и решение будет очень простым.
Одним из возможных решений является
with Ada.Text_IO; use Ada.Text_IO; procedure Main is Input : String (1 .. 1_024); Length : Natural; function last_half (S : in String) return String is Mid : Positive := 1 (S'Length / 2); begin return S (Mid .. S'Last); end last_half; begin Put ("Enter a string: "); Get_Line (Input, Length); Put_Line (Input (1 .. Length) amp; " : " amp; last_half (Input (1 .. Length))); end Main;
Изучите, как решение использует срезы массива для возвращаемого значения Get_Line и параметра функции last_half, а также для ее оператора возврата. Также важно помнить, что строка типа определяется как неограниченный массив символов. Это означает, что каждый фрагмент строки также является строкой.
type String is array ( Positive range lt;gt; ) of Character;
Комментарии:
1. Приведенное выше вычисление для mid правильно работает для строк четной или нечетной длины из-за того, как работает целочисленное деление. Например, 5 / 2 возвращает 2. Целые числа не имеют дробной части. Результат 1 ( 5/2) равен 3. Таким образом, последняя половина «привет» будет «llo». Аналогично работает строка с четным числом символов. Последняя половина «клея» будет равна 1 ( 4/2) = 3, что приведет к «ue».
2. Это выглядит многообещающе, но я не знаю, как внедрить это в свою программу. Например, где должна быть моя линия получения и т. Д.
3. Строку Get_Line не нужно перемещать в вашей программе. Вам не нужна функция, чтобы определить, является ли длина строки четной или нет. Об этом позаботится математика.
4. Я обновил свой код, но он все равно не будет работать так, как должен. Я действительно не до конца понял ваши инструкции, поскольку я новичок в программировании, но вы могли бы взглянуть на мой подход, если хотите.
5. Я должен был увидеть ваше обновленное решение, я собираюсь взглянуть на это. A
Ответ №2:
Помимо того, что это неопрятный беспорядок, ваше последнее редактирование кода (по состоянию на 20:11 по Гринвичу 15 ноября 2021 года) даже не компилируется. Пожалуйста, не показывайте нам такой код! (если, конечно, в этом не проблема).
Я хотел бы настоятельно рекомендовать этот альтернативный способ ввода строк:
declare S : constant String := Get_Line; begin -- do things with S, which is exactly as long as -- the input you typed: no undefined characters at -- the end to confuse the result, no need to worry -- about overrunning an input buffer end;
С этим изменением и очевидными синтаксическими изменениями ваш текущий код будет делать то, что вы хотите.