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

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

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

if文とは様々なプログラミング言語で使用される制御構文の一種であり、条件によって処理の流れを制御します。

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

Q&A

解決済

2回答

1616閲覧

プログラミング超初心者の質問です。

H-JURI

総合スコア42

if

if文とは様々なプログラミング言語で使用される制御構文の一種であり、条件によって処理の流れを制御します。

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

0グッド

0クリップ

投稿2015/10/20 10:20

問題の解答例がいまいちよくわかりません。問題は「"a"のあとの3文字以内に"z"がある文字列のものをtrueと返すメソッドを書け」です。

解答例の自分なりの解釈をコードの横に#で書くので、もし間違っている解釈があれば指摘してください。また、「??」が付いている解釈がよくわからなかったところです。以下に質問内容を書かせてもらってます。

lang

1#問題の原文 2# Write a method that takes a string in and returns true if the letter 3# "z" appears within three letters **after** an "a". You may assume 4# that the string contains only lowercase letters. 5 6 7def nearby_az(string) #nearby_az(string)というメソッドを定義します 8 idx1 = 0 #変数idx1に0を代入します。 9 while idx1 < string.length #idx1よりも文字列の文字数が多い時、以下を繰り返す 10 if string[idx1] != "a" #もし文字列のidx1番目の文字が"a"でなかった場合、 11 idx1 += 1 #idx1に1をたす 12 next **#次に行く??** 13 end #ifを終わる 14 15 idx2 = idx1 + 1 #変数idx2をidx1+1とする 16 while (idx2 < string.length) && (idx2 <= idx1 + 3) #idx2が文字列の文字数より少なく、かつidx1+3以下の時、以下を繰り返す 17 if string[idx2] == "z" #もし文字列のidx2番目の文字が"z"なら 18 return true #trueを返す 19 end #ifを終わる 20 21 idx2 += 1 #idx2に1をたす 22 end #以上を繰り返す 23 24 idx1 += 1 **#idx1に1をたす??** 25 end #以上を繰り返す 26 27 return false #falseを返す 28end #終わり 29 30 31 32# These are tests to check that your code is working. After writing 33# your solution, they should all print true. 34 35puts('nearby_az("baz") == true: ' + (nearby_az('baz') == true).to_s) 36puts('nearby_az("abz") == true: ' + (nearby_az('abz') == true).to_s) 37puts('nearby_az("abcz") == true: ' + (nearby_az('abcz') == true).to_s) 38puts('nearby_az("a") == false: ' + (nearby_az('a') == false).to_s) 39puts('nearby_az("z") == false: ' + (nearby_az('z') == false).to_s) 40puts('nearby_az("za") == false: ' + (nearby_az('za') == false).to_s)
  1. nextの意味がよくわからないです。一つ目のif文はもし指定の番号idx1の文字が"a"でないなら、次の文字が"a"なのか確かめにもう一回if文の最初に戻るのか、もしくは次のコード(idx2の方)に移動するのかわからないです。また、もし前者の場合、if文の最初に戻るのはnextの効果ですか?またはwhileの効果ですか?

(後者の場合次のコードにいくと"a"を発見できていない状態で次に行くことになるのでおかしいとは思いますが。。。)

  1. 下から4文目のidx1 + 1の必要性がわからないです。おそらくそれまでに全ての文字列の文字の検証が終わっていると思うので次の文字に行く必要がない気がします。ただこのidx1 + 1をとり実行すると、

lang

1nearby_az("baz") == true: true 2nearby_az("abz") == true: true 3nearby_az("abcz") == true: true 4

のようになり6つ欲しいtrueの結果が3つしか得られず、ここで矢印キーをおすと、

lang

1nearby_az("baz") == true: true 2nearby_az("abz") == true: true 3nearby_az("abcz") == true: true 4 5 6^[[B^[[B^[[A^[[A^[[B^[[D^[[A^[[B^[[C^[[A

のように、よくわからない文字列がでてきます。これは一体なんなのでしょうか?

長文になってしまいましたが、ご教授お願いします。

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

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

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

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

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

guest

回答2

0

題意を簡単に実装する方法をご紹介します。

ruby

1def identify(text) 2 ident = false 3 texts = text.split(‘a’) # 文字列をaで区切って配列に分けます。 4 texts.each do |parts| 5 index = parts.index(‘z’) # zが先頭から数えてどこにあるのか調べます。無かったら -1 を返します。 6 if index != -1 && index <= 3 then # -1 以外 (zが見つかってること) かつ 3文字以内にあること。 7 ident = true 8 end 9 end 10 return ident 11end

実行すると下記の通り。

bash

1text1 = “abcdzabbz” 2 # split -> ["", "bcd", bbz] -> index -> -1, -1, -1, 3 -> bizは、aから3つ以内にzがある。 3text2 = “ababababcdz” 4 # split -> ["", "b", "b", "b", "bcdz"] -> index -> -1, -1, -1, 4 -> bcdは、aから4つ後ろにzがある。 5print(identify(text1)) # -> true 6print(identify(text2)) # -> false

という感じです。

実行中にキーを押すと文字列が出てしまうのはですね、
コンソールがキーコードを表示しているからです。

特にソースが悪いわけでも、
プログラムの動作に影響を与えないものなので、お気になさらず。

投稿2015/10/20 13:34

編集2015/10/20 13:38
SKYYFISH

総合スコア654

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

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

H-JURI

2015/10/21 02:20

回答ありがとうございます! 貴重な別解ありがとうございます。ぜひ参考にしたいです! ところで見当違いかもしれませんが、この別解について質問させていただきます。この別解だともし文字列に"a"が入っていなければうまくいかない気がするのですがどうなのでしょう? もしうまくいくならば、なぜですか?
SKYYFISH

2015/10/21 14:27

お尋ねの意味は、文字列にaが入っていないとプログラムがエラーを起こすのではないかということでしょうか?そのような意図でしたら、配列化されずに文字列として変数に入るだけですので、大丈夫です。
guest

0

ベストアンサー

処理の流れの理解は概ねあっているようなので、??の部分についてお答えします

処理する文字列の例として以下とします

string = "baz"

配列イメージはこんな感じです

[0] = "b"
[1] = "a"
[2] = "z"

  1. の質問

next #次に行く??

この next は、 while の処理を続けるためのものです
while の条件 idx1 < string.length に戻って判定します
直前の idx1 += 1 によって idx1 は変化しているので
"a"が見つからなかった位置情報から次の位置情報に移動し、文字の長さと比較して処理を続けるかどうか判断しています

idx = 0 のとき
最初のifで参照しているのは下図の位置です

[0] = "b" ← idx1
[1] = "a"
[2] = "z"

"a"ではないので idx1+=1 をして while に戻ります
次のifで参照しているのは下図の位置です

[0] = "b"
[1] = "a" ← idx1の位置
[2] = "z"

"a"に合致するので if string[idx1] != "a" の中に入らず end まで進み、3文字チェックの処理へと進んでいきます

2.の質問

idx1 += 1 #idx1に1をたす??

もしもstringの中身に"a"があって"z"がない場合

string = "bab"

ここまでに行われているのは、idx1の値をidx2へ代入し、idx2を使っての位置情報によるチェックです
なので、元のidx1は"a"を見つけた位置のままです

[0] = "b"
[1] = "a" ← idx1の位置
[2] = "b"
← idx2の位置(長さを超えて 3 になっている)

このままでは次のendによってwhileに戻ったとき
idx1 < string.length
の条件が成立し、さらに次の
if string[idx1] != "a"
の条件によって"a"を発見した手順へ進むので、結果、無限ループに陥ります

矢印キーを押したら変なん文字がでたのは、恐らくプログラムが暴走しているせいと思います

以上ご参考になりましたら

投稿2015/10/20 10:55

編集2015/10/20 13:44
takito

総合スコア3111

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

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

H-JURI

2015/10/21 02:15

回答ありがとうございます! 非常にわかりやすい解説ありがとうございます。疑問が解消されたのでベストアンサーにさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問