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

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

新規登録して質問してみよう
ただいま回答率
85.49%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Q&A

8回答

1108閲覧

エレガントにコードを書くには?

hjrmrs

総合スコア3

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

1グッド

1クリップ

投稿2021/09/12 06:49

漠然とした質問ですみません。私は、独学でだいぶ前から独学でプログラミングしてる者なんですが...
どんなときにif-else文ではなくswitch-case文を使うか、とかclassで管理すべきか否かを間違えまくって全然きれいにコード書けんし、
アルゴリズムも効率悪くて本来めっちゃ速く処理できるところに時間かかってしまったり、(atcoderでタイムアウト!でもフローチャートとか描いても思いつかない) ...
慣れかと思って続けてたら、visual studio更新したりして... いつの間にか5年目(笑)
全く模範的なコードが書けません。回答者の皆さんは、どのようにして模範的なコードが書けるようになりましたか?

KouRo👍を押しています

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

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

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

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

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

Zuishin

2021/09/12 06:57

5 年目でその状態なら聞いても無理じゃないですか?
mather

2021/09/12 07:26

企業に入ったりスクールで学んだりせず独学をしている理由はなぜですか? なぜプログラミングを学びたいと思いましたか?(採用活動のため、趣味、など) 普段はどうやって勉強していますか? 他の人のコードを分析していますか?
meg_

2021/09/12 07:40

> とかclassで管理すべきか否かを間違えまくって > アルゴリズムも効率悪くて本来めっちゃ速く処理できるところに時間かかってしまったり 間違いに気づいたときに改善して行けば良いと思うのですが、それでは駄目なのでしょうか?
K_3578

2021/09/13 00:15

結局なんのためにプログラミングしてるかによると思いますけど。 速度重視で以降保守とかしない単発の案件なら管理しやすさより素早さ重視で書きますし、 その逆もありますし。 特に競プロと業務なんて同じプログラミングでも目的が違いますから全く別の事と考えるべきだと思いますけど
kaina

2021/09/13 00:24

あなたは何のためにプログラミングをしてるんですか? まさかatcoderでタイムアウトしないプログラムを作る為ではありませんよね? 実際の仕事では効率が良く速く処理できるプログラムは必ずしも必要ではありません。 もっと実用に則したことを学ぶようにしたほうが良いかと思います。
guest

回答8

0

どういう回答を期待しているのかわからないけど、あなたの中で「模範的なコード」とはどういうものなのか、定義がちゃんとできているなら、その定義に従ってコードを書くだけ。

「思いつかない」のは単純な知識不足。
「無」からは何も創造できないので、知識のインプットをするしかない。

Amazon等で探せばその手の本はいくらでも見つかるし、GitHub等で他人様のコードはいくらでも読めるので、それらを読んで学べば良いだけなので、まぁ早い話「勉強して経験を積め」という当たり前の結論にしかならないと思う。

投稿2021/09/12 07:01

gentaro

総合スコア8949

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

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

0

if-else文ではなくswitch-case文を使うか、とかclassで管理すべきか否か

複数のパターンが思いつくのであれば,なんなら実際に全パターンで書いてみれば良いのではないでしょうか.

で,それらを比較するなりして,あなたなりの評価を下す.
あなたがより{エレガント,模範的,etc}と思うのはどれなのか?
その理由は…?

そういう,反省というか反芻というか,の経験をたくさん積んだ結果として,
「実際に全パターンの実装をせずとも頭の中で比較して最初から良さそうな形を選択する」ようなことができるようになるんじゃないでしょうか.

投稿2021/09/13 07:22

fana

総合スコア11647

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

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

0

回答者の皆さんは、どのようにして模範的なコードが書けるようになりましたか?

模範的なコードを書いてるつもりは一切ないです。
業務に必要で、要件を満たすコードをきちんと書いてレビューでOK頂いているだけです。

答えがない中で、自分で答えやルール、答えまでのルートを作っていくものなので、
「模範」というのは方向性が違います。

「要件通りに動くこと」が最低条件。
何を良しとするかは現場やプロジェクトによるでしょう。
正解はありません。要件通りに動いてなければ不正解。
あとはプロジェクトのレビュー観点を満たすかどうか。

学習時期なら、他人のコードを読んでみるのは勉強にはなりますが、
それはあくまで「こういう書き方もあるのか」という見識を広める意味合いと、
自身の理解度を確かめる意味合いになると思います。

