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

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

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

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

Q&A

解決済

1回答

1585閲覧

【Go言語のスライス操作】05/23 AtCoderRegularContest120のA問題について。

Jonathan_Sf

総合スコア13

Go

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

0グッド

0クリップ

投稿2021/05/23 16:51

編集2021/05/23 16:53

お世話になります。

AtCoderに取り組んでいるGo言語初心者です。
昨日のAtCoderRegularContestのA問題について、下記のように回答を作成しましたが、うまくいきません。原因もわかっているのですが、対処法が思い付かず、ご教示いただけましたら幸いです。

問題はこちらをご参照ください。

方針としては下記です。

1、標準入力から得た配列numbsに対し繰り返し処理をします。
2、この配列numbsの要素を一部分取り出したスライスsliceを作り、問題文で定義された操作を行います。ループのたびにsliceの長さは1からNまで1ずつ増やします。
3、sliceの総和を出力して次の繰り返し処理を行います。

一言で言えば原因は、2の操作を行う際に、numbsの値も書き換わってしまうからです。(コードの当該箇所をご覧ください。)

これは、スライスが内部にポインタを持つデータ型であるためと理解しています。sliceを書き換えると参照元であるnumbsの値も変わってしまい、ループの2周目以降、sliceの中身が意図したものでなくなってしまっています。

原因はわかっているのですが、どのように実装すれば良いかわからず、ヒントをいただけませんでしょうか。詰まるところ解決策としては、sliceの参照元であるnumbsの値を書き換えることなく、内側のループ内でのみsliceの値を変更できれば良いのですが、、、。

よろしくお願いします。

Go

1 2package main 3 4import ( 5 "bufio" 6 "fmt" 7 "os" 8 "sort" 9 "strconv" 10 "strings" 11) 12 13var sc = bufio.NewScanner(os.Stdin) 14 15func main() { 16 s, t := nextLine(), nextLine() 17 N, _ := strconv.Atoi(s) 18 words := strings.Fields(t) 19 numbs := StrToInt(words) 20 21 22//当該箇所 23 for i := 1; i <= N; i++ { 24 slice := numbs[0:i]  //Aが原因で2回目以降の繰り返し処理の際、sliceの値が変わってしまう。 25 for k, _ := range slice { 26 slice[k] += maxInt(slice)//この時、numbsも書き換わってしまう。(A) 27 } 28 fmt.Println(Sum(slice)) 29 } 30//当該箇所 31 32 33} 34 35func nextLine() string { 36 sc.Scan() 37 return sc.Text() 38} 39 40// 最大値を求める。 41func maxInt(slice []int) int { 42 sort.Sort(sort.IntSlice(slice)) 43 return slice[len(slice)-1] 44} 45 46//総和を求める。 47func Sum(arr []int) int { 48 ret := 0 49 for i := 0; i < len(arr); i++ { 50 ret += arr[i] 51 } 52 return ret 53} 54 55//型変換(文字列から整数) 56func StrToInt(str []string) []int { 57 f := make([]int, len(str)) 58 for n := range str { 59 f[n], _ = strconv.Atoi(str[n]) 60 } 61 return f 62} 63

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

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

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

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

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

guest

回答1

0

ベストアンサー

ループ内でコピーしてそれを書き換えれば元の配列に影響しません。
コピーすると速度が出ないことを心配してるのかもしれませんが、もっと大きなボトルネックがあるので心配するだけ無駄です。

投稿2021/05/23 18:17

yudedako67

総合スコア2047

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

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

Jonathan_Sf

2021/05/26 11:29

ご回答ありがとうございました。ご回答をもとに修正したところ、テストケースについては正しく答えを求めることができました。しかしまた、ほとんどのケースでREとなってしまったのもご指摘通り?でした。こちらの問題につきまして、下記エントリにてまた質問させていただいたので、よろしければご覧いただけますと幸いです。この度はありがとうございました。 https://teratail.com/questions/340509?modal=q-comp
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問