How can I improve my scramble string function whiche may include different symbols, numbers and string Golang?

huangapple go评论91阅读模式
英文:

How can I improve my scramble string function whiche may include different symbols, numbers and string Golang?

问题

这是一个创建函数的想法,该函数接受一个包含整数、文本和符号(如',.等)的字符串:

  • 如果字符串中有数字,则返回字符串。
  • 单词中的第一个和最后一个字母应保持不变,只对其他字母进行混淆。
  • 如果字符串中有'符号,则不要混淆它。

问题在于,我期望输出与所需部分相同,但得到了另一个结果。例如:而不是 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] != " " && slicy[a] != "." && slicy[a] != "," && slicy[a] != "(" && 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."

实际输出:

"it deson't metater in waht odrer the leretts in aa wrod are, the olny imtoaprnt thnig is that the fisrt and last leettr be at the right place."
英文:

The idea was to create a function that takes a string of some integers, text that can also include symbols like ',. etc.
-If there is numbers in a string, return string
-The first and last letter in a word should be untouched. Scramble only other letter.

  • If we have a "'" symbol, don't scramble it.

The problem is that I expect to print out as in the want section, but getting another result . For example: instead of a -> aa , metatr -> metater etc. I use seed = 100

Function to tokenize:

import &quot;regexp&quot;

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

Scramble code

import (
	&quot;math/rand&quot;
	&quot;strconv&quot;
)

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

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

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

			if slicy[a] != &quot; &quot; &amp;&amp; slicy[a] != &quot;.&quot; &amp;&amp; slicy[a] != &quot;,&quot; &amp;&amp; slicy[a] != &quot;(&quot; &amp;&amp; slicy[a] != &quot;)&quot; {
				new_length := 0
				for d := 0; d &lt; len(shufle); d++ {
					if string(shufle[d]) == &quot;&#39;&quot; {
						new_length = d - 1
					}
				}
				if new_length != 0 {
					for l := 0; l &lt; 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 &lt; 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 &quot; &quot;:
					str += &quot; &quot;
				case &quot;.&quot;:
					str += &quot;.&quot;
				case &quot;(&quot;:
					str += &quot;(&quot;
				case &quot;)&quot;:
					str += &quot;)&quot;
				case &quot;,&quot;:
					str += &quot;,&quot;
				default:

				}
			}
		} else {
			return text
		}
	}

	return str
}

When i test it, i fails on:

Input:

&quot;it doesn&#39;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.&quot;

Want:

 &quot;it deson&#39;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.&quot;

What I get:

"it deson't metater in waht odrer the leretts in aa wrod are, the olny imtoaprnt thnig is that the fisrt and last leettr be at the right place."

答案1

得分: 2

根据我对问题要求的理解,这是一个替代方案。

在一个句子中,如果一个单词不是数字,就对每个单词进行混淆,但保留那些字符 "'.,()" 的第一个字母和最后一个字母。

它使用配置为使用 bufio.ScanWords 将输入按单词拆分的 bufio.Scanner

当找到一个单词时,如果它被检测为数字,则保持不变,否则,它会检查单词的长度,如果长度大于2,则对单词进行混淆。

为了混淆单词,它使用 strings.IndexAny 将单词按照 ".,()'\"" 的部分进行扫描,然后使用 rand.Shuffle 对每个部分进行混淆。

你可以在 这里 尝试它。

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 "&#39;\.,()", the first letter, and the last letter.`
	output := scramble(input, 100)
	fmt.Printf("%v\n", input)
	fmt.Printf("%v\n", 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:], ".,()&#39;\\\"")
		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
}

请在 这里 尝试它。

英文:

this is an alternative solution given my understanding of OP requirements.

> Wthiin a seneetnc, if it is nto a nburem, scrmaebl eahc wosrd, btu levae itnact teohs cceahrsrta "'&quot;.,()", the frtsi lrteet, and the ltsa ltreet.

It uses the bufio.Scanner configured to split the input by words using bufio.ScanWords.

When a word is found, if it is detected as a number it leaves it intact, otherwise, it checks for the length of the word, if it is greater than 2, then it shuffle the word.

To shuffle the word, it scans it by portion of text until &quot;.,()&#39;\&quot;&quot; using strings.IndexAny, each portion is then shuffled using rand.Shuffle.

package main
import (
&quot;bufio&quot;
&quot;fmt&quot;
&quot;math/rand&quot;
&quot;strconv&quot;
&quot;strings&quot;
)
func main() {
input := `Within a sentence, if it is not a number, scramble each words, but leave intact those characters &quot;&#39;\&quot;.,()&quot;, the first letter, and the last letter.`
output := scramble(input, 100)
fmt.Printf(&quot;%v\n&quot;, input)
fmt.Printf(&quot;%v\n&quot;, 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) &lt; 2 {
output += w
} else {
output += shuffleWord(w)
}
output += &quot; &quot;
}
return strings.TrimSuffix(output, &quot; &quot;)
}
func shuffleWord(input string) (output string) {
if len(input) &lt; 2 {
output = input
return
}
r := []rune(input)
ln := len(r)
for i := 1; i &lt; ln-1; i++ {
n := strings.IndexAny(input[i:], &quot;.,()&#39;\&quot;&quot;)
if n == -1 {
n = ln - i
}
if n &gt; 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
}

try it here

huangapple
  • 本文由 发表于 2021年9月18日 18:48:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/69233938.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定