やはり自分で考えて書くこと。
非効率ならどうやったら効率的になるのか、何を以て「効率的」とみなすのか、
テーマや意識、意図をもって書くことです。

私も若手社員に出した課題に対して自分で解答例を準備することはありますが、
あくまで「参考コード」としてです。「お手本」とは口では言いますが、
「模範にしてくれ」ではなく「読んで参考にしてくれ」としか思っていません。
それが全てではないし、あくまで多くあるルートの1つでしかないからです。

業務観点になると「納品物として認められる品質かどうか」になってくるので、
「模範かどうか」は全く別の話です。

結局、あなた自身がどうなりたいかでは?

投稿2021/09/12 08:26

m.ts10806

総合スコア80842

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

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

0

質問に質問で返して申し訳ないんですけど、

「模範的なコード」ってなんですか? なにをもって模範的とするのでしょうか?

投稿2021/09/12 07:04

episteme

総合スコア16614

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

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

0

5年前に書いたコード、4年前に書いたコード、3年前に書いたコード、2年前に書いたコード、1年前に書いたコードを読んでみましょう。

何が書かれているかがわからないのなら、それは悪いコードです。
次に書くときには、5年後に読んでもすぐにわかるように書きましょう。

何が書かれているかはわかり悪いコードだと思うけれども、どこが良くないのかがわからないなら、なぜそれが悪いコードだと思うのでしょう。どこが良くないかわかるまで考えましょう。

どこが良くないのかがわかるけれども、どうすれば良くなるのかがわからないなら、アルゴリズムの本やコーディングスタイルの本や、使っているプログラミング言語の文法、ライブラリの本を読んで勉強しましょう。

これらすべてを1年間やって少しでも良いので以前よりも良いコードが書けようになったなら、あなたは進歩しています。最善のコードなどというものはないので、前よりも良いコードが書けるようにならばそれで良いのです。

これらすべてを1年間やっても以前よりも良いコードが書けるようにならないなら、プログラミングの適性がないのでしょう。そういう方もいらっしゃいます。そういう場合場合は趣味で続けるのも良し、プログラミング以外に目標を変えるのも良しです。

投稿2021/09/13 12:44

ppaul

総合スコア24666

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

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

0

先輩独学プログラマーとして、プログラミングを完全に理解したので回答します。

エレガントにコードを書くために必要なのは、ずばり「適切な命名」です。
命名さえ適切できれば、アルゴリズムも if/switch の選択も、優雅に実装することが可能です。
あとは缶コーヒーじゃなくて、ガラス製のティーサーバーをつかって紅茶を飲むようにすると完璧です。

余談ですが、エレガントなコードが書きたいのであれば、競技プログラミングは卒業した方が良いですよ。
プログラマーじゃなくて、ゴルファーの適性が上がってしまいます。

投稿2021/09/12 09:35

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

pepperleaf

2021/09/12 09:57

あと、真っ白なティーカップ。そして、ティーパックじゃなくて、大きめの葉っぱが、より良いかと。
Zuishin

2021/09/12 10:06

ガラスのティーサーバーにティーバッグ……
退会済みユーザー

退会済みユーザー

2021/09/12 10:21

ブランデーさえ入れなければ大丈夫です。 ブランデー入れるとエレガントの対極に位置してしまいます。
Daregada

2021/09/14 10:11

「健康と美容のために、食後に一杯の紅茶」
退会済みユーザー

退会済みユーザー

2021/09/14 10:55

それだと停止してしまいます。。。
pepperleaf

2021/09/14 11:36

色々と注文が多そう。 エレガントの定義も難しい。
退会済みユーザー

退会済みユーザー

2021/09/16 01:58

そうでもないです。 動かすときには「ロシアン・ティーを一杯。ジャムではなくママレードでもなく蜂蜜で」。
Zuishin

2021/09/16 02:47

ファイエル(炎上)
Daregada

2021/09/16 02:57

「指を2回鳴らしたときにはウィスキーが欲しいのに、なぜかコーヒーが2杯出てきます」
guest

0

そもそも何のためにプログラミングを勉強してるんですか?何か目的を達成するためにコードを書くんじゃないですか?模範的なコードより、汚くても読みにくくても目的を達成するためのコードを書けばいいんじゃないですか?独学なら、別に仕事でやってる訳じゃないんですよね?

