0

申し分なく、私の問題は、数独プログラムを使用している状況でどこに行くべきかわからないことです。現在、私は複数のプログラムを連携させて数独プログラムを作成しています。この数独プログラムは、スペースでも数字でも、それぞれ 9 文字の 9 行の入力を受け取ることが想定されています。例:

53  7    
6  195   
 98    6
8   6   3
4  8 3  1
7   2   6
 6    28
   419  5
    8   79

プログラムがもたらすものは次のとおりです。

534678912
672195348
198342567
859761423
426853791
713924856
961537284
287419635
345286179

私の現在のプログラムは、ファイルstack.h、stack.cc、sudokuboard.h、sudokuboard.cc、sudoku.cc、およびMakefile、およびtest.txtで構成されています(上記の入力例で構成されています)

プログラム stack.h:

struct Node {
  StackElementType data;
  Node *next;
};
class Stack {
 public:

 Stack(); //constructor
 ~Stack(); //deconstructor
 Stack(const Stack & orig); // copy constructor
 void output(ostream & ostr) const; //output method
 bool empty() const; // if empty returns true
 void push(const StackElementType & item); // puts new item on top of stack
 void pop(); // removes top element of nonempty stack
 StackElementType top() const; // returns copy of top element of a stack

 private:
 Node*first;
 size_t _size;
}

私のコードを直接コピーすることができないため、これにはスペルミスがある可能性があることに注意してください。

私のstack.ccは

#include "stack.h"
#include <cstdlib>
#include <cassert>

void destroy(Node *p)
{
  // delete all nodes dominated by p.
  while (p != NULL) {
    Node *old = p;
    p = p->next;
    delete old;
  }
}

Node *copy(Node *p)
{
  // Make a deep copy of linked list dominated by p.
  Node *result = NULL;
  if (p != NULL) {
    result = new Node;
    Node *last = result;
    while (p != NULL) {
      // invariant: last points to a node ready to receive p's data.
      last->data = p->data;
      last->next = NULL;
      p = p->next;
      if (p != NULL) {
    // there's going to more to this copy.  Get it ready.
    last->next = new Node;
    last = last->next;
      }
    }
  }
  return result;
}

Stack::Stack()
{
  first = NULL;
}

Stack::~Stack()
{
  destroy(first);
}

Stack::Stack(const Stack & orig)
{
  first = copy(orig.first);
}

Stack & Stack::operator=(const Stack & rhs)
{
  if (this != &rhs) 
    first = copy(rhs.first);
  return *this;
}

void Stack::output(ostream & ostr) const
{
  ostr << "<";
  for(Node *p = first;p;p=p->next) {
    ostr << p->data;
    if (p->next)
      ostr << ", ";
  }
  ostr << ">";
}

void Stack::push(const ElementType & item)
{
  Node *born = new Node;
  born->data = item;
  born->next = first;
  first = born;
}

void Stack::pop()
{
  assert(!empty());
  Node *rest = first->next;
  delete first;
  first = rest;
}

ElementType Stack::top() const
{
  assert(!empty());
  return first->data;
}

bool Stack::empty() const
{
  return first==NULL;
}

これは単にスタックに使用しているものです

私の sudokuboard.h:

#include <iostream>

#define SDIM 9

class SudokuBoard {
 public:
  //------------------------------------------------------------------------
  SudokuBoard();
  // Construct a blank sudoku board
  //------------------------------------------------------------------------

  //------------------------------------------------------------------------
  void print(std::ostream & ostr) const;
  // display it.  duh.
  //------------------------------------------------------------------------

  //------------------------------------------------------------------------
  void place(size_t r, size_t c, char digit);
  // PRE: safe(r,c,digit)
  //------------------------------------------------------------------------

  //------------------------------------------------------------------------
  void remove(size_t r, size_t c, char digit); 
  // PRE: get(r,c) == digit
  //------------------------------------------------------------------------

  //------------------------------------------------------------------------
  char get(size_t r, size_t c) const;
  // Return the digit at (r,c) on the board.  or ' ' if blank.
  //------------------------------------------------------------------------

  //------------------------------------------------------------------------
  bool safe(size_t r, size_t c, char digit) const;
  // 
  //------------------------------------------------------------------------

  //------------------------------------------------------------------------
  bool done() const; 
  // Return true iff every cell has a number
  //------------------------------------------------------------------------
 private:
  std::string rows[SDIM];
};

私のsudokuboard.ccながら

#include <iostream>
#include <cassert>
#include "sudokuboard.h"

#define ASSERTBOUNDS assert(0 <= r and r < SDIM and 0 <= c and c < SDIM)

SudokuBoard::SudokuBoard()
{
  for (size_t i = 0;i<SDIM;i++) {
    rows[i] = "";
    for (size_t j=0;j<SDIM;j++)
      rows[i] += ' ';
  }
}

void SudokuBoard::place(size_t r, size_t c, char digit)
{
  ASSERTBOUNDS;
  assert(safe(r,c,digit));
}

void SudokuBoard::remove(size_t r, size_t c, char digit)
{
  ASSERTBOUNDS;
  assert(get(r,c)==digit);
  rows[r][c] = ' ';
}

