質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

解決済

2回答

260閲覧

[Go] 同じ関数に同じ引数を与えているのに、2度目の処理が動かなくなる。

nooon0800

総合スコア10

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

0グッド

0クリップ

投稿2018/10/05 13:57

編集2018/10/05 14:14

前提・実現したいこと

Golangの勉強のため、言語処理100本ノック#9
(http://www.cl.ecei.tohoku.ac.jp/nlp100/#sec09)を解いています。

その中の処理の一部で、単語を引数として与えると、
「単語の先頭と末尾の文字は残し,それ以外の文字の順序をランダムに並び替える
文字列」をreturnするという関数random()を実装しようとしています。

下記の事象に陥り、試行錯誤したものの自力で脱出できなくなってしまったため、
この実装の何が問題なのかをご指摘いただきたいです。

発生している問題・エラーメッセージ

関数random()に
文字列"testtest"を与えると、1度目はちゃんと機能をするのですが、
同じ文字列をさらに与えると、2度目の処理が待ち状態になったままになってしまいます。

実行結果: tstestet <このまま待ち状態になるため強制終了...>

該当のソースコード

func random(x string) (string) { var random string = "" var random_target []string = nil var random_num []int = nil var num int = 0 var skip_flag string = "" for i := 2 ; i <= len(x)-1 ; i++ { random_target = append(random_target,x[i-1:i]) } num = rand.Intn(len(random_target)) random_num = append(random_num,num) for len(random_num) < len(random_target) { num = rand.Intn(len(random_target)-1) for i :=1 ; i <= len(random_num) ; i++ { if random_num[i-1] == num { skip_flag = "skip" } } switch skip_flag { case "skip" : skip_flag = "" default : random_num = append(random_num,num) } } for i := 1 ; i <= len(x) ; i++ { switch i { case 1,len(x) : random = random + x[i-1:i] default : random = random + random_target[random_num[i-2]] } } return random }
func main() { fmt.Print("\n") fmt.Print(random("testtest")) fmt.Print("\n") fmt.Print(random("testtest")) fmt.Print("\n") }

試したこと

3文字の文字列"tst"を与えると、2度目でも動作しました。
2度目&4文字以上の文字列のときにこの事象がおこります。

補足情報(FW/ツールのバージョンなど)

Golang のバージョンは1.10を使用しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

これは別解ですので、参考程度にどうぞ。

  1. Typoglycemia

スペースで区切られた単語列に対して,各単語の先頭と末尾の文字は残し,それ以外の文字の順序をランダムに並び替えるプログラムを作成せよ.ただし,長さが4以下の単語は並び替えないこととする.適当な英語の文(e.g. I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind .)を与え,その実行結果を確認せよ.

go

1package main 2 3import ( 4 "fmt" 5 "math/rand" 6 "time" 7 "strings" 8) 9 10// 単語の先頭と末尾の文字は残し,それ以外の文字の順序をランダムに並び替える 11func shuffle(word string) (string) { 12 arr := []rune(word) 13 rand.Seed(time.Now().UnixNano()) 14 for i := len(word) - 2; i > 1; i-- { 15 j := rand.Intn(i) + 1 16 arr[i], arr[j] = arr[j], arr[i] 17 } 18 return string(arr) 19} 20 21 22// スペースで区切られた単語列をランダムに並べ替える 23// ただし,長さが4以下の単語は並び替えない 24func generateTypoglycemia(src string) (string) { 25 dst := []string{} 26 for _,word := range strings.Split(src, " ") { 27 if (len(word) <= 4) { 28 dst = append(dst, word) 29 } else { 30 dst = append(dst, shuffle(word)) 31 } 32 } 33 return strings.Join(dst, " ") 34} 35 36// エントリーポイント 37func main() { 38 src := "I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind ." 39 dst := generateTypoglycemia(src) 40 41 fmt.Println(src) 42 fmt.Println(dst) 43}

実行結果

text

1I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind . 2I co'ulndt bveliee that I cloud alatlcuy urtdasnned what I was rideang : the paneohneml pwoer of the hamun mind .

投稿2018/10/06 02:37

編集2018/10/09 08:29
shozi3

総合スコア691

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nooon0800

2018/10/06 03:45

ありがとうございます。参考にさせていただきます。
guest

0

自己解決

関数random()内で
・strinng型配列random_targetにシャッフル対象の文字列を格納
・int型配列random_numに0~<random_targetの配列数-1>を格納
random_numの配列のなかみを配列番号としてrandom_targetから文字をランダム抽出する方式で実装していました。

もともとの実装方法では、
random_numの配列への要素追加の1巡目で0~<random_targetの配列数>にしてしまっていて、ランダムの対象範囲が1多い状態になってしまっていました。

num = rand.Intn(len(random_target)) random_num = append(random_num,num)

そのあたりを下記のように書き直すと、想定通りの動作ができるようになりました。

//num = rand.Intn(len(random_target)) //random_num = append(random_num,num) for len(random_num) < len(random_target) { num = rand.Intn(len(random_target)-1) //for i :=1 ; i <= len(random_num) ; i++ { for i :=0 ; i <= len(random_num) ; i++ { switch i { case 0 : random_num = append(random_num,num) default : if random_num[i-1] == num { skip_flag = "skip" } } } switch skip_flag { case "skip" : skip_flag = "" default : random_num = append(random_num,num) } }
実行結果: tsttestt teeseest

投稿2018/10/06 04:03

nooon0800

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問