色々作ってる過程で他人のソースとか見ていいなと思う所があったら、パクったり(ライセンスは要確認)、作り方を真似してみればいいんです。そうやって新しい知識を取り入れていって過去の自分のソースみて設計がまずいと思ったら、スキルレベルに合わせて作り直したりするとかしてみれば、自然にブラッシュアップされていくと思います。
何も作らず足踏み行進してるだけなら、一生そのままです。

投稿2021/09/12 11:09

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

(atcoderでタイムアウト!

その場合は、「計算量」を意識するといいかもしれません。

後は、たとえばいわゆる蟻本と呼ばれる書籍を参考にするとかですね。

(すでにお持ちで、参考にしていらっしゃるならスルーで)

AtCoderはあまりやっていませんが、A問題やB問題はそのまま解けばいいタイプが多いですが、
B問題のいくつかやC問題からは計算量を意識しないとできないような問題が多い気がします。

たとえば、解こうと思えば貪欲法とかでもイケなくはないですが、TLEになったりとか。

その場合は、メモ化とかを使って出来る限り計算量を落とせないかを考えるといいみたいです。
(ただし私はまだ……)

全く模範的なコードが書けません。

それは問題ない気がします。プログラミングって、結局、「仕様に沿っていて、ユーザが満足すればいい」のです。(極論ですが)
そりゃ、綺麗なコードを書くように心がけるべきですが。
ただ、一つの処理でも、極論をすればいくらでも実装はあるのです。
たとえば、Hello World。普通はC言語だとprintf関数に相当するものに渡すだけですが、

考えると、

■ "Hello World"を文字列として変数等(C言語だと配列) にセットしてそれを渡す
■ "Hello" と " " と "World" をそれぞれ変数等に入れてそれを渡す
■ "Hello " と "World" をそれぞれ入れて...
■ "Hello World"を変数等に入れて一文字ずつ表示する
...

とかみたいにやろうと思えばできますよね。(ただ、普通はそんなまどろっこしいことはせずに一回でやる)

なので、「模範解答」になる必要はありません。

仕様に沿っていないと話になりませんし、実行結果が異様に遅い場合も話になりませんが、
基本的にはそれらを守っていればOKだと思います。

つか、WindowsとかのようなOSとかですら、毎年のようにアップデートやら修正やらをしています。
ましてや、たった一回で、スペルミスもせずにやるのは無理です。

どんなときにif-else文ではなくswitch-case文を使うか、とかclassで管理すべきか否かを間違えまくって全然きれいにコード書けんし

経験じゃないでしょうか。
後は知識。

質問者さんはどのように学習しているのでしょうか。
たとえば、「単にAtCoderの問題を解くだけ」なのか、「本を読むだけ」なのか、
「実際に何か作品を作る」なのかとか。

オススメは『何か作る』です。
作る事で、「いつ使うべきか」「作法」等を学べます。

if文は「条件で分岐させる場合」ですが、switch...caseは言語によっては『複雑な条件式は不可能』だったりします。(現にC言語やC++だと複雑な条件式は不可能)

たとえば

C

1int a = 100; 2int b = 2; 3switch( a ){ 4 case 100 && b == 2: 5 // 何らかの処理 6 break; 7 case 200 && b == 3: 8 // 何らかの処理 9 break; 10 case 300 && b == a+1: 11 // 何らかの処理 12 break; 13}

のような複雑な条件式はできません
( a が 100 で b が 2 である場合... とかのような )

この場合はif文でしかできません。

classで管理すべきか否か

競技プログラミングとかでは考えませんね。(そんな余裕ない…)
時間があればいじるかもしれませんが。

やるとしたら、経験的に。ですかね。

「これをオブジェクトにしたら楽そう……」と思ったらOOPで、そうじゃないなら非OOPで。

後のお勧めは、「以前作ったものを改良する」「自分用のライブラリを作る」でしょうか。

たとえば、C言語 + Windows API だと、MessageBoxは文字列しか受け取りません。(表示部)
でもint型を埋め込みたい事がありますね。

これを

C++

1int MsgBox( const std::string &s ){ 2 return MessageBox( nullptr, s.c_str(), "", MB_OK ); 3}

のように関数とかにしておけば若干楽になるっていう感じで。

それと昔作ったものでも今振り返ると「うわぁ……ダセぇ……」ってなります。
なのでそれを修正するとかですね。

つまり、「単に、単発で作るのではなく、保守ありきで組んでいく」という感じでしょうか。
それなら、必要に駆られれば自分でも調べますから。

投稿2021/09/12 09:11

BeatStar

総合スコア4958

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問