char SudokuBoard::get(size_t r, size_t c) const
{
  ASSERTBOUNDS;
  return rows[r][c];
}


void SudokuBoard::print(std::ostream & ostr) const
{
  for (size_t i=0;i<SDIM;i++)
    ostr << rows[i] << std::endl;
}
bool SudokuBoard::safe(size_t r, size_t c, char digit) const
{
 for(size_t r=0; r<SDIM; r++)
    for(size_t c=0; c<SDIM; c++)
       if (get(r,c) == digit)
           return false;

 for(size_t c=0; c<SDIM; c++)
    for(size_t r=0; r<SDIM; r++)
       if (get(r,c) == digit)
           return false;
  return true;
}
bool SudokuBoard::done() const
{
  for (size_t r=0;r<SDIM;r++)
    for (size_t c=0;c<SDIM;c++)
      if (rows[r][c]==' ')
    return false;
  return true;
}

私のsudoku.ccは、目標を達成する方法について一般的なアイデアしか持っていないため、現在ほとんど空白です。空のスペースを埋める方法は、単一の領域を取り、現在の行/列に可能な限り小さい数を入れ、その行/列にそれよりも大きい数がある場合は行くことです+1アップ。次に、列などを下ります。

私の質問は、次の sudokuboard.cc と stack.cc のプログラムを自分の sudoku.cc にどのように統合するかです。何らかの方法で test.txt の入力を取得し、各行を空のボードに変換する必要があることは知っていますが、そのための cin 入力を表現する方法がまったくわかりません!

言い換えれば、sudok.cc を開始するための助けを探しています。どのようにアプローチすればよいですか?

数独.cc

#include <iostream>
#include <cassert>
#include "sudokuboard.h"
#include "stack.h"

int main()
{


}

これらの回答をくれたことに感謝したいと思います。皆さんのおかげで、私の研究室は順調に進んでいます! 私の担当者が低すぎるため、あなたにポイントを与えることはできませんが、そうでなければ私はします!

4

3 に答える 3

0

私の最初の質問は、なぜあなたがStackクラスを持っているのかということです。再帰関数を使用すると、スタックが無料になります。

あなたの質問に関して:私std::getlineは行を読むために使用します。9文字を超える文字を無視するか、コメントを許可するか、または入力時にフォーマットエラーとして扱うかはあなた次第です。ただし、経験から、少なくとも末尾の空白を追加することは許可します。行を取得したら、おそらく最も簡単な解決策は、最小9文字(resize文字列で機能)まで強制し、末尾に空白を追加することです。次に、すべての文字が数字またはスペース文字(std::find_if、適切な述語を含む)のいずれかであることを確認します。スペースを「0」に変換した場合も簡単になる可能性があります。内部表現が0空の正方形(最も論理的な選択、IMHO)を使用する場合、'0'

ボード()の最も論理的な表現を想定するとvector<int>、これは次のようになります。

struct TransformInputForSudoku
{
    int operator()( char ch ) const
    {
        if ( ch == ' ' ) {
            return 0;
        } else if ( ! isdigit( static_cast<unsigned char>( ch ) ) ) {
            return ch - '0';
        } else {
            throw std::runtime_error( "Illegal character" ) ;
        }
    }
};

std::vector<int>
getBoard( std::istream& source )
{
    std::vector<int> results;
    while ( results.size() < 81 ) {
        std::string line;
        if ( ! std::getline( source, line ) ) {
            throw std::runtime_error( "Input error" );
        }
        line.resize( 9, ' ' );  //  extra char's are comments
        std::transform( line.begin(),
                        line.end(),
                        std::back_inserter( results ),
                        TransformInputForSudoku() );
    }
    return results;
}

(このコードは、単一の機能オブジェクトで入力検証と変換を組み合わせたものです。)

于 2012-10-04T08:10:45.733 に答える
0

ファイルを読み込むには、fstreamを見てください。std::cin から読み取る場合と同様に、ファイル ストリームから読み取ることができます。std::vector<std::string>次に、ファイル全体を読み取って、または別の場所に保存できます。それはあなた次第です。用途に合わせて最適な容器を見つけてください。

std::vector<std::string>  data;
std::string               line;
std::fstream              file("test.txt", std::in);

if (file.good())
{
   while (file.eof() == false)
   {
     getline(file, line);
     data.push_back(line);
   }
}

その後、 を実行してデータにアクセスできますdata[r][c]。今はテストできないので、多少の誤差があるかもしれませんが、それは一般的な考えです

于 2012-10-04T07:44:50.517 に答える
0

テキストファイルを読み取るために使用する方法:

//Code here
std::ifstream infile("test.txt", std::ios::binary);
if(infile.is_open())
{
    char szFileData[32]; //I think we can assume that each line won't be above 32 bytes
    infile.getline(szFileData, 32);
    do
    {
       //Set the cells to the data you just pulled
       infile.getline(szFileData, 32);
    }while(infile.good());
}
else
{
   std::cout<<"Unable to open file!"<<std::endl;
}
于 2012-10-04T07:51:43.860 に答える