Форум программистов
 
О проблемах, например, с регистрацией пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail, а тут можно восстановить пароль.

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

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

Здесь нужно купить рекламу за 20 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru
Без учёта ботов - 20000 человек в день, 350000 в месяц.

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

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

Вот тут есть алгоритмы перетасовки
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, 23:55   #3
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,260
По умолчанию

я предложил бы такой код:
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 вне форума Ответить с цитированием
Старый 23.06.2019, 00:36   #4
Вадим Мошев

 
Регистрация: 12.11.2010
Сообщений: 8,590
По умолчанию

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

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

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

 
Регистрация: 12.11.2010
Сообщений: 8,590
По умолчанию

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

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

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

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

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

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

Здесь нужно купить рекламу за 20 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru
Без учёта ботов - 20000 человек в день, 350000 в месяц.

Опции темы


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


Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru
Пеллетный котёл Emtas
котлы EMTAS