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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

3323閲覧

文字列内の空白文字を"%20"に置き換えるメソッド

退会済みユーザー

退会済みユーザー

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2016/08/22 13:25

文字列内に出現するすべての空白文字を"%20"に置き換えるメソッドを考えます。
しかし、以下の文章の文意がイマイチ読み取れません。
解答例もあるのですが、その解答例も不明な点が幾つかあるのです。

「文字列内に出現するすべての空白文字を"%20"で置き換えるメソッドを書いてください。ただし、文字列の後ろにはあたらに文字を追加するためのスペースが十分にある(バッファのサイズは気にしなくても良い)ことと、その追加用スペースを除いた文字列の真の長さが与えられます。
(注意)Javaで実装する場合は、追加の領域を使用せずに処理できるように文字配列を使ってください。

入力:"Mr John Smith "
出力;”Mr%20John%20Smith"

(解答)
文字列操作においてよく使用されるアプローチとして、文字列の最後尾から先頭に向かって編集する方法があります。この方法ではバッファの後ろに追加のバッファを加えることができるので、便利ですし、編集時に文字列を上書きしてしまう心配もありません。

では、実際にこのアプローチを使ってみましょう。2回の走査を行います。最初の走査では空白文字の数を数えます。これにより、返還後の文字列の長さを計算することができます。次の操作で逆順に、実際の置き換え処理を行います。空白文字があれば次の場所に「%20」という文字列をコピーします。もし空白文字でなければ、そのままコピーします。

Java

1public void replaceSpaces(char[] str, int length) { 2 int spaceCount =0,newLength,i=0; 3 //スペースの数を数える 4 for(i =0;i<length;i++) { 5 if(str[i] ==' ') { 6 spaceCount++; 7 } 8 } 9 //変換後の文字列の長さを算出 10 newLength = length + spaceCount*2; 11 12 str[newLength] = '\0'; 13 14 //逆順で置き換え処理 15 for(i = length - 1;i >= 0;i--) { 16 if(str[i] == ' '){ 17 18 str[newLength - 1] = '0'; 19 str[newLength - 2] = '2'; 20 str[newLength - 3] = '%'; 21 newLength = newLength - 3; 22 } else { 23 str[newLength - 1] = str[i]; 24 newLength = newLength -1; 25 } 26 }

「文字列の後ろにはあたらに文字を追加するためのスペースが十分にある(バッファのサイズは気にしなくても良い)こと」
これの意味は
"a b " -> "a%20b"
と変換されるときに、元々の文字列よりも返還後の文字列が必ず大きくなるから、本来ならそのことを考慮しないといけないけれど、今回は考えなくていいですよ。
ということだと思うのですが、他の言語(C言語等)で実装する場合はこのようなことを考慮しないといけないのでしょうか?
また、バッファという言葉の意味がつかめていません。
返還後の文字列の容量のことなのでしょうか?
そして、これも他の言語だと気にする必要があるのでしょうか?

以上が文意についての質問でした。

続いて、コードについてです。
このコードの戻り値をvoidにして、staticをつけて、以下のように呼び出してみました。

Java

1public static void main(String[] args) { 2 String initialString = "a b c"; 3 char[] chars = initialString.toCharArray(); 4 String after = replaceSpaces(chars,5); 5 System.out.println(after); 6 }

結果は予想どおりArrayIndexOutOfBoundsExceptionが出ました。
最初に渡す配列サイズよりも大きいインデックスにアクセスしようとしているためです。
この本は「いかに良いコードを書くか」という点にもフォーカスしているのですが、このコードってエクセレントなのでしょうか。
私が理解できないだけなのかと思い質問いたしました。

質問が多く、申し訳ないですが、お答え頂ければ嬉しいです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

むちゃくちゃな出題です。
お察しの通り

他の言語(C言語等)で実装する場合はこのようなことを考慮しないといけないのでしょうか?

これはC言語向けの問題を何も考えずにJavaに移植したものです。

元々の文字列よりも返還後の文字列が必ず大きくなるから、本来ならそのことを考慮しないといけない

というのがその通りで、C言語ではそういう考慮が常に求められるのです。

ただし、この問題はC言語の問題としても粗悪です。

文字を追加するためのスペースが十分にある(バッファのサイズは気にしなくても良い)

「十分」って一体何文字のことですか。その「十分」に一文字でもスペースが足りないと何が起こるのですか。
、ということをデジタルに考えるのがプログラミングであり、「十分に」でお茶を濁してしまうのでは出題の意味がありません。
単に意味がないだけでなく、この「十分に」のせいでこれまで大量の脆弱性がさまざまなソフトに埋め込まれてきました。有害なのです。

というわけで、この問題には悩むだけ人生の時間の無駄だと言い切らせていただきます。忘れましょう。

投稿2016/08/22 14:09

yuba

総合スコア5568

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

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

退会済みユーザー

退会済みユーザー

2016/08/22 14:12

いやー、参りましたね。 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問