アカウント名:
パスワード:
でも説明できないヤツでも、「C言語が難しいので出来ない」と思いこんでるんだな。
かなりスマートにできたと思います。
# ジョークなので突っ込み禁止。 # 後、sed は GNU のじゃないとダメかも。
#include <stdio.h> int main(){ FILE *fp = popen("sed 's/[[:space:]]\\{1,\\}/\\n/g' " "| awk '" " /[0-9]/ { s += $1; ss += $1 * $1; n++ }" " END {" " print s / n;" " print ss / n - (s / n) ^ 2" " }'", "r"); int c; while ((c = fgetc(fp)) != EOF) putchar(c); return pclose(fp);}
閑話休題。
元の問題は「改行区切りで EOF まで」の方が初心者に優しいんじゃないですかね。 #1286978 [srad.jp] でやっているように自力で parse するのなら、strpbrk と strspn を使えば多少楽になるかもしれません。 C++ だと stream I/O があるのでかなり楽にできそうですし、Java も同様ですね。
真面目な回答は以下のような感じでしょうか:
#include <stdio.h> int main(){ int n = 0; double s = 0, ss = 0; while (!feof(stdin)) { double x; if (scanf("%lf", &x) == 1) { n++; s += x; ss += x * x; } scanf("%*[^-+0-9Ee.]"); } printf("%f\n%f\n", s / n, ss / n - (s / n) * (s / n)); return 0;}
但し、scanf が解釈できなかった文字を確実に stdin の中に残してくれるものと仮定しています (大抵の実装は大丈夫だと思う)。 ISO/IEC 9899 が何と言っていたかは憶えていません。 よろしければ、JISC [jisc.go.jp] で JIS X3010 を読んで確かめてみてください。
If any of those characters differ from the ones composing the directive, the directive fails and the differing and subsequent characters remain unread.
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
あと、僕は馬鹿なことをするのは嫌いですよ (わざとやるとき以外は)。-- Larry Wall
プログラミングの普遍化 (スコア:0)
自力で開発してしまうようになるんでないの。
業務知識を深く反映した強力なロジックを実装して使いながら日々改良していくなんてことができそう。
Javaの最新版いじってみたら、あっけなくいろんな事ができるんでびっくりしたよ。
Re: (スコア:0)
Re: (スコア:3, すばらしい洞察)
たとえば、「EOFがくるまでホワイトスペース区切りで数値を読み込み、平均と分散を計算して出力しろ、というC(でもJAVAでもいいけれど)の課題がわかりません」って学生が居るとする。 そいつに、『じゃ、紙と鉛筆と電卓で、平均と分散を計算する方法を説明してみろ』というと・・・
説明できるヤツ→C言語の技能が足りない
説明できないヤツ→プログラミング以前の問題
でも説明できないヤツでも、「C言語が難しいので出来ない」と思いこんでるんだな。
Re: (スコア:1)
> EOFがくるまでホワイトスペース区切りで数値を読み込み、
と
> 平均と分散を計算して出力しろ、
を分けて教えてやらないといけない。
どっちかいうと、前者の方が難しかったりする。
「数値を入力してください」というプロンプトを出すようなスタイルだと、なんとかできる学生もいる。
ま、プロンプトを出すところまで書いて立ち往生してる学生が、圧倒的に多いがな。
Re:EOFがくるまでホワイトスペース区切りで数値を読み込み (スコア:1)
「ホワイトスペース区切りで数値を読み込み」のところを、オレなりに実装したらこうなった。12xx5 -> 125 になっちゃうし、30桁以上の数字を入れられたらアウトなのだが、誰かもっとスマート方法があったら教えて。但し、C言語。元ネタが Java OK なのは承知。
#よそでやれって?
---------------------------------------------------------------
#include <stdio.h>
#include <string.h>
char *whitespace = " \t\n";
char *numericdot = "0123456789.";
#define BUFLEN 30
int getfloat(FILE *fp, float *x) {
char buf[BUFLEN+1], *bp;
int c;
bp = buf; *bp = '\0';
while (1) {
c = fgetc(fp);
if (c == EOF) return EOF;
if (strchr(whitespace, c)) {
if (bp == buf) continue;
sscanf(buf, "%f", x);
return 0;
}
if (strchr(numericdot, c)) {
*bp++ = c;
}
}
}
int main() {
int n=0;
float x, sum=0., sqsum=0., mean, variance;
while (getfloat(stdin, &x) != EOF) {
sum += x;
sqsum += x*x;
n++;
}
mean = sum/n;
variance = sqsum/n - mean*mean;
printf("sample = %d, mean = %f, variance = %f\n", n, mean, variance);
}
Re:EOFがくるまでホワイトスペース区切りで数値を読み込み (スコア:1)
かなりスマートにできたと思います。
# ジョークなので突っ込み禁止。
# 後、sed は GNU のじゃないとダメかも。
閑話休題。
元の問題は「改行区切りで EOF まで」の方が初心者に優しいんじゃないですかね。 #1286978 [srad.jp] でやっているように自力で parse するのなら、strpbrk と strspn を使えば多少楽になるかもしれません。 C++ だと stream I/O があるのでかなり楽にできそうですし、Java も同様ですね。
真面目な回答は以下のような感じでしょうか:
但し、scanf が解釈できなかった文字を確実に stdin の中に残してくれるものと仮定しています (大抵の実装は大丈夫だと思う)。 ISO/IEC 9899 が何と言っていたかは憶えていません。 よろしければ、JISC [jisc.go.jp] で JIS X3010 を読んで確かめてみてください。
Re:EOFがくるまでホワイトスペース区切りで数値を読み込み (スコア:1)
そうか、やはり通常はお手軽言語に逃げている身では、そのあたりまで理解してなかった。なんだかんだ言って、再発明しようとしてたな。厳しく反省。
というわけで、みんなしっかりCを勉強するんだぞ。(なんか議論のレベルが違う気が、、、)
Re: (スコア:0)
7.19.6.2 The fscanf function 6: