Джава:Самый простой способ заменить строки случайными строками

StackOverflow https://stackoverflow.com/questions/237058

  •  04-07-2019
  •  | 
  •  

Вопрос

Строка будет состоять из определенных символов (например, ax,bx,dx,c,acc) и цифр.

бывший:AX 5 5 DX 3 ACC C AX BX

Я хочу заменить один или все символы (случайным образом) другим символом того же набора.т. е. замените один из {ax,bx,dx,c,acc} на один из {ax,bx,dx,c,acc}.

пример замены:АКК 5 5 dx 3 акк c ax bx или c 5 5 dx 3 акк c ax ax

Есть ли способ сделать это с помощью регулярных выражений?На Яве?Если да, то какие методы мне следует использовать?

Это было полезно?

Решение

Я думаю, что это наиболее чистое решение для замены определенного набора символов из строки, содержащей их надмножество.Appendreplacement является ключом к этому методу.одно важное предостережение:не включайте в список элементов неэкранированные символы доллара ($).избежать их, используя « $» в конечном итоге использовать
.replaceall("\$","\\$");для каждой строки перед добавлением ее в список.см. также Javadoc сомневаюсь в знаках $.

import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class ReplaceTokens {
public static void main(String[] args) {
    List<String> elements = Arrays.asList("ax", "bx", "dx", "c", "acc");
    final String patternStr = join(elements, "|"); //build string "ax|bx|dx|c|acc" 
    Pattern p = Pattern.compile(patternStr);
    Matcher m = p.matcher("ax 5 5 dx 3 acc c ax bx");
    StringBuffer sb = new StringBuffer();
    Random rand = new Random();
    while (m.find()){
        String randomSymbol = elements.get(rand.nextInt(elements.size()));
        m.appendReplacement(sb,randomSymbol);
    }
    m.appendTail(sb);
    System.out.println(sb);
}

/**
 * this method is only needed to generate the string ax|bx|dx|c|acc in a clean way....
 * @see org.apache.commons.lang.StringUtils.join    for a more common alternative...
 */
public static String join(List<String> s, String delimiter) {
    if (s.isEmpty()) return "";
    Iterator<String> iter = s.iterator();
    StringBuffer buffer = new StringBuffer(iter.next());
    while (iter.hasNext()) buffer.append(delimiter).append(iter.next());
    return buffer.toString();
}

Другие советы

Чтобы ответить на первый вопрос:нет.

Поскольку вы выполняете случайную замену, регулярное выражение вам не поможет, в регулярном выражении нет ничего случайного.* Поскольку ваши строки находятся в массиве, вам не нужно находить их с помощью какого-либо сопоставления с образцом, поэтому регулярное выражение снова не требуется.

**Редактировать:вопрос был отредактирован, поэтому в нем больше не говорится, что строки находятся в массиве.В этом случае, предполагая, что все они находятся в одной большой строке, вы можете создать регулярное выражение, чтобы найти части, которые хотите заменить, как показано в других ответах.*

  1. Да, это можно сделать с помощью регулярных выражений.Наверное, не очень красиво, нет. без петли или двух
  2. Да, это можно реализовать на Java.
  3. Видеть Случайный, регулярное выражение упаковка
  4. Реализация оставлена ​​в качестве упражнения для студента.

Использовать Случайный класс для генерации случайного целого числа для выбора индекса символов.

    String text = "ax 5 5 dx 3 acc c ax bx";
    System.out.println("Original: " + text);
    String[] tokens = text.split(" ");
    List<Integer> symbols = new ArrayList<Integer>();
    for(int i=0; i<tokens.length; i++) {
        try {
            Integer.parseInt(tokens[i]);
        } catch (Exception e) {
            symbols.add(i);
        }
    }
    Random rand = new Random();
    // this is the part you can do multiple times
    int source = symbols.get((rand.nextInt(symbols.size())));
    int target = symbols.get((rand.nextInt(symbols.size())));
    tokens[target] = tokens[source];

    String result = tokens[0];
    for(int i=1; i<tokens.length; i++) {
        result = result + " " + tokens[i];
    }
    System.out.println("Result: " + result);

Сделайте столько замен, сколько вам нужно до ты присоединиться жетоны снова вместе.

Здесь есть две части, которые могут показаться сложными.Во-первых, попытайтесь поймать те токены, которые не являются целыми числами.Я рекомендую вам выделить эту часть в отдельный метод, поскольку она работает, но немного хаотично.

Во-вторых, я установил source и target переменные.Что я там делаю, так это получаю случайно выбранный индекс одного из нечисловых символов.Если у меня есть два случайных индекса, я могу поменять их местами в следующей строке.

Альтернативой может быть создание новой строки из случайно выбранных символов после того, как вы разделили исходную строку на массив.

спасибо большое, ребята.вот что я придумал.посмотрим, сможете ли вы придумать более эффективный способ.

private final String[] symbolsPossible = {"ax","bx","cx","dx","foo"};
private boolean exists;
private final String mutate(String s)
{
String[] tokens=s.split(" ");
for(int j=0; j<tokens.length; j++)
if(Math.random()<.1) //10% chance of mutation per token
{
//checking to see if the token is a supported symbol
exists=false;
for(int i=0; i<symbolsPossible.length; i++)
    if(tokens[j].equals(symbolsPossible[i]))
       exists=true;
if(exists)
    tokens[j]=symbolsPossible[(int)Math.random()*symbolsPossible.length];
}
StringBuffer result=new StringBuffer();
for(String t:tokens)
    result.append(t);
return result;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top