忙しい現代人の腰&肩のお悩み対策!

例えば、1,2,3というのは3つの数字であり、順列の数は3!=6となり、
123
132
213
231
312
321
となります(重複なしのシャッフルだけということです)。数字を全部使うと、0123456789の10個であり個数は10!です。(自然数という意味だったら先頭が0だとダメとかありますがそれは考えないとして)。またアルファベット26文字を並び替えると26!通りになります。それを全部表示するアルゴリズムはどのようなものがあるでしょうか。ちょっと考えてみましたが、思いつきません。
pythonだと1000!とか10000!の数を表示してくれます。しかし例えば11だと0~10までの数字を並び変えるので二けただと変則的かなと思いますが。とにかく、N!個の順列を全部表示してくれるアルゴリズムはどうなるでしょうか。

できれば言語の仕様に特化したものでない方がいいのですが。あるいはそのような機能がライブラリに含まれているような言語でない方がいいです。

よろしくお願いします。

A 回答 (11件中1~10件)

正方行列のデターミネントを定義通りに計算する時に用いる関数で、n個の数値をすべての順列をある順番に並べた場合、k番目(k <= n!)の順列を返すものがありましたが、今、行方不明です。

この関数は、順列の符号(偶置換?奇置換?)も返してくれるので、デターミネントを計算する時に浮動小数点を使う必要がなくなるので便利ですので、探しておきます。これを読めば、知っている人がいると思うので、期待できるでしょう。
内部のロジックとしては、何種類かあるみたいで、高速のものが見つかれば幸いです。
    • good
    • 0

やっぱり再帰が楽ですね。

今度は切り張りで作るバージョン
「順列の内容をすべて表示するプログラムにつ」の回答画像10
    • good
    • 0

たとえば C++ では「次の順列を求める」関数 std::next_permutation があるので, これの実装を流用すれば


再帰を使わないで全ての順列を列挙する
ことは可能です.
    • good
    • 0

> できれば言語の仕様に特化したものでない方がいいのですが。

あるいはそのような機能がライブラリに含まれているような言語でない方がいいです。

これは利用するプログラミング言語に例えばマッピングに類する機能が無いと非常に面倒くさい問題ですよ。
そもそも、このテの問題は元々、PrologとかLisp向きの問題であってCには向いていない。
Pythonは結構「丁度良い」ですが、それは現代的で内包表記を持ってるから、です。
Cでは解けなくはないだろうけど、恐らくC++のSTLを利用した方が「解きやすい」。C#ならもっとラクかも。
そういう性質の問題です。

def perm(lst):
  def loop(lst, remain):
    if remain == []:
      return []
    elif lst[1:] == []:
      return [lst]
    else:
      return [[lst[0]] + l for l in perm(lst[1:])]\
          +\
          loop(lst[1:] + [lst[0]], remain[1:])
  return loop(lst, lst)
    • good
    • 0

A,B,C,Dの順列のケースです。


python3です。
再帰呼び出しをする方法
https://ideone.com/2ClmMo

再帰呼び出しをしない方法
https://ideone.com/kyq6kM

上記URLを参照ください。
尚、再帰呼び出しをする方法の場合は
arr = ["A","B","C","D"]の箇所を
arr = ["A","B","C","D","E"]
のようにすれば、A,B,C,D,Eの順列が求められます。

arr = ["A","B","C","D","E"・・・途中省略・・・,"Z"]
とすれば、アルファベット26文字も可能です。(完了までに莫大な時間がかかると思いますが・・・)
    • good
    • 0

よこから失礼します。


No5の方へ
よろしければ、そのソースをこちらに張り付けていただけませんでしょうか。
こちらは、インデントが乱れませんので、そのままのソースが保たれます。
https://ideone.com/

1.添付図の左側の赤線で囲んだところで、言語を選択してください。
2.次に青線で囲んだところにソースを張り付けてください。(your code goes hereの文字を削除してからです)
3.Run(右側の赤線で囲んだところ)をクリックしてください。
4.実行結果表示され、ソースが登録されるので、そのURLをこのサイトに投稿してください。

そうすると、質問者の方も、そのソースをコピペできるので、確認がしやくすなるかと。
「順列の内容をすべて表示するプログラムにつ」の回答画像6
    • good
    • 0

もう少し綺麗なイメージ

「順列の内容をすべて表示するプログラムにつ」の回答画像5
    • good
    • 0

非再帰だととっても面倒くさいんですよね。

「順列の内容をすべて表示するプログラムにつ」の回答画像4
    • good
    • 0

AN02です。



