0

学習演習として、さまざまな種類の数値をさまざまなファイルに並べ替えたいと思います。正しくソートするためにdoubleとintを取得することができましたが、正しくフォーマットするために自分のタイプ(カードのデッキをソートするため)を取得できません。Readerクラスのsort関数に絞り込むことができました。あらゆる種類のエラーが発生します。私は正確に何を間違っているのですか?それとも私は何かが足りないのですか?皆さん、ありがとうございました。問題を明確に説明できたと思います。

カード用に作成したファイルは次のようになります...

1 11 (meaning Jack of Diamonds)

2 8 (meaning 8 of hearts)

等...

エラー:

エラー:'((Reader )this)-> Reader :: array [compareIndex] <((Reader)this)-> Reader ::array[smallestIndex]'の'operator<'に一致しません

エラー:初期化時に「Card」を「int」に変換できません

エラー:'((Reader *)this)-> Reader :: array [smallestIndex]=temp'の'operator='に一致しません

私のコード

最後に、メイン

#include <iostream>
#include "Reader.h"
#include "Card.h"

using namespace std;


int main() {

    Reader<int> nums;
    Reader<double> dubs;
    Reader<Card> cards;
    int number;

    do {

        cout << "Enter 1 if your file contains integers\n"
           << "Enter 2 if your file contains doubles\n"
           << "Enter 3 if your file contains Cards:\n"
           << "Enter a number: ";
        cin >> number;

        if (number == 1){
            nums.open_IO();
            nums.read_array();
            nums.sort();
            nums.write_array();
            nums.close_IO();
        } else if (number == 2){
            dubs.open_IO();
            dubs.read_array();
            dubs.sort();
            dubs.write_array();
            dubs.close_IO();
        } else if (number == 3){
            cards.open_IO();
            cards.read_array();
            cards.sort();
            cards.write_array();
            cards.close_IO();
        }

    } while ((number != 1) && (number != 2) && (number != 3));


}

Reader.h

#ifndef READER_H
#define READER_H
#include <string>
#include <fstream>
using namespace std;

template <class rList>
class Reader {
 public:
    static const int SIZE = 50;

      Reader();

      bool open_IO();

      void close_IO();

      bool read_array();

      bool write_array();

      void sort();


 private:
      // Ask for the files
      void ask_filenames();

      rList array[SIZE];
      int readSize;

      // input file names and stream to get the data
      string readFileName;
      ifstream inFile;

      // output file names and stream to get the data
      string writeFileName;
      ofstream outFile;
      bool askedFileNames;
    };

#endif

#include "Reader.cpp"

私のReader.Cppファイル

// File: Reader.cpp
#ifndef READER_CPP
#define READER_CPP
#include "Reader.h"
#include <iostream>
using namespace std;

/***************************************************************************
 * Contructors and modifying functions defined in "Reader.h"
***************************************************************************/


template <class rList>
Reader<rList>::Reader() {
  askedFileNames = false;
  readFileName = "";
  writeFileName = "";
  readSize = 0;
  rList empty;
  for( int i = 0; i<SIZE; i++ ) array[i]=empty;
}

template <class rList>
bool Reader<rList>::open_IO(){
    if(!askedFileNames) ask_filenames();

    inFile.open(readFileName.c_str()); //we can't pass a string, we need a char array
    if(!inFile.is_open()) {
        return false;
    }
    outFile.open(writeFileName.c_str());
    if(!outFile.is_open()) {
        inFile.close(); //inFile opened successfully so it needs to be closed now
        return false;
    }
    return true;
}

template <class rList>
void Reader<rList>::close_IO() {
    inFile.close();
    outFile.close();
}

template <class rList>
bool Reader<rList>::read_array() {
    if(inFile.is_open()) {
        inFile >> readSize;
        int index = 0;
        while(!inFile.eof() && index < readSize) {
            inFile >> array[index++]; //increments index after assigning value
        }
        readSize = index; //the input file could have had fewer numbers so set readSize
        return true;
    }
    return false;
}

template <class rList>
bool Reader<rList>::write_array() {
    if(outFile.is_open()) {
        outFile << readSize << endl;
       //don't forget the number indicating the element co
        int index = 0;
        while(index < readSize) {
            outFile << array[index++] << endl;
        }
        return true;
    }
    return false;
}

template <class rList>
void Reader<rList>::sort() {
    int startIndex = 0;
    int compareIndex;
    int smallestIndex;
    bool smallerFound;
    while(startIndex < readSize) {
        smallestIndex = startIndex;
        compareIndex = startIndex + 1;
        smallerFound = false;
        while(compareIndex < readSize) { //find the smallest value from the starting index
            if(array[compareIndex] < array[smallestIndex]) {
                smallestIndex = compareIndex;
                smallerFound = true;
            }
            compareIndex++;
        }
        if(smallerFound) { //only swap the values if a smaller value is found
            int temp = array[startIndex];
            array[startIndex] = array[smallestIndex];
            array[smallestIndex] = temp;
        }
        startIndex++;
    }
}

/*--------------------------------------------------------------
  This function asks the user for the filenames. This operation
  is placed in a separate function because it is called multiple
  times.
  --------------------------------------------------------------*/
template <class rList>
void Reader<rList>::ask_filenames() {
  cout << "Welcome. Please type in the name of the file to read the numbers.\n";
  cin >> readFileName;
  cout << "Thank you. Please type in the name of the file to write the numbers.\n";
  cin >> writeFileName;
  askedFileNames = true;
}

#endif

Card.h

#include <ostream>
#include <string>
#include "Reader.h"

using namespace std;

class Card{
 public:
    static const int SIZE = 50;
    enum SUIT {clubs, diams, hears, spads };
    enum RANK {ace=1, two, thr, fou, fiv, six, sev, eig, nin, ten, jac, que, kin};

    Card();

    Card(int newSuit, int newRank);

    void change(int newSuit, int newRank);

    friend ostream& operator << ( ostream& out, Card theCard );
    friend istream& operator >> ( istream& in, Card theCard );

 private:
    void change_rank(int newRank);

    void change_suit(int newSuit);

    string get_rank() const;

    string get_suit() const;

    SUIT suit;
    RANK rank;


};

Card.cpp

    #include <iostream>
#include <string>
#include "Card.h"

using namespace std;

Card::Card() { suit = spads; rank = ace; }

Card::Card(int newSuit, int newRank) {
    change(newSuit, newRank);
}

void Card::change( int newSuit, int newRank ) {
    change_suit( newSuit );
    change_rank( newRank );
}


ostream& operator << ( ostream& out, Card theCard ) {
  out << theCard.get_rank() << " of " << theCard.get_suit();
  return out;
}

istream& operator >> ( istream& in, Card theCard ) {
    int aSuit;
    int aRank;

    in >> aSuit >> aRank;
    return in;
}


// private member functions to set the private variables with their
// corresponding values: integer input -> enumerated type;
void Card::change_rank( int newRank ) {
    if( newRank == ace ) rank = ace;
    else if( newRank == two ) rank = two;
    else if( newRank == thr ) rank = thr;
    else if( newRank == fou ) rank = fou;
    else if( newRank == fiv ) rank = fiv;
    else if( newRank == six ) rank = six;
    else if( newRank == sev ) rank = sev;
    else if( newRank == eig ) rank = eig;
    else if( newRank == nin ) rank = nin;
    else if( newRank == ten ) rank = ten;
    else if( newRank == jac ) rank = jac;
    else if( newRank == que ) rank = que;
    else if( newRank == kin ) rank = kin;
}

void Card::change_suit( int newSuit ) {
    if( newSuit == clubs ) suit = clubs;
    else if( newSuit == spads ) suit = spads;
    else if( newSuit == diams ) suit = diams;
    else if( newSuit == hears ) suit = hears;
}

  // Private member functions to extract the information from the card
  // class.
string Card::get_rank() const {
    if( rank == ace ) return "ace";
    if( rank == two ) return "two";
    if( rank == thr ) return "three";
    if( rank == fou ) return "four";
    if( rank == fiv ) return "five";
    if( rank == six ) return "six";
    if( rank == sev ) return "seven";
    if( rank == eig ) return "eight";
    if( rank == nin ) return "nine";
    if( rank == ten ) return "ten";
    if( rank == jac ) return "jack";
    if( rank == que ) return "queen";
    if( rank == kin ) return "king";
    return "get_rank: error";
}

string Card::get_suit() const {
    if( suit == diams ) return "D";
    if( suit == hears ) return "H";
    if( suit == spads ) return "S";
    if( suit == clubs ) return "C";
    return "get_suit: error";
}
4

2 に答える 2

2

std::vector<Card>C配列の代わりに使用し、のoperator<ためにオーバーロードしCardた場合は、標準ライブラリを使用してデッキをシャッフルおよびソートできます。

vector<T>標準ライブラリが付属しているコンテナです。これは、タイプの要素を格納できるクラステンプレートですTT数値タイプ、a、std::stringまたはastructまたはclass

以下の小なり演算子をオーバーロードする方法は次のCardとおりです。

bool Card::operator<(const Card& other)
{
    return true if this card is smaller than the other card;
    // You may want to order by rank, then by suit, or vice-versa.
}

この演算子を定義すると、標準ライブラリのコンテナとアルゴリズムがの注文方法を「認識」するようになりますCards

のを使用する方法は次のとおりvectorですCard

std::vector<Card> deck(52); // Initially sized to 52 elements
// Populate deck just like you would an array
deck[0] = Card(diams, ace);
etc...

// Sort the deck
std::sort(deck.begin(), deck.end());

// Shuffle the deck
std::random_shuffle(deck.begin(), deck.end());

// Get the 5th card in the deck
Card fifth = deck[4];

std::sortクイックソートアルゴリズムを使用します。これは、作成したバブルソートよりもはるかに高速です(不快感はありません:-)。標準ライブラリが提供するものを打ち負かすことができる手作りのデータ構造とアルゴリズムを書くのは難しいです。コンパイラの作成者は、標準ライブラリの実装を完成させ、調整するために何年も費やしてきました。

標準ライブラリコンテナを使用する場合、自由に使用できる標準ライブラリアルゴリズムの武器があります。これにより、同じ基本的なアルゴリズムやデータ構造を何度も書き直すことなく、問題の解決に集中できます。

于 2012-09-02T22:52:05.160 に答える
1

の比較演算子を実装する必要がありますCard

class Card{
 public:
  friend bool operator< ( const Card &left, const Card &right ) {
     ... 
  }

そして、タイプミスがあります。

    if(smallerFound) { //only swap the values if a smaller value is found
        int temp = array[startIndex];
        array[startIndex] = array[smallestIndex];
        array[smallestIndex] = temp;
    }

する必要があります

    if(smallerFound) { //only swap the values if a smaller value is found
        rList temp = array[startIndex];
        array[startIndex] = array[smallestIndex];
        array[smallestIndex] = temp;
    }

またはもっと簡単に

    if(smallerFound) { //only swap the values if a smaller value is found
        std::swap( array[startIndex], array[smallestIndex] );
    }
于 2012-09-02T22:48:04.373 に答える