Форум программистов, компьютерный форум, киберфорум
PascalABC.NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
1 / 1 / 0
Регистрация: 02.08.2022
Сообщений: 12

Строка >255 Всё работает?

16.03.2023, 19:14. Показов 1418. Ответов 5

Студворк — интернет-сервис помощи студентам
На форуме видел следующую тему: Как ввести в строку более 255 символов?
о Free-Pascal, есть ли в PascalABC.NET похожие сложности на счет длинных строк?

Написал код, который разрешает вводить строку более 255 символов (проверил ручками). Помогите найти подводные камни программы если они есть. Как вы думаете сработает ли на Я.Контесте без сбоев (районная олимпиада скоро как-никак) ?
Код 1
Pascal
1
2
3
4
5
6
7
8
9
begin
 
  var s:string;
  
  setlength(s,3000);
  read(s);
  writeln(s);
  
end.
Код 2
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
begin
  var s:string;
  
  setlength(s,3000);
  
  for var i := 1 to 3000 do
    s[i] := 'F';
  
  s[1556] := 'S';
  
  writeln(s);
  
end.
Если есть свои методы для длинных строк в PascalABC.NET, то напишите пожалуйста, буду очень благодарен!
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
16.03.2023, 19:14
Ответы с готовыми решениями:

Дана строка содержащая не более 255 цифр
Помогите решить задачу,уже какой день не могу решить. Вот сами условия: Дана строка символов, содержащая не более 255 цифр. Необходимо...

Дана строка длиной не более 255 символов.
Дана строка длиной не более 255 символов. Группы символов, разделённых между собой одним пробелом и не содержащих пробелов внутри себя,...

Дана строка S длиной не более 255 символов
Дана строка S длиной не более 255 символов. Подсчитать количество содержащихся в ней цифр. Входные данные: ввести строку S с длиной...

5
 Аватар для Sun Serega
2355 / 1458 / 526
Регистрация: 07.04.2017
Сообщений: 4,798
16.03.2023, 22:05
Лучший ответ Сообщение было отмечено Ilya_2009 как решение

Решение

Цитата Сообщение от Ilya_2009 Посмотреть сообщение
setlength(s,3000);
Мда... Уже б хоть s := #0*3000 - хотя это глупость.

В фри паскале обычные строки размерны - то есть они выделяют для себя на стеке 256 байт.

В .Net строки (все, даже если вы укажете статическую длину) ссылочные - их содержимое хранит в динамической памяти.
Это значит что в случае:
Pascal
1
2
var s1 := #0*3000;
var s2 := s1;
У вас в памяти будет 1 огромная строка на 3000*2 байт (2 байта на символ, потому что юникод)
А обе переменные будут на неё лишь ссылаться

Но это так же значит что просто так менять 1 символ со всей строки нельзя - вдруг на неё другая переменная где то ссылается.
Вместо этого, ваше s[i] := 'F'; делает новую копию строки, но с 1 символом заменённым на F
Разумеется это нереально медленно

Если программируете в PascalABC.NET - лучше использовать только современные методы для строк, а не то что поддерживается ради совместимости.
Pascal
1
2
3
##
var s := ReadString;
s.Println;
## это заголовок короткой программы - по сути заменяет begin-end.

ReadString возвращает строку, поэтому у s тип string автоматически, указывать лишний раз не стоит.

А когда вы ставите точку после переменной - вам показывает все "методы", то есть подпрограммы соответствующего типа (тут - string), вызываемые по точке, как .Println
Советую пробежаться по этому списку хотя бы разок, посмотреть что вообще существует - самое интересное само отложится в памяти на потом.
1
Модератор
10442 / 5734 / 3406
Регистрация: 17.08.2012
Сообщений: 17,442
16.03.2023, 22:50
Ilya_2009, проще говоря, в Pascal ABC.NET и во Free Pascal тоже (а также в многих других паскалях, за исключением Turbo/Borland Pascal), строка запросто может быть длиннее 255 символов.
1
1 / 1 / 0
Регистрация: 02.08.2022
Сообщений: 12
17.03.2023, 12:13  [ТС]
А как тогда рекомендовано менять символ строки? Не создавать ли новую куда записывать ответ, если это что-то поменяет? Оптимизируйте, пожалуйста, моё решение выдуманной задачи.
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
##
//Заменить маленькие буквы "а" на буквы "о"
  var s1 := ReadString;
  var s2:string;
  
  setlength(s2, s1.Length);
 for var i := 1 to s1.Length do
 begin
   
  if s1.chars[i] = 'а' then s2[i] := 'о' else
    s2[i] := s1[i];
    
 end;
 
  s2.Print;
Все "методы" типа .abracadabra, похожи на функции, они не меняют "исходник", а возвращают новое значение. Может быть это из-за того, что они рассчитаны на создание новых строк, а не на редактирование исходных?
0
 Аватар для Sun Serega