いけね、Cのカテですね。pythonで書いてます(^-^;
変換するのは容易なので、御参考まで。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。pythonで結構です。動作確認しました。
ところで1つ教えて頂きたいのですが、このプログラムは関数再帰呼び出しということによって実現すると理解してよいでしょうか。私は関数再帰呼び出しができない言語ばかりで仕事をしてきたのでコードが読みにくい感じはしています。

お礼日時:2018/10/02 15:41

取り合えず、こんなかんじ。



Nが桁数ですが、10だと遅い(^-^;

標準ライブラリの itertools.permutations
でもできますね。
「順列の内容をすべて表示するプログラムにつ」の回答画像2
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aと関連する良く見られている質問

Qこのプログラミングの問題がいくら考えてもわかりません。for文とif文を組み合わせて使うと言われたの

このプログラミングの問題がいくら考えてもわかりません。for文とif文を組み合わせて使うと言われたのですが、よろしければ教えてください

Aベストアンサー

No.1です、
念のための追加です。

日本語で「〇〇の値が××だったら、、、。そうでなかったら~。」といった表現で書かれたものが多くのプログラミング言語ではifを用いた処理になります。
同じく「〇〇の値が××になるまで、、、を繰り返す。」といった表現で書かれたものfor文やwhile文を用いた処理になります。

参考まで。

Qc言語の課題がわかりません

XOR を用いて文字列の暗号化及び暗号化された文字列の復号化をするプログラムを作成し,暗号化した文字列の結果は code.txt に出力し、復号化する際には code.txt からファイルを読み込んで復号化することとし、入力する文字列は最大で 9 文字までとする。暗号化および復号化には鍵として1つの文字用いる。鍵は暗号化の際に入力させ、復号化の際にも同じ鍵を用いる。暗号化は文字列の各文字ごとに鍵との間の XOR を取るものとする。と課題で出たのですが、自分には難しすぎて出来ません。どなたかおしえてください。プログラムの途中経過と実行例を記しておきます。
#include<stdio.h>
int main(){
int x;
char a[256],b[256];

printf("Select Mode 1.Encryption, 2.Decryption :");
scanf("%d",&x);
if(a==1){
printf("Input passphrase :");
scanf("%s",a);
printf("Input key:");
scanf("%d",b);
}else{
printf("Input key:");
scanf("%d",b);

}

if(a==3){
printf("Invalid value\n");
}
return 0;
}
<実行例 1>
Select Mode 1.Encryption, 2.Decryption : 1
Input passphrase : password
Input key : $
TEWWSKV@
<実行例 2>
Select Mode 1.Encryption, 2.Decryption : 2
Input key : $
Code : TEWWSKV@
Decode : password
<実行例 3>
Select Mode 1.Encryption, 2.Decryption : 3
Invalid value

XOR を用いて文字列の暗号化及び暗号化された文字列の復号化をするプログラムを作成し,暗号化した文字列の結果は code.txt に出力し、復号化する際には code.txt からファイルを読み込んで復号化することとし、入力する文字列は最大で 9 文字までとする。暗号化および復号化には鍵として1つの文字用いる。鍵は暗号化の際に入力させ、復号化の際にも同じ鍵を用いる。暗号化は文字列の各文字ごとに鍵との間の XOR を取るものとする。と課題で出たのですが、自分には難しすぎて出来ません。どなたかおしえてください...続きを読む

Aベストアンサー

以下、ファイルの入出力を絡めると理解が遠のくので、
シンプルに、画面を通しての入出力動作をするものにしました。
forループの中で行っている1行が最も重要な箇所なので、じっくり理解して下さい。

#include<stdio.h>
#include<string.h>

int main() {
int x;
char a[9+1];
char b[1+1];
char r[9+1];

memset(a, 0x00, sizeof(a));
memset(b, 0x00, sizeof(b));
memset(r, 0x00, sizeof(r));

printf("Select Mode 1.Encryption, 2.Decryption : ");
scanf_s("%d", &x);
if (x == 1) {

printf("Input passphrase : ");
scanf("%s", a);

printf("Input key: ");
scanf("%s", b);

} else if (x == 2) {
printf("Input key: ");
scanf("%s", b);

printf("Code : ");
scanf("%s", a);

printf("Decode : ");

} else {
printf("Invalid value\n");
return 0;
}

for (unsigned int i = 0; i < strlen(a); i++) {
r[i] = a[i] ^ b[0];
}

printf("%s\n", r);

return 0;
}

以下、ファイルの入出力を絡めると理解が遠のくので、
シンプルに、画面を通しての入出力動作をするものにしました。
forループの中で行っている1行が最も重要な箇所なので、じっくり理解して下さい。

#include<stdio.h>
#include<string.h>

int main() {
int x;
char a[9+1];
char b[1+1];
char r[9+1];

memset(a, 0x00, sizeof(a));
memset(b, 0x00, sizeof(b));
memset(r, 0x00, sizeof(r));

printf("Select Mode 1.Encryption, 2.Decryption : ");
scanf_s("%d", &x);
if (x == 1) {

printf(...続きを読む

Qc言語 立方根

プログラムは全くの初心者です。
数学をしていて級数の計算(収束が遅いので)をするために必要最低限だけ覚えようとしました。

c言語で立方根の計算をしたくてnの立方根を出すときに
n=;\\任意の数
t=pow(n,1/3);
printf("%f",t);
でしました。が、試しにn=2でした時1.000…と小数点以下が切り下げ?四捨五入?されています。そのままの値を返す方法が知りたいです。
簡単な質問ですが、すいません。
回答お願いしますm(._.)m

Aベストアンサー

1 / 3 は0ですよ。C言語の基本の基本です(^-^;

プログラム初心者ではしょうがないかもしれませんが
数学の数式とCの数式は別物。
最初は、演算に対して、演算の入力、演算結果の「型」を強く意識して
「式」を覚えるのが肝要です。

Qsleep関数の原理について

sleep関数がPC内でどういった原理で一定時間おきに動作などを行っているのか教えてください。
「Linuxカーネルがどういう働きしている」「ハードがどういう動作している」とかです。

Aベストアンサー

>一定時間おきに動作などを行っているのか
確実にsleep関数で指定した時間はお休みしているだけであり、
厳密には「一定時間おき」に動作はしません。

・LinuxはマルチタスクOSである
・一定時間(確か100Hzだったと思います)ごとにタスク切り換えを行っている

この2点がわかっていれば、
>「Linuxカーネルがどういう働きしている」
は簡単ですよね。

「sleep関数で指定した時間は、タスク切り換えで自分にCPU時間を割り当てることはしない」というだけです。

>「ハードがどういう動作している」
特段ハードでは、sleep関数実現のために何もしていません。

<おまけ>
sleep関数を呼ばなくてもマルチタスクOS上のタスクは、
 ユーザの知らないタイミングで休み休み動いている
ということです。

Q構造体の勉強をしているのですが1と2は同じなのでしょうか?違うのでしょうか? もし違うならなぜ違うの

構造体の勉強をしているのですが1と2は同じなのでしょうか?違うのでしょうか?
もし違うならなぜ違うのか説明してください‼︎
よろしくお願いします。

1.typedef struct roll{メンバー};

2.typedef struct {メンバー}roll;

Aベストアンサー

「struct の直後に来るのが型でメンバーの後に来るのが新しい構造体の名前」の「型」と「構造体の名前」の違いってなんだろ.

さておき, これは typedef の仕様との関係がありますねぇ.

まず構造体の定義を完全に書くと
struct 構造体タグ メンバー定義 宣言子;
という形になります. ここで構造体タグは識別子, メンバー定義は
{ メンバーの宣言 }
という形で宣言子は変数やら配列やらポインタやらを表します. struct 以外は省略可能なのですが, 実際に意味を持つのは
・宣言子を省略する: 「struct 構造体タグ」で表される新しい構造体を定義する
・メンバー定義を省略する: 「struct 構造体タグ」で表される構造体型の変数などを宣言する
・構造体タグを省略する: 構造体タグがなんらかの理由で不要なときにはこの形式もあります
・メンバー定義と宣言子を省略する: 「struct 構造体タグ」で表される構造体型があることを宣言する
の 4つに限られます (全部省略しちゃダメなのは明らかだと思うけど). 再度確認しておくと, 「struct 構造体タグ」で 1つの型を表します.

質問文にある 2つの文を (typedef を除いて) 解釈するとそれぞれ
1. 宣言子を省略している. roll が構造体タグで, 「struct roll」という型を定義する
2. 構造体タグを省略している. roll は宣言子で, この場合は roll という変数を宣言する
となります. そして, *typedef がなければ*どちらも合法です (ただし, 当然ですが意味は違います).

で typedef の影響が出ます. typedef は
宣言子に含まれる識別子に対し, 「typedef がなければ与えられるはずの型」の別名として定義する
という働きをもちます. 例えば
int FOO, *Bar;
だと
・FOO は int型の変数
・Bar は int へのポインタ型の変数
なので, ここに typedef を付けた
typedef int FOO, *Bar;
では
・FOO は int型の別名
・Bar は int へのポインタ型の別名
となります. このように typedef では「別名を定義する」都合上, 宣言子はどうしても必須となります. 従って, 宣言子が省略された 1 はダメということになります.

「struct の直後に来るのが型でメンバーの後に来るのが新しい構造体の名前」の「型」と「構造体の名前」の違いってなんだろ.

さておき, これは typedef の仕様との関係がありますねぇ.

まず構造体の定義を完全に書くと
struct 構造体タグ メンバー定義 宣言子;
という形になります. ここで構造体タグは識別子, メンバー定義は
{ メンバーの宣言 }
という形で宣言子は変数やら配列やらポインタやらを表します. struct 以外は省略可能なのですが, 実際に意味を持つのは
・宣言子を省略する: 「struct 構造体タグ」...続きを読む

QCのif文の書き方の質問です

『x=a & j=1 』の様に、『&』の前後に式を書くことがありますか?
使ったことがないので、ここに質問させて頂いております。
コメント、説明頂けますと大変有り難いです。

if stype=='L' then
x=a & j=1 //===
elseif stype=='M' then
x=a+(h/2) & j=2//============
else x=a+h & j=3//=================
end

以上、宜しくお願いします。

Aベストアンサー

見た目から、命令の区切りに使っているように見えますが、
公式マニュアルを確認しても ; や , はありましたが & は見つけられなかったので断言はできません。

https://help.scilab.org/docs/6.0.1/ja_JP/comma.html
https://help.scilab.org/docs/6.0.1/ja_JP/semicolon.html

QC#のOutOfMemoryException発生要因について

C#でOutOfMemoryExceptionは発生するのは、いくつかサイトを見てみたところ、仮想メモリ不足と考えています。
物理メモリ不足でも起こるものなのでしょうか?

Aベストアンサー

アプリケーションから認識できるのは仮想メモリだけなので、物理メモリの不足が直接OutOfMemoryExceptionを引き起こすことはありません。ただし、物理メモリの不足は仮想メモリ不足の原因になり得ます。

よく、仮想メモリ=ページファイルのような書き方をしているサイトがありますが、これは厳密には間違いです。

この辺りの説明を一通り理解すれば、こんな質問はしなくなるでしょう。

 https://ja.wikipedia.org/wiki/仮想記憶

Qc++ プログラムについて

txtデータを読み込みデータの行をカウントする
指定した行の前後に違うデータを書き込む

指定する行は複数行であるが書き込むデータは始め以外同じ
書き込む数の初めは1からカウントする

書き込むデータは2進数である
といったプログラムを作成したいのですが
アドバイスなどお願いします

Aベストアンサー

>javaプログラムは組んだことがあるのですがc++は初めてでサイトを見てもよくわからないことが多いので
基本的にあなたが悩んでいる部分は言語の違いは関係ありません
考え方の問題なので

https://gab-km.bitbucket.io/blog/html/2013/11/21/typical_of_cplusplus_file_io.html
http://www.geocities.jp/eneces_jupiter_jp/cpp1/005-004.html
必要な知識はここら辺ですかね?

まぁこの際ある程度書きますが...
頭の中で考えているだけで、実際に動かしているわけではないので
正しく動く保証はできません、そこは調整してください
あといくらか省略していますが、既にご自身で書いてあるソースから想像できると思うので
そこは自分で書き足してくださいね

挿入する行の計算方法は「指定した行」±1ですね

cin >> a; //行指定

std::ofstream ofs("新しいファイル");
std::string line;
int i = 1;
while (std::getline(ifs, line))
{
if( a == i-1 )
{
ofs << 挿入するデータ << std::endl;
}

ofs << line << std::endl;

if( a == i+1 )
{
ofs << 挿入するデータ << std::endl;
}
}

我ながらなかなか雑な処理です
もっとスマートに作れるでしょうけど
まぁ求めている出力は出せるかと

>javaプログラムは組んだことがあるのですがc++は初めてでサイトを見てもよくわからないことが多いので
基本的にあなたが悩んでいる部分は言語の違いは関係ありません
考え方の問題なので

https://gab-km.bitbucket.io/blog/html/2013/11/21/typical_of_cplusplus_file_io.html
http://www.geocities.jp/eneces_jupiter_jp/cpp1/005-004.html
必要な知識はここら辺ですかね?

まぁこの際ある程度書きますが...
頭の中で考えているだけで、実際に動かしているわけではないので
正しく動く保証はできません、そ...続きを読む

Qこのプログラムを教えてください。

このプログラムを教えてください。

Aベストアンサー

以下のPGで実現出来ます。
難解なところは特にありません。
初めて見る関数などの無いよう、敢えて四則演算を用いて解を導いています。
これを見て、数式の解を表現する1つの方法をぜひ身に付けて下さい。

/* 課題1 */
/* maru.c */

#include<stdio.h>
#include<string.h>
#define PI 3.14

int main() {

float d; /* 入力の直径 */
float e; /* 円周 */
float m; /* 面積 */
float s; /* 表面積 */
float v; /* 体積 */

printf("直径を入力してください[cm]: ");
scanf("%f", &d);

d = d / 2; /* 入力直径を半径に変換 */
d = d / 100; /* 入力値の単位変換 [cm]→[m] */

printf("(1)円の円周 [m] =%f\n", 2 * PI * d );
printf("(2)円の面積 [m2]=%f\n", PI * d * d );
printf("(3)球の表面積[m2]=%f\n", 4 * PI * d * d );
printf("(4)球の体積 [m3]=%f\n", (4.0 / 3.0) * PI * d * d * d);

return 0;
}

以下のPGで実現出来ます。
難解なところは特にありません。
初めて見る関数などの無いよう、敢えて四則演算を用いて解を導いています。
これを見て、数式の解を表現する1つの方法をぜひ身に付けて下さい。

/* 課題1 */
/* maru.c */

#include<stdio.h>
#include<string.h>
#define PI 3.14

int main() {

float d; /* 入力の直径 */
float e; /* 円周 */
float m; /* 面積 */
float s; /* 表面積 */
float v; /* 体積 */

printf("直径を入力してください[cm]: ");
scanf("%f", &d);

d = d / 2; /* ...続きを読む

QC言語でプログラミングを組みたいんですがcosの使い方がわかりません

x_i = cos((pi*(2i-1))/2N) (i=1,2,…,N)

という式で、N=5,9,17の時の値を求めたいのですが、うまくできません。

頑張ってN=5の式を作ってみたのですがうまくいきませんでした。
C言語、プログラミング初心者でわからないのでできるだけ丁寧に教えていただけると助かります。

自分で作ってみたプログラムを書いてみたので、どこが違うか、またどうすればいいかを教えていただきたいです。



#include <stdio.h>
#include <math.h>

#define iMAX 5

#define PI 3.1415926535


int main()
{

int i ;

int x[iMAX] ;

int n = ((PI * (2i-1) ) / 10) ;

double cos ( n ) ;



for (i = 1; i < 5; i++) {

x[i] = cos ( n );

}


for (i = 1; i<=5; i++) {

printf("x[%d] = %d\n",i,x[i]);

}


return 0 ;


}

x_i = cos((pi*(2i-1))/2N) (i=1,2,…,N)

という式で、N=5,9,17の時の値を求めたいのですが、うまくできません。

頑張ってN=5の式を作ってみたのですがうまくいきませんでした。
C言語、プログラミング初心者でわからないのでできるだけ丁寧に教えていただけると助かります。

自分で作ってみたプログラムを書いてみたので、どこが違うか、またどうすればいいかを教えていただきたいです。



#include <stdio.h>
#include <math.h>

#define iMAX 5

#define PI 3.1415926535


i...続きを読む

Aベストアンサー

cosの結果はdouble型です。
x_i = cos((pi*(2i-1))/2N) は、コード上、正確には
x_i = cos((pi*(2*i-1))/(2*N)) です。
N=5の場合、iを1からNまで変化させればOKです。
以下のようにしてください。
#include <stdio.h>
#include <math.h>
#define N 5
#define PI 3.1415926535
int main()
{

int i;
double x_i;
for (i = 1; i <= N; i++) {
x_i = cos((PI*(2*i-1))/(2*N));
printf("x[%d] = %f\n",i,x_i);
}
return 0;
}
-----------------------
以下、実行結果です。
x[1] = 0.951057
x[2] = 0.587785
x[3] = 0.000000
x[4] = -0.587785
x[5] = -0.951057

cosの結果はdouble型です。
x_i = cos((pi*(2i-1))/2N) は、コード上、正確には
x_i = cos((pi*(2*i-1))/(2*N)) です。
N=5の場合、iを1からNまで変化させればOKです。
以下のようにしてください。
#include <stdio.h>
#include <math.h>
#define N 5
#define PI 3.1415926535
int main()
{

int i;
double x_i;
for (i = 1; i <= N; i++) {
x_i = cos((PI*(2*i-1))/(2*N));
printf("x[%d] = %f\n",i,x_i);
}
return 0;
}
-----------------------
以下、実行結果です。
x[...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング