ふらっとC#,C♯,C#(初心者用) Part59

このエントリーをはてなブックマークに追加
952デフォルトの名無しさん:2010/05/25(火) 09:52:40
昨日のコマ大の問題

各桁の数字が相異なり、どれも0でないような3桁の正の整数nがある。
nの各数字を並べて出来る6つの数の最大公約数をgとする。
gとして考えられる最大の値を求めよ。
953デフォルトの名無しさん:2010/05/25(火) 10:38:06
18
954デフォルトの名無しさん:2010/05/25(火) 10:38:17
("○")
(^○^)
(-○-)
955デフォルトの名無しさん:2010/05/25(火) 10:59:29
C#初心者です。
マウスの右クリック(コンテキストメニュー)と右ドラッグ(ダウン-移動-アップ)で、
異なる処理を割り当てるにはどうしたらよいですか?
956デフォルトの名無しさん:2010/05/25(火) 11:14:34
どのレベルで処理するのかわからんけど、
ダウン後移動があったらドラッグ扱いでいいんじゃないかな
957デフォルトの名無しさん:2010/05/25(火) 11:35:37
C#つうかPG初心者と言ったところか・・・

1.マウスダウンでフラグセット・マウス位置記憶

2.マウス移動で移動量を記憶

3.アップで
 A.移動量が既定の移動量に達していない場合はコンテキストメニューを表示
 B.移動量が既定の移動量に達している場合、右ドラッグの処理

みたいなんじゃいかんのかな?

コントロールの移動とかからむとめんどくさそうだけど
958デフォルトの名無しさん:2010/05/25(火) 11:57:55
>>956、957
右クリックすると、コンテキストメニューが開いちゃうのですが、それをどうキャンセルすればいいんでしょう?
まずは、
private void img_MouseRightButtonDown(object sender, MouseButtonEventArgs e){
MessageBox.Show("mousedown");
}

private void img_MouseRightButtonUp(object sender, MouseButtonEventArgs e){
MessageBox.Show("mouseup");
}
としてみたんですけど、MessageBoxが開かず、コンテキストメニューが開いてます。
959デフォルトの名無しさん:2010/05/25(火) 12:03:53
コンテキストメニューを割り当てないようにしたらいいんじゃないかな・・・・
960デフォルトの名無しさん:2010/05/25(火) 12:11:41
ContextMenuStripプロパティにセットするのをやめて
イベント時にShowするとかかな
961デフォルトの名無しさん:2010/05/25(火) 12:22:25
>>935
配列に対してfor文でカウンタを回しながら要素アクセスを行うと、
添字の範囲チェックが行われる。
これはtry〜catchの例外処理が挟まれることに相当するので、単独でこの部分だけを見ると差は大きい。

処理時間の差が大きくなるかどうかはループあたりの処理量とループ回数の比によって異なる。
ベンチマーク的な空ループに近い処理や、巨大なbyte[]に対する処理などではバカにならないぞ。

>>949,950
ちげーよ。Stopwatchは計測にパフォーマンスカウンタを使用する。

パフォーマンスカウンタは一般的に精度がシステムごとに固定値(例えば100万分の1秒)になっているか
CPUのクロック数に依存するかなので、
それ未満の経過時間の場合はそんなふうに固定時間ずれているように見える。
実際はそうじゃないかもしれないんだぞ。
.NETの場合はどういう実装になっているのかは誰か調べといてください。
962デフォルトの名無しさん:2010/05/25(火) 12:24:19
>>958
ContextMenuプロパティを設定するのをやめて、MouseDown/MouseUpを独自に実装するのはどうだ?
963デフォルトの名無しさん:2010/05/25(火) 12:28:26
>>960
bool mousemove = false;
private void img_MouseRightButtonDown(object sender, MouseButtonEventArgs e){
mousemove = true;
//マウス位置取得
MessageBox.Show("mousedown" + mousemove);
}

private void img_MouseRightButtonUp(object sender, MouseButtonEventArgs e){
//マウス位置取得
//マウス位置計算
if (移動量 > たとえば20ピクセル) MessageBox.Show("mouseup");
else ContextMenu.Show();
}
とかですか?
コンテキストメニューって、どこでプロパティにセットしているんでしょう?
964デフォルトの名無しさん:2010/05/25(火) 12:32:16
>>963
マウスの位置はMouseButtonEventArgsに入ってるべ?
ContextMenuStripはそのコントロールのプロパティの動作あたりに無いか?
965デフォルトの名無しさん:2010/05/25(火) 12:38:31
>>961
QueryPerformanceCounterの替りに実装できるて書いてるくらいだから
内部でそれつかってんじゃね?
966デフォルトの名無しさん:2010/05/25(火) 13:21:32
>>964
bool mousemove = false;
int startX;
int startY;
private void img_MouseRightButtonDown(object sender, MouseButtonEventArgs e){
mousemove = true;
//マウス位置取得
startX = e.X;
startY = e.Y;
MessageBox.Show("mousedown" + mousemove);
}

private void img_MouseRightButtonUp(object sender, MouseButtonEventArgs e){
//マウス位置取得。マウス位置計算
//if (移動量 > たとえば20ピクセル)
if ((e.X - startX) * (e.Y - startY) > 20 || (e.X - startX) * (e.Y - startY) < -20 MessageBox.Show("mouseup");
else ContextMenu.Show();
}
こんな感じでしょうか。
967947:2010/05/25(火) 13:24:42
面倒なことやってるねw

なんで左を使わないの?
968デフォルトの名無しさん:2010/05/25(火) 13:28:05
好きにやってみて思った通り動かないところを聞いてくれ
マウスアップがコントロールから外れると来なくなるから
Captureプロパティも使った方がいいかも

メニュー表示はこんな感じかな
ContextMenu.Show(img.PointToScreen(e.Location));
969デフォルトの名無しさん:2010/05/25(火) 13:30:44
>>964,968
コンテキストメニューのイベントハンドラが見つからないんですけど、
<Grid Name="img" MouseRightButtonDown="img_MouseRightButtonDown" MouseRightButtonUp="img_MouseRightButtonUp">
<Grid.ContextMenu>
<ContextMenu Name="contextMenu">
<MenuItem Header="コピー" Name="copy" Click="copy_Click" />
</ContextMenu>
</Grid.ContextMenu>
</Grid>
の場合、どうキャンセルすればいいんでしょう?
単に<Grid.ContextMenu>から</Grid.ContextMenu>までをコメントアウトしちゃうと、.csのコンテキストメニュー関係が全滅しちゃうのですが…。

>>967
左は描画に使う予定です。
http://homepage3.nifty.com/midori_no_bike/CS/graphics.html
を参考にしてます。
970947:2010/05/25(火) 13:32:27
>>969
なるほど〜なんだけどさw
WinFormじゃなくてWPFなの?
971デフォルトの名無しさん:2010/05/25(火) 14:07:18
確かにMouseButtonEventArgsはWPF用のイベント引数だったなw

<ContextMenu>は<Window.Resources>辺りで宣言
C#のコードからはthis.Resources[]で取得
とかする

あとWPFでそのページはあんま役に立たんと思うぞ
972デフォルトの名無しさん:2010/05/25(火) 14:21:07
>>971
ありがとうございます。
<Window.Resources>
<Window.ContextMenu>
<ContextMenu Name="contextMenu">
<MenuItem Header="コピー" Name="copy" Click="copy_Click" />
</ContextMenu>
</Window.ContextMenu>
</Window.Resources>
<Grid Name="img" MouseRightButtonDown="img_MouseRightButtonDown" MouseRightButtonUp="img_MouseRightButtonUp">
</Grid>
ってことですか?
これだと、「アタッチ可能なプロパティContextMenuが型Windowに見つかりませんでした」とエラーです。

WPFで、よい入門ページってご存じありませんか?
973947:2010/05/25(火) 14:24:24
>WPFで、よい入門ページってご存じありませんか?
ない

<Grid Name="img"

とかやって名前付けておけば従来のwinformのように

img.

ってやれば候補がでてくるので自分でそれっぽいの探してがんばるしかない
974デフォルトの名無しさん:2010/05/25(火) 14:30:25
>>973
Gridには名前つけましたが、Windowにも名前が必要ってことでしょうか?
975947:2010/05/25(火) 14:32:54
>>973
MSDNで調べてもいいけどざっくり見る場合の手段なだけだよw

XAMLの方でも候補は見えるけどやりにくいので
XAML側にはとりあえずNameつけておいてC#側で何が使えるか見るってだけ
976デフォルトの名無しさん:2010/05/25(火) 14:34:35
んー、WPFの基礎もできてない…
<Window.***> はWindowの***プロパティにセットする記述
C#のコードでWindow.*** = ...って書くのと同じ
だから
<Window.Resources>
  <Window.ContextMenu>
はイミフ
WindowのContextMenuにしたいわけじゃないんだからWindow.ContextMenuは関係ない
977デフォルトの名無しさん:2010/05/25(火) 14:40:06
>>969のイベントハンドラはXAMLに書かない方がいいんじゃね?
978デフォルトの名無しさん:2010/05/25(火) 15:12:46
VC#2010で同じことやろうとしたらGridのContextMenuがでねえw
979デフォルトの名無しさん:2010/05/25(火) 16:02:02
yieldを使用した反復子methodで、外部から入力を受け取ることは可能でしょうか?
Pythonにおけるgenerator.send(value) のようなものが欲しいんですが。
980デフォルトの名無しさん:2010/05/25(火) 16:48:06
>>979
IEnumerable<int> f(int i)
{
for (int j = 0; j < 10; j++)
{
yield return i * j;
}
}
こういう話?
981デフォルトの名無しさん:2010/05/25(火) 16:50:25
>>976
基礎がないから初心者ってことで…。

<Window.Resources>
あたりで宣言ってのはどうやるんですか?

>>977
イベントハンドラを、C#側に書くにはどうしたら?
982デフォルトの名無しさん:2010/05/25(火) 17:00:40
>>980
その例に合わせると、こんな感じでしょうか。
// 反復子メソッドの例
IEnumerable<int> f(int i)
{
bool continuation = true;
for (int j = 0; j < 10; j++)
{
continuation = yield return i * j;
if(!continuation)
break;
}
Console.WriteLine("iterater ended!");
}

// ユーザーコード
var g = f(5);
for (int m = 0; m < 3; m++)
{
k.MoveNext();
Console.WriteLine(k.Current);
}
k.send(false);
983デフォルトの名無しさん:2010/05/25(火) 17:04:50
>>961
知らないなら適当なこと言うなよ。
言っとくが、>>943のループの中身は足し算一回だぜ(配列の値を取り出して別の変数に足す)。

中身を足し算すらなしの、別変数への格納だけにしても、
01.325 for
01.046 foreach
00.730 for
00.719 foreach
00.701 for
00.696 foreach
00.697 for
00.709 foreach
こんな感じだ。
どこにバカにならない差があるって?
範囲チェックも、JITコンパイル時点で、オーバーすることはないことが確認できた場合は省かれるんだよ。
最初から、そうなるから差なんてないって話なのに今更何言ってるの?
984デフォルトの名無しさん:2010/05/25(火) 17:11:24
だから最初から状況によってって書いてあるじゃねえか
985デフォルトの名無しさん:2010/05/25(火) 17:12:30
あとパフォーマンスカウンタの話だが、まあ>>949のコード自体はよくなかった、
あの結果だけじゃ確かに何の説明にもならないからな。
※こっちはかかる時間を知ってるから、あれでも確認できるって分かってるだけだから。

で、これなら納得いくかい?
※Stopwatch.GetTimestampの中身はほぼ単なるQueryPerformanceCounterの呼び出しな
long[] t = new long[10];
for (int i = 0; i < t.Length; i++)
{
t[i] = Stopwatch.GetTimestamp();
}
for (int i = 1; i < t.Length; i++)
{
Console.WriteLine(((t[i] - t[i - 1]) * 1000.0 / Stopwatch.Frequency).ToString("0,0.000000000"));
}
結果、
00.000628572
00.000628572
00.000558730
00.000628572
00.000628572
00.000628572
00.000628572
00.000628572
結局QueryPerformanceCounterで600ナノ秒程度かかってるっていう結果には変わりないってこと。
そしてそんなので200ナノ秒程度しかかからない処理の時間を計測すること自体があほだってこと。
986デフォルトの名無しさん:2010/05/25(火) 17:19:05
>>984誰に言ってるのかわからないけど、
>>961はこう言ってる。

>>935
配列に対してfor文でカウンタを回しながら要素アクセスを行うと、
添字の範囲チェックが行われる。
これはtry〜catchの例外処理が挟まれることに相当するので、単独でこの部分だけを見ると差は大きい。

処理時間の差が大きくなるかどうかはループあたりの処理量とループ回数の比によって異なる。
ベンチマーク的な空ループに近い処理や、巨大なbyte[]に対する処理などではバカにならないぞ。
987デフォルトの名無しさん:2010/05/25(火) 17:21:09
>>982
〜〜の◯◯みたいな、だけじゃなくて具体的にどういう動作させたいのか書いてくれよ
その例もよく分からんが、fの第二引数にFunc<int, bool>でも持たせるとかするのはどう?
f()の中でi*jを計算してFunc<int,bool>を呼び出しyield breakする
988デフォルトの名無しさん:2010/05/25(火) 17:30:47
>>987
いただいた例が私のやりたかった処理にあまり似ていなかったためか、
うまく伝わらなかったようです。ごめんなさい。
こんな感じです。

// 反復子メソッドの例
void somework(...)
{
bool continuation = true;
for (int j = 0; j < **; j++)
{
// ターン処理
// ...
continuation = yield return ***;
if(!continuation)
break;
}
// 終了処理
// ...
return
}

// ユーザーコード
var g = somework();
var k = g.GetEnumerator();
while(k.MoveNext())
{
if(中断するかどうか)
k.send(false);
}
989デフォルトの名無しさん:2010/05/25(火) 17:30:54
>>985でもやっぱり納得いかないなら、こうだ。
watch = Stopwatch.StartNew();
long tmp;
for (int i = 0; i < 10000; i++)
{
tmp = Stopwatch.GetTimestamp();
}
watch.Stop();
Console.WriteLine(watch.Elapsed.TotalMilliseconds.ToString("0,0.000000"));
で、結果がこんな感じ。
06.734900
少なくとも平均的には、間違いなく1回の呼び出しで600〜700ナノ秒かかってる。
990デフォルトの名無しさん:2010/05/25(火) 17:36:40
>>988
で、987はどうよ
IEnumerable<int> f(int i, Func<int, bool> pred) {
  for (int k = 0; k < 10; ++k) {
    int x = i * k;
    if (pred(x))
      yield break;
    yield return x;
  }
}

foreach (var x in f(10, n => n > 30)) {
  Debug.WriteLine(x.ToString());
}
991デフォルトの名無しさん:2010/05/25(火) 17:43:14
>>988
http://ideone.com/l1Ypn
こういう感じに、状態を持ちつつyield returnするクラスが作りたいっていう話なんだろうか
992デフォルトの名無しさん:2010/05/25(火) 17:50:02
>>991
すばらしい!
まさにこういう事がしたかったんです。
ありがとうございます。
993デフォルトの名無しさん:2010/05/25(火) 18:09:15
>>981
xaml
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        Loaded="Window_Loaded">
    <Grid Name="img">
        
    </Grid>
</Window>
こんな感じでwindowにLoadedイベントを追加して

cs
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            img.MouseRightButtonDown += new MouseButtonEventHandler(img_MouseRightButtonDown);
        }

        void img_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            throw new NotImplementedException();
        }
こんな感じでイベントハンドラ追加
この方法だとwinformでやってたやり方に近くなる

完成イメージがつかめたらWPFらしい記述に直すとか
994デフォルトの名無しさん:2010/05/25(火) 18:15:39
xaml側でとりあえず名前付けてC#側でなんとかしなよ
って書いたのは理解してなかったのね・・・
995デフォルトの名無しさん:2010/05/25(火) 18:32:50
初心者スレでこんな議論が起きようとはw
996デフォルトの名無しさん:2010/05/25(火) 18:36:45
>>995
よくあるよw
最近は行ってないけどC/C++関連でもよくあった
997デフォルトの名無しさん:2010/05/25(火) 18:39:00
次たててくるわ
998デフォルトの名無しさん:2010/05/25(火) 18:42:59
ふらっとC#,C♯,C#(初心者用) Part60
http://pc12.2ch.net/test/read.cgi/tech/1274780512/
999デフォルトの名無しさん:2010/05/25(火) 18:46:49
>>998
1000デフォルトの名無しさん:2010/05/25(火) 18:54:29
うめ
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。