前提・実現したいこと
C++で問題を解いています。
以下の関数が問題通り動いているかわかりません。
発生している問題・エラーメッセージ
ジョーカーを除いた52枚のトランプカードが上から順番に
s:スペード, C:クローバー,D:ダイヤ, H:ハートとして
SK SQ SJ S10 S9 S8 S7 S6 S5 S4 S3 S2 SA CK CQ CJ C10 C9 C8 C7 C6 C5 C4 C3 C2 CA DK DQ DJ D10 D9 D8 D7 D6 D5 D4 D3 D2 DA HK HQ HJ H10 H9 H8 H7 H6 H5 H4 H3 H2 HA
積まれています。
これを昇順にする問題です。
その際に使う関数として、一番上(head)から n 枚カードを残しその後に続くカードを切り取って 2 組に分割するsplit関数を作ります。実行後 head 自体は変化なく残った n 枚の組の一番上とします。切り取られた組の一番上のカードのポインタが return されるようにします。
今のところコンパイルは通るのですが、実行しても何も起きません。
該当のソースコード
#include <iostream>
using namespace std;
class Card {//トランプの一枚のカード
private:
int suit; //0-3 各々がH(Heart), D(Diamond), C(Clover), S(Spade)に対応
int number; //1-13
Card *next; //一枚下にあるカードを指すポインタ
public:
Card(int i, int j, Card current_next=NULL){suit = i; number = j; next = current_next;}
friend ostream& operator<<(ostream&, Card);
friend void printCards(Card head);
friend Card *split(Card *, int );
friend void pileup(Card *, Card *);
};
// Cardの出力オペレータ
ostream& operator<<(ostream &fout, Card c){
// suit = 0, 1, 2, 3 をH, D, C, Sに変換してsuitを表示
if(c.suit==0) fout << "H";
else if(c.suit==1) fout << "D";
else if(c.suit==2) fout << "C";
else fout << "S";
// number = 1 の時はA(Ace)を表示
// number = 2-10の時はそのまま数を表示
// number = 11, 12, 13 の時はJ(Jack), Q(Queen), K(King)を表示
if(c.number==1) fout << "A";
else if(c.number==11) fout << "J";
else if(c.number==12) fout << "Q";
else if(c.number==13) fout << "K";
else fout << c.number;
// 末尾にスペースを一つ表示
fout << ' ';
return fout;
}
//一番上のheadから順番に全てのカードをたどって表示する関数
void printCards(Card *head){
Card *current;
current = head;
int i = 0;
while(current != NULL){//次のカードがなくなるまで繰り返す
//currentの内容を表示し、次のカードに移動
cout << *current;
current = current->next;
// 13枚毎に改行する
i++;
if(i == 13){
cout << endl;
i = 0;
}
}
}
// 一番上(head)から n 枚カードを残しその後に続くカードを切り取って 2 組に分割する関数
// 実行後 head 自体は変化なく残った n 枚の組の一番上となる
// 切り取られた組の一番上のカードのポインタが return される
Card *split(Card *head, int n){
int i = 0;
while(head!=NULL){
head = head->next;
i++;
if(i==n)
break;
}
return head;
}
// head1 のカードの組を head2 の組の上にのせて 1 組にする関数
// 実行後 head1 は変化がなくまとめた組の一番上となる
void pileup(Card *head1, Card *head2){
while(head1!=NULL){
Card *tmp;
tmp = head2;
head2 = head1;
head1->next = tmp;
}
}
// 与えられたリストを逆順にしたリストを返す関数
Card *reverse(Card *head){
Card *new_head, *reverse_head;
reverse_head = NULL;
// カードを 1 枚ずつ head の上から取り去る
// そのカードを別の場所に 1 枚ずつ積んでいく
// 結果として逆順に積まれる
while(head != NULL){
new_head = split(head,1);
pileup(head,reverse_head);
reverse_head = head;
head = new_head;
}
return reverse_head;
}
int main() {
Card *head;//一番上のカードを指すポインタ
for(int i = 0; i < 4; i++){
for(int j = 1; j <= 13; j++){
// 最初のi=0,j=1の時のみ、next=NULLとしてカードを生成
// それ以降は現在のheadをnextとしてカードを生成し、新しいカードをheadとする
if(i==0 && j==1)
head = new Card(0, 1, NULL);
else
head = new Card(i, j, head);
}
}
// カードの表示
printCards(reverse(head));
return 0;
}
試したこと
split関数とpileup関数はすでに自分なり考えて書いてみました。
補足情報(FW/ツールのバージョンなど)
split関数とpileup関数以外は変えずに、2つの関数を追記することでプログラムを完成させます。
回答3件
あなたの回答
tips
プレビュー