お知らせ:このサイトは閉鎖します。移転先についてはhttp://projectroom.jphttp://haukun.projectroom.jpを参照ください。
新約聖書 マタイによる福音書朗読TwitterBot @BibleJP_Matt好きなテキストをiPhoneの壁紙に。iPhone用Webアプリ「ポステラ」聖書 創世記朗読TwitterBot @BibleJP_GenCodeOfCelestia -数学的壁紙配信サイト-

Problems 2524. Conversions

公開日:2010/10/02 (Sat)

概要

出展

https://www.spoj.pl/problems/GNY07B/

簡単な解説

入力された値の単位変換を行う。

(主観的な)ジャンル

単純アルゴリズム

(主観的な)難易度 5段階

☆(単純)

所感

「キログラム←→ポンド」と「リットル←→ガロン」の値の変換を行います。(ただし、変換する値は既に問題に与えられているので調べる必要はありません。)
単位として「kg」が来たらその値をポンドに直す、という単純な変換を行うだけの問題です。
壁は、強いて言えば出力する値が小数点以下第4位までという点です。C言語だとprintf()の書式指定で解決してしまうのでほとんど壁にはなりませんが…。

素直に書けば完成させることができます。

最近、プログラムに対して思うことがあったので、今回はきっちり書くことにしました。
初期化子とかconst引数とかsizeof()とか(ようはCにあってVB6にないもの)が不慣れだったので、勉強がてら使ってみることにしました。

考察

値の変換部分をif{キログラムなら~}elseif{ポンドなら~}...とやってもよかったのですが、構造体配列使ったらいい感じになりそうだったので、それを使ってみました。

//  データ変換用構造体
typedef struct
{
    char    strSrcUnit[LENGTH_UNIT_TEXT];
    double  dConvertValue;
    char    strDstUnit[LENGTH_UNIT_TEXT];
} tagConvertset;

//  データ変換用のデータ配列
tagConvertset ARRAY_CONVERTSET[] = {
                                    {NAME_KILOGRAMS, KILOGRAM_TO_POUNDS, NAME_POUND},
                                    {NAME_POUND, POUNDS_TO_KILOGRAM, NAME_KILOGRAMS},
                                    {NAME_LITER, LITER_TO_GALLONS, NAME_GALLON},
                                    {NAME_GALLON, GALLONS_TO_LITER, NAME_LITER}
                                    };
これによりif文をすっきりさせることができました。
for(i = 0; i < sizeof(ARRAY_CONVERTSET) / sizeof(tagConvertset); i++)
{
    if(!strcmp(pDataset->strUnit, ARRAY_CONVERTSET[i].strSrcUnit))
    {
        dOutputValue = pDataset->dValue * ARRAY_CONVERTSET[i].dConvertValue;
        strcpy(strOutputUnit, ARRAY_CONVERTSET[i].strDstUnit);
        break;
    }
}
ちょっと冗長かもしれないけど、説明しやすいうえにelseif{}がずらっと並ばなくなるので見た目がきれいです。

解答例

//////////////////////////////////////////////////
//
//  Sphere Online Judge
//      2524. Conversions
//      Problem code: GNY07B
//
//      Author  : Hau-kun
//      Date    : 2010/10/02
//
//////////////////////////////////////////////////
//  accepted
//      TIME    0.00
//      MEM     1.6M
//      LANG    C
//////////////////////////////////////////////////

#include 
#include 
#define LENGTH_UNIT_TEXT 3

//  単位名
#define NAME_KILOGRAMS      "kg"
#define NAME_POUND          "lb"
#define NAME_LITER          "l"
#define NAME_GALLON         "g"

//  単位変換
#define KILOGRAM_TO_POUNDS 2.2046
#define POUNDS_TO_KILOGRAM 0.4536
#define LITER_TO_GALLONS   0.2642
#define GALLONS_TO_LITER   3.7854

//  データセット構造体
typedef struct
{
    double dValue;
    char   strUnit[LENGTH_UNIT_TEXT];
} tagDataset;

//  データ変換用構造体
typedef struct
{
    char    strSrcUnit[LENGTH_UNIT_TEXT];
    double  dConvertValue;
    char    strDstUnit[LENGTH_UNIT_TEXT];
} tagConvertset;

