ログ日記

作業ログと日記とメモ

文字列を入れ替える関数

twitterで見かけたので真面目に考えてみる。

引数で渡された2つの文字列(s1,s2)の中身を入れ替える関数を作りなさい。

http://d.hatena.ne.jp/tek_koc/20080518/1211095764

意図はなんだろう。
単純に数値を入れ替える関数の文字列版でいいのかな。

#define MAX 15
void strchange(char s1[], char s2[])
{
    char tmp[MAX];

    strncpy(tmp, s1,  MAX);
    strncpy(s1,  s2,  MAX);
    strncpy(s2,  tmp, MAX);
}

tmpを使って処理しなさいということならこれで良さそう。分解すると

#define MAX 15
void strchange(char s1[], char s2[])
{
    char tmp[MAX];
    int i;

    for (i = 0; i<MAX; i++){
        tmp[i] = s1[i];
    }
    for (i = 0; i<MAX; i++){
        s1[i] = s2[i];
    }
    for (i = 0; i<MAX; i++){
        s2[i] = tmp[i];
    }

}

こんな感じなのかな。
\0 があるかないかに関わらず動くので安全。
でもMAXが微妙だ。それを直すついでにfor文もまとめると

void strchange(char s1[], char s2[], int size)
{
    char tmp;
    int i;

    for (i = 0; i<size; i++){
        tmp = s1[i];
        s1[i] = s2[i];
        s2[i] = tmp;
    }
}


こうなる。
サイズを受け取る引数は無しなんだろうか。それは困る。
意外にむずい。


というかこれはポインタを使うという問題?コメントでもポインタ使ってるしなぁ。
ポインタを使えという意図なら機械的に置換で。

void strchange(char *s1, char *s2)
{
    char tmp;
    int count = 0;

    while(count != 3){
        tmp = *s1;
        *s1 = *s2;
        *s2 = tmp;

        if (*s1 == '\0')
            count |= 1;
        if (*s2 == '\0')
            count |= 2;
        s1++;
        s2++;
    }
}

(追記) コメントより。汎用的な関数と考えた場合に、長さが違うと短い方の変数の範囲を超えて入れ替えるのでこれは駄目ですね。ヘンテコなビット演算を使ってるし採点もしにくいので、解答には不向きだ。


長さが決まっていない場合はフラグ使わないとループ抜けれない気がしてきた。段々斜め上の方向に行ってしまう。
巡り巡って、素直に元日記の解答でいいのかもわからん。


ポインタの問題じゃなければ *(s1+i) より s1[i] と書いてくれる方が採点も楽なんだけれど。

 *(temp+i)=*(s1+i);

こことか、配列として宣言した変数にiを足してるところもちょっと気になる。