Как вы проверяете, заканчивается ли строка другой строкой в ​​Аде? - PullRequest
3 голосов
/ 29 мая 2020

На этот вопрос есть канонические ответы для каждого популярного языка, хотя этот ответ обычно сводится к: «Используйте string.endsWith () из стандартной библиотеки». Для Ada, насколько я могу найти в документацию для пакета Fixed String , функции string.endswith нет.

Итак, учитывая две фиксированные строки A и B, как сделать вы проверяете, заканчивается ли A на B?

declare
   A : constant String := "John Johnson";
   B : constant String := "son";
begin
   if A.Ends_With(B) then -- this doesn't compile
      Put_Line ("Yay!");
   end if;
end

Моя цель - установить sh стандартный ответ для Ады.

Ответы [ 4 ]

6 голосов
/ 29 мая 2020

Небольшое упрощение ответа Саймона:

function Ends_With (Source, Pattern : String) return Boolean is
begin
   return Pattern'Length <= Source'Length 
     and then Source (Source'Last - Pattern'Length + 1 .. Source'Last) = Pattern;
end Ends_With;
4 голосов
/ 29 мая 2020

Что ж, вот возможное решение:

main.adb

with Ada.Text_IO;       use Ada.Text_IO;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;

procedure Main is

   A : constant String := "John Johnson";
   B : constant String := "son";

begin

   if Tail (A, B'Length) = B then
      Put_Line ("Yay!");
   end if;

end Main;

вывод

$ ./main
Yay!

UPDATE (2)

Еще одно обновление (спасибо @Brian Drummond за комментарий; однако комментарий исчез), снова используя Tail. Теперь это почти идентично ответу @ Zerte, за исключением зависимости от Ada.Strings.Fixed:

main.adb

with Ada.Text_IO;       use Ada.Text_IO;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Assertions;    use Ada.Assertions;

procedure Main is

   function Ends_With (Source, Pattern : String) return Boolean is
   begin
      return Source'Length >= Pattern'Length and then
        Tail (Source, Pattern'Length) = Pattern;
   end Ends_With;   

begin

   Assert (Ends_With ("John Johnson", "son")  = True);
   Assert (Ends_With ("hi", "longer than hi") = False);

   Assert (Ends_With (""  , ""  ) = True);
   Assert (Ends_With (" " , ""  ) = True);
   Assert (Ends_With (""  , " " ) = False);
   Assert (Ends_With (" " , " " ) = True);

   Assert (Ends_With ("n ", "n ") = True);
   Assert (Ends_With (" n", "n" ) = True);
   Assert (Ends_With ("n" , " n") = False);
   Assert (Ends_With (" n", " n") = True);

   Put_Line ("All OK.");

end Main;

output

$ ./main
All OK.
2 голосов
/ 29 мая 2020

В качестве небольшого упрощения ответа Джима это тоже работает:

   function Ends_With (Source, Pattern : String) return Boolean is
   begin
      if Pattern'Length > Source'Length then
         return False;
      else
         return Source (Source'Last - Pattern'Length + 1 .. Source'Last)
           = Pattern;
      end if;
   end Ends_With;

но, даже лучше (спасибо, Зерте),

function Ends_With (Source, Pattern : String) return Boolean is
  (Pattern'Length <= Source'Length and then
     Source (Source'Last - Pattern'Length + 1 .. Source'Last) = Pattern);
2 голосов
/ 29 мая 2020

Вот пример без явных циклов.

with Ada.Assertions; use Ada.Assertions;
with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
   function Ends_With(Source : String; Pattern : String) return Boolean is
      result : Boolean := False;
   begin
      if Pattern'Length <= Source'Length then
         if Pattern'Length > 0 then
            result := Source((Source'Last - Pattern'Length + 1)..Source'Last) = Pattern;
         else 
            result := True;
         end if;
      end if;
      return result;
   end Ends_With;

begin

   Assert (Ends_With ("John Johnson", "son") = True);


   Assert (Ends_With (""  , ""  ) = True);
   Assert (Ends_With (" " , ""  ) = True);
   Assert (Ends_With (""  , " " ) = False);
   Assert (Ends_With (" " , " " ) = True);   

   Assert (Ends_With (""  , "n" ) = False);
   Assert (Ends_With ("n"  , "" ) = True);

   Assert (Ends_With ("n ", "n ") = True);
   Assert (Ends_With (" n", "n" ) = True);
   Assert (Ends_With ("n" , " n") = False);
   Assert (Ends_With (" n", " n") = True);

   Put_Line("All OK");
end Main;
...