//  データ変換用のデータ配列
tagConvertset ARRAY_CONVERTSET[] = {
                                    {NAME_KILOGRAMS, KILOGRAM_TO_POUNDS, NAME_POUND},
                                    {NAME_POUND, POUNDS_TO_KILOGRAM, NAME_KILOGRAMS},
                                    {NAME_LITER, LITER_TO_GALLONS, NAME_GALLON},
                                    {NAME_GALLON, GALLONS_TO_LITER, NAME_LITER}
                                    };

//  プロトタイプ宣言
void InputDataset(tagDataset* pDataset);
void OutputDataset(const int nDatasetNumber, const tagDataset* pDataset);


//////////////////////////////////////////////////
//  メイン関数
//////////////////////////////////////////////////
int main(void)
{
    int i = 0;
    int nLoopMax = 0;
    
    //  問題数読み取り
    scanf("%d", &nLoopMax);

    //  問題数分、処理を繰り返す
    for(i = 1; i <= nLoopMax; i++)
    {
        tagDataset dataset;

        InputDataset(&dataset);

        OutputDataset(i, &dataset);
    }

    return 0;
}

//////////////////////////////////////////////////
//  データ取得関数
//////////////////////////////////////////////////
void InputDataset(tagDataset* pDataset)
{
    //  値の取得
    scanf("%lf", &pDataset->dValue);

    //  単位の取得
    scanf("%s", pDataset->strUnit);
}

//////////////////////////////////////////////////
//  データ出力関数
//////////////////////////////////////////////////
void OutputDataset(const int nDatasetNumber, const tagDataset* pDataset)
{
    int i = 0;
    int nOutputDatasetNumber = 0;
    double dOutputValue = 0;
    char strOutputUnit[LENGTH_UNIT_TEXT];
    
    nOutputDatasetNumber = nDatasetNumber;

    //  データ変換用データ配列を利用して値を変換する。
    for(i = 0; i < sizeof(ARRAY_CONVERTSET) / sizeof(tagConvertset); i++)
    {
        if(!strcmp(pDataset->strUnit, ARRAY_CONVERTSET[i].strSrcUnit))
        {
            dOutputValue = pDataset->dValue * ARRAY_CONVERTSET[i].dConvertValue;
            strcpy(strOutputUnit, ARRAY_CONVERTSET[i].strDstUnit);
            break;
        }
    }

    printf("%d %.4f %s\n", nOutputDatasetNumber, dOutputValue, strOutputUnit);
}

このコンテンツへのコメント

コメント無し

コメントフォーム
名前
(Max15文字)
削除パスワード
(Max15文字)
コメント
(Max1500文字)
コメントを投稿する※投稿する場合はこちらをチェック。
コメントを削除する※名前欄にIDを、削除パスワードに投稿時のパスワードを入れることで削除できます。

2013年もよろしくお願いいたします!

合計 228095
12/12 20
12/11 99
12/10 80
12/09 93
12/08 78
12/07 93
12/06 98
1,722,375
478 時間
19
5.4616
[とても昔]
アプリ内は良さそうだけど、ホーム画面はのっぺりしちゃうなぁ…。
[とても昔]
次のOSXそう来たかw
[とても昔]
SurfaceProゲットなう。思ったよりタッチ画面が使いやすかった。キーボードの縦幅短いから、画面と近いからかな。 これで、Win8/iOS/Androidアプリどれでも作れる! http://t.co/7CXQCVVao5
[とても昔]
じわじわくるw >RT
[とても昔]
スタジオレンタルして、15年ぶりにピアノを弾くなう。あとステージアも初体験できて良かった。近場で便利。フロッピーじゃなく、USBでレジストいけるのね。楽譜もネットで購入→印刷できるので、買いに行く必要すらなくなった。すごい時代。 http://t.co/9gRBztS2UB
@Hau_kun

Twitterでマタイによる福音書を読んでみませんか @BibleJP_Mattで朗読中 Twitterで創世記を読んでみませんか @BibleJP_Genで朗読中 好きなテキストをiPhoneの壁紙に。iPhone用Webアプリ「ポステラ」

区切り線
はぅ君プロジェクトについて

管理人はぅ君の運営する個人ポータルサイトです。
技術・思想・ソフトウェア・その他もろもろをコンテンツとして公開していきます。
ご意見・ご感想・要望は、各コンテンツのコメントか、お問い合わせよりどうぞ。

Rss 1.0 RSS1.0のフィード