Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.06.2019, 16:32   #1
0xyg3n
 
Регистрация: 12.05.2019
Сообщений: 4
По умолчанию Смешать рандомно символы в строке

Здравствуйте всем.
Есть строка string, размер ранее не известен.
Нужно перемешать все символы в строке. Чтоб порядок символов изменился. Например строка "abc123" стала "a2b1c3". В общем что-то в этом роде.
Задача, казалось бы не трудная, но реализация ее у меня заняла некоторое время. Код получился громоздкий и не очень быстрый, да еще и через костыли. Приводить его здесь просто стыдно.
Может быть натолкнете, или у кого есть похожий пример или готовое решения, буду очень признателен за помощь.
0xyg3n вне форума Ответить с цитированием
Старый 22.06.2019, 19:34   #2
ViktorR
Старожил
 
Регистрация: 23.10.2010
Сообщений: 2,306
По умолчанию

Вот тут есть алгоритмы перетасовки
https://ru.wikipedia.org/wiki/%D0%A2...82%D1%81%D0%B0
Пример на Паскале (у меня FPC)
Код:
uses crt;   {это исключительно для тестирования}
function FisherCycle(var s: string): string; {первый алгоритм из ссылки}
var i, j, n: word;
         ch: char;
begin
   n := Length(s);
   for i := n - 1 downto 1 do
   begin
      j := random(i + 1) + 1;
      ch := s[j];
      s[j] := s[i];
      s[i] := ch;
   end;
   FisherCycle := s;
end;

function SattoloCycle(var s: string): string; {другой алгоритм из ссылки}
var i, j, n: word;
         ch: char;
begin
   i := Length(s);
   while i > 1 do
   begin
      i := i - 1;
      j := random(i + 1) + 1;
      ch := s[j];
      s[j] := s[i];
      s[i] := ch;
   end;
   SattoloCycle := s;
end;

var s, s1, s2: string;
begin
   randomize;
   writeln('Input text with chars <= 255): ');
   readln(s);
   Repeat {этот цикл завершается по нажатию любой клавиши}
      s1 := s;
      s2 := s;
      writeln('NewF: ', FisherCycle(s1));
      writeln('NewS: ', SattoloCycle(s2));
   Until KeyPressed;
   readln;
end.
Заметил, что последний символ редко участвует в перемешивании.
Но это вроде как проблема генератора случайных чисел.
Как-то так, ...
ViktorR вне форума Ответить с цитированием
Старый 22.06.2019, 22:55   #3
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

я предложил бы такой код:
https://www.programmersforum.ru/show...8&postcount=13

Код:

var
 s : string;
 i,k, N:integer;
 buf : char;
begin
 Randomize; 
 
 s := 'abc123';

 //----------перемешать-------------
 N := Length(s);
 for i:=1 to N-1 do
  begin
   k:= Random(N-i+1)+i;
   if k<>i then begin
     buf:=s[i];
     s[i]:=s[k];
     s[k]:=buf;
   end;
  end;
 
 WriteLn(s);

end.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 22.06.2019, 23:36   #4
Вадим Мошев

Старожил
 
Аватар для Вадим Мошев
 
Регистрация: 12.11.2010
Сообщений: 8,568
По умолчанию

И от меня пример: https://www.programmersforum.ru/show...060#post960060

Строка — это массив символов.
Вадим Мошев вне форума Ответить с цитированием
Старый 23.06.2019, 14:58   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от Вадим Мошев Посмотреть сообщение
И от меня пример
Вадим, только хочу предостеречь - https://www.programmersforum.ru/show...27&postcount=4
ссылка "Как не надо тасовать карты"
суть - простое перемешивание не даёт нормальное распределение
Serge_Bliznykov вне форума Ответить с цитированием
Старый 23.06.2019, 15:08   #6
Вадим Мошев

Старожил
 
Аватар для Вадим Мошев
 
Регистрация: 12.11.2010
Сообщений: 8,568
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
простое перемешивание не даёт нормальное распределение
Может, я что-то не понимаю, но, может нормальное распределение не нужно при перемешивании? Я думаю, что для перемешивания нужно равномерное распределение, чтобы вероятность появления какого-то элемента на каком-то месте была везде одинакова?

Вообще, когда я писал тот код, я не задумывался о распределении. Просто был нужен случайный порядок.

Или вы опечатались и хотели сказать "равномерное" распределение? По ссылке вы о нём и говорите.
Вадим Мошев вне форума Ответить с цитированием
Старый 23.06.2019, 23:12   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от Вадим Мошев Посмотреть сообщение
Или вы опечатались и хотели сказать "равномерное" распределение? По ссылке вы о нём и говорите.
точно так.

Цитата:
Вторая проблема: плохое распределение раздач

Более близкое изучение тасующего алгоритма показывает, что, независимо от первой проблемы, он не дает равномерное распределение раздач. То есть некоторые раздачи более вероятны, чем другие. Неравное распределение может превратиться в преимущество, если знающий об этом игрок просидит за столом достаточно долго.
Цитата:
Сообщение от Вадим Мошев Посмотреть сообщение
Вообще, когда я писал тот код, я не задумывался о распределении. Просто был нужен случайный порядок.
Воля ваша. Можно использовать любой алгоритм.
Ну, зачем делать плохо, если можно сделать хорошо?
И, в любом случае, нужно знать, что за алгоритм используешь и какие он имеет особенности.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 05.10.2020, 13:04   #8
canadamoscow
Пользователь
 
Аватар для canadamoscow
 
Регистрация: 16.05.2020
Сообщений: 57
По умолчанию

На PascalABC.NET это так:
Код:
begin
  //var s := ReadlnString;
  var s := '1234567890asdfzxcvqwer';
  Writeln(1,'-й вариант: ',s.ToCharArray.Shuffle.JoinToString);
  loop s.Length do swap(s[Random(1,s.Length)],s[Random(1,s.Length)]);
  Writeln(2,'-й вариант: ',s);
end.
canadamoscow вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

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

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как заменить символы в строке на С? masha99 Помощь студентам 1 30.11.2018 11:29
Символы в строке KT82 Общие вопросы C/C++ 4 21.01.2016 20:20
Символы в строке. Predator199 PHP 1 21.10.2012 14:42