2355 / 1458 / 526
Регистрация: 07.04.2017
Сообщений: 4,798
17.03.2023, 14:05
Лучший ответ Сообщение было отмечено Ilya_2009 как решение

Решение

Если надо изменяемую коллекцию символов - есть массив (который быстро изменять, но медленно расширять) и StringBuilder (который быстро расширять, дописывая в символы в конец, но чуть медленнее изменять).

Общий принцип, который работает в любом случае:
Pascal
1
2
3
4
5
6
7
8
## var s1 := ReadString;
 
var sb := new StringBuilder(s1.Length);
foreach var ch in s1 do
  sb += if ch='а' then 'о' else ch;
 
var s2 := sb.ToString;
s2.Println;
Передавать длину s1 в конструктор StringBuilder не обязательно, но так мы указываем сколько места надо заранее, чтобы в процессе добавления символов не перевыделять память.

Или можно скопировать в него все символы из строки и затем уже подменять их:
Pascal
1
2
3
4
5
6
7
8
## var s1 := ReadString;
 
var sb := new StringBuilder(s1);
for var i := 0 to sb.Length-1 do
  if sb[i]='а' then sb[i] := 'о';
 
var s2 := sb.ToString;
s2.Println;
Но в таком случае обёртка в виде StringBuilder не нужна - по сути мы используем всего 1 массив. Можно использовать его напрямую:
Pascal
1
2
3
4
5
6
7
8
## var s1 := ReadString;
 
var a := s1.ToCharArray;
for var i := 0 to a.Length-1 do
  if a[i]='а' then a[i] := 'о';
 
var s2 := new string(a);
s2.Println;
То же самое в 1 строчку (я всё равно разбил на несколько для читабельности):
Pascal
1
2
3
4
5
6
7
## string.Create(
  ReadString
  .ToCharArray
  .ConvertAll(ch->(
    if ch='а' then 'о' else ch
  ))
).Print;
Кроме отсутствия переменных отличий 2:
1. "string.Create" вместо "new string", потому что у точки (после скобок) приоритет больше чем у new.
2. ".ConvertAll" создаёт новый массив из предыдущего, по указанному правилу. То есть в итоге используется 2 промежуточных массива вместо 1

Добавлено через 8 минут
Цитата Сообщение от Ilya_2009 Посмотреть сообщение
Все "методы" типа .abracadabra, похожи на функции, они не меняют "исходник", а возвращают новое значение. Может быть это из-за того, что они рассчитаны на создание новых строк, а не на редактирование исходных?
Метод вообще не может подменить переменную, на которой он вызван. Но может подменить её содержимое. То есть к примеру:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
type
  r1 = record
    i: integer;
    constructor(i: integer) := self.i:=i;
    
    procedure m;
    begin
      //Ошибка: Нельзя поменять self
//      self := new r1(2);
      
      //self.i := 3;
      // то же самое
      i := 3;
    end;
    
  end;
  
begin
  var a := new r1(1);
  a.m;
  Writeln(a);
end.
Но раз string неизменяемы - содержимое метод тоже заменить не может. Остаётся только новую строку делать.

Добавлено через 4 минуты
Ну и это всё нужно если вам в результате нужна именно строка. С LINQ проще:
Pascal
1
2
3
4
## ReadString
.Select(ch->(
  if ch='а' then 'о' else ch
)).Print;
.Select создаёт не новый контейнер данных, вроде массива или строки, а последовательность, у которой можно в любом момент запросить следующий элемент (что делает .Print).
В итоге в памяти хранится только исходная строка и обрабатываемый в данный момент символ.
2
1 / 1 / 0
Регистрация: 02.08.2022
Сообщений: 12
17.03.2023, 18:34  [ТС]
Спасибо, Sun Serega, за такой подробный ответ и советы!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
17.03.2023, 18:34
Помогаю со студенческими работами здесь

Дана строка длиной не более 255 символов. Найти длину самого короткого слова
Дана строка длиной не более 255 символов. Строка содержит слова, разделенные между собой пробелами. Найти длину самого короткого слова.

Распечатать все символы с четными номерами в интервале кодов от 0 до 255
Распечатать все символы с четными номерами в интервале кодов от 0 до 255.

Найти и напечатать все числа, нацело делящиеся на 16 из диапазона 2…255
Добрый вечер. Нужна помощь с заданием по Паскалю: Найти и напечатать все числа, нацело делящиеся на 16 из диапазона 2…255. При организации...

Зашифровать текст(не более 255 символов),записываю все слова наоборот
Зашифровать текст(не более 255 символов),записываю все слова наоборот.Считать,что слова в тексте отделены друг от друга одним пробелом.

421 cannot connect to SMPT server 255.255.255.255 (255.255.255.255:25)
Добрый день! при вызове bool mSocket::Connect(int port,char* adr) { hostent* hn; if (0==(hn = gethostbyname...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru