Как я могу улучшить свою функцию скремблирования строк, которая может включать различные символы, цифры и голанг строк?

# #go #testing #ascii #shuffle #scramble

Вопрос:

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

  • Если у нас есть символ»‘», не перемешивайте его.

Проблема в том, что я ожидаю распечатать, как в разделе «Хочу», но получаю другой результат . Например: вместо a -> aa , metatr ->> metater и т. Д. Я использую seed = 100

Функция для токенизации:

 import "regexp"

func tokenize(text string) []string {
    re := regexp.MustCompile(`[A-Za-z0-9'] |[':;?().,!\ ]`)
    return re.FindAllString(text, -1)
}
 

Шифровальный код

 import (
    "math/rand"
    "strconv"
)

func scramble(text string, seed int64) string {
    rand.Seed(seed)
    slicy := tokenize(text)
    var str string = ""
    for a := 0; a < len(slicy); a   {

        _, err := strconv.Atoi(slicy[a])
        if err != nil {

            var shufle []byte
            for i := 1; i < len(slicy[a])-1; i   {
                shufle = append(shufle, slicy[a][i])
            }

            if slicy[a] != " " amp;amp; slicy[a] != "." amp;amp; slicy[a] != "," amp;amp; slicy[a] != "(" amp;amp; slicy[a] != ")" {
                new_length := 0
                for d := 0; d < len(shufle); d   {
                    if string(shufle[d]) == "'" {
                        new_length = d - 1
                    }
                }
                if new_length != 0 {
                    for l := 0; l < new_length-1; l   {
                        m := l   1
                        shufle[l], shufle[m] = shufle[m], shufle[l]
                    }
                } else {
                    rand.Shuffle(len(shufle), func(k, j int) {

                        shufle[k], shufle[j] = shufle[j], shufle[k]
                    })
                }

                var scrambled_list []byte
                scrambled_list = append(scrambled_list, slicy[a][0])
                for d := 0; d < len(shufle); d   {
                    scrambled_list = append(scrambled_list, shufle[d])
                }
                scrambled_list = append(scrambled_list, slicy[a][len(slicy[a])-1])

                str = str   string(scrambled_list)
            } else {
                switch slicy[a] {
                case " ":
                    str  = " "
                case ".":
                    str  = "."
                case "(":
                    str  = "("
                case ")":
                    str  = ")"
                case ",":
                    str  = ","
                default:

                }
            }
        } else {
            return text
        }
    }

    return str
}
 

Когда я тестирую его, у меня не получается:

Ввод:

 "it doesn't matter in what order the letters in a word are, the only important thing is that the first and last letter be at the right place."
 

Хотеть:

  "it deson't metatr in waht oredr the lettres in a wrod are, the only inmproatt thing is taht the frist and last letetr be at the right plcae."
 

Что я получаю:

«это не значит, что в вах-одре леретты в аа-роде, главное, чтобы фисрт и последний литтр были в нужном месте».

Комментарии:

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

2. @NuLo проблема в том, что я ожидаю распечатать, как в разделе «Хочу», но получаю другой результат . Например: вместо a -> aa , metatr ->> metater и т. Д. Я использую seed = 100

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

4. пожалуйста, приведите воспроизводимый пример. play.golang.org/p/QSj_1YbFL29

Ответ №1:

это альтернативное решение, учитывая мое понимание требований OP.

В случае, если это не нбурем, скрмаебл еахк wosrd, бту левае итнакт теохс ссеахрсрта «‘».,()», frtsi lrteet и ltsa ltreet.

Он использует bufio.Сканер, настроенный для разделения ввода по словам с помощью bufio.СканВорды.

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

Чтобы перетасовать слово, он сканирует его по частям text until ".,()'"" с помощью строк.IndexAny, затем каждая порция перемешивается с помощью rand.Шарканье.

 package main

import (
    "bufio"
    "fmt"
    "math/rand"
    "strconv"
    "strings"
)

func main() {
    input := `Within a sentence, if it is not a number, scramble each words, but leave intact those characters "'".,()", the first letter, and the last letter.`
    output := scramble(input, 100)
    fmt.Printf("%vn", input)
    fmt.Printf("%vn", output)
}

func scramble(text string, seed int64) (output string) {
    rand.Seed(seed)

    b := bufio.NewScanner(strings.NewReader(text))
    b.Split(bufio.ScanWords)

    for b.Scan() {
        w := b.Text()
        _, err := strconv.Atoi(w)
        if err == nil || len(w) < 2 {
            output  = w
        } else {
            output  = shuffleWord(w)
        }
        output  = " "
    }
    return strings.TrimSuffix(output, " ")
}

func shuffleWord(input string) (output string) {
    if len(input) < 2 {
        output = input
        return
    }
    r := []rune(input)
    ln := len(r)
    for i := 1; i < ln-1; i   {
        n := strings.IndexAny(input[i:], ".,()'"")
        if n == -1 {
            n = ln - i
        }
        if n > 0 {
            rand.Shuffle(n, func(k, j int) {
                r[i k], r[i j] = r[i j], r[i k]
            })
            i  = n - 1
        }
    }
    output = string(r)
    return
}
 

попробуйте это здесь