- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
所以我不得不为高中的计算机项目编写一个程序,我想做一个数独求解器。 “解决”算法是这样实现的:-
到目前为止,我有这段代码:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
//Prints a message and exits the application.
void error(const char msg[])
{
cout << "An error occurred!" << endl;
cout << "Description: " << msg << endl;
exit(0);
}
//A representation of a sudoku board. Can be read from a file or from memory.
class Sudoku
{
protected:
//For a point x, y and a number n in the board, mAllowed[x][y][n]
//is 1 if n is allowed in that point, 0 if not.
int mAllowed[9][9][10];
int filledIn;
public:
/*
* For mBoard[i][j], the location is (i,j) in the below map:
*
* (0,0) (0,1) (0,2) (0,3) (0,4) (0,5) (0,6) (0,7) (0,8)
* (1,0) (1,1) (1,2) (1,3) (1,4) (1,5) (1,6) (1,7) (1,8)
* (2,0) (2,1) (2,2) (2,3) (2,4) (2,5) (2,6) (2,7) (2,8)
*
* (3,0) (3,1) (3,2) (3,3) (3,4) (3,5) (3,6) (3,7) (3,8)
* (4,0) (4,1) (4,2) (4,3) (4,4) (4,5) (4,6) (4,7) (4,8)
* (5,0) (5,1) (5,2) (5,3) (5,4) (5,5) (5,6) (5,7) (5,8)
*
* (6,0) (6,1) (6,2) (6,3) (6,4) (6,5) (6,6) (6,7) (6,8)
* (7,0) (7,1) (7,2) (7,3) (7,4) (7,5) (7,6) (7,7) (7,8)
* (8,0) (8,1) (8,2) (8,3) (8,4) (8,5) (8,6) (8,7) (8,8)
*
*/
int mBoard[9][9];
//Read in from file with given name.
Sudoku(char filename[])
{
filledIn = 0;
int i, j, k;
//Fill the board with 0s.
for (i = 0; i < 9; ++i)
for (j = 0; j < 9; ++j)
mBoard[i][j] = 0;
//Set every number to 'allowed' initially.
for (i = 0; i < 9; ++i)
for (j = 0; j < 9; ++j)
for (k = 1; k <= 9; ++k)
mAllowed[i][j][k] = 1;
//Read in from the file.
ifstream file(filename);
if (!file)
error("File doesn't exist!");
for (i = 0; i < 9; ++i)
for (j = 0; j < 9; ++j)
if (file)
{
int m;
file >> m;
if (m)
set(i, j, m);
}
else
error("Not enough entries in file!");
}
//Solve the board!
int solve()
{
int prevFilledIn;
do
{
prevFilledIn = filledIn;
singleLeft();
checkOnlyAllowed();
} while (filledIn - prevFilledIn > 3);
if (filledIn < 81)
guess();
return filledIn == 81;
}
//Given a point i, j, this looks for places where this point
//disallows a number and sets the 'mAllowed' table accordingly.
void fixAllowed(int i, int j)
{
int n = mBoard[i][j], k;
for (k = 0; k < 9; ++k)
mAllowed[i][k][n] = 0;
for (k = 0; k < 9; ++k)
mAllowed[k][j][n] = 0;
//Look in 3x3 sets too. First, set each coordinate to the
//highest multiple of 3 below itself. This takes us to the
//top-left corner of the 3x3 set this point was in. Then,
//add vectorially all points (x,y) where x and y each are
//one of 0, 1 or 2 to visit each point in this set.
int x = (i / 3) * 3;
int y = (j / 3) * 3;
for (k = 0; k < 3; ++k)
for (int l = 0; l < 3; ++l)
mAllowed[x + k][y + l][n] = 0;
mAllowed[i][j][n] = 1;
}
//Sets a point i, j to n.
void set(int i, int j, int n)
{
mBoard[i][j] = n;
fixAllowed(i, j);
++filledIn;
}
//Try using 'single' on a point, ie, only one number can fit in this
//point, so put it in and return 1. If more than one number can fit,
//return 0.
int trySinglePoint(int i, int j)
{
int c = 0, m;
for (m = 1; m <= 9; ++m)
c += mAllowed[i][j][m];
if (c == 1)
{
for (m = 1; m <= 9; ++m)
if (mAllowed[i][j][m])
set(i, j, m);
//printBoard();
return 1;
}
return 0;
}
//Try to solve by checking for spots that have only one number remaining.
void singleLeft()
{
for (;;)
{
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j)
if (!mBoard[i][j])
if (trySinglePoint(i, j))
goto logic_worked;
//If we reached here, board is either full or unsolvable by this logic, so
//our job is done.
return;
logic_worked:
continue;
}
}
//Within rows, columns or sets, whether this number is 'allowed' in spots
//other than i, j.
int onlyInRow(int n, int i, int j)
{
for (int k = 0; k < 9; ++k)
if (k != j && mAllowed[i][k][n])
return 0;
return 1;
}
int onlyInColumn(int n, int i, int j)
{
for (int k = 0; k < 9; ++k)
if (k != i && mAllowed[k][j][n])
return 0;
return 1;
}
int onlyInSet(int n, int i, int j)
{
int x = (i / 3) * 3;
int y = (j / 3) * 3;
for (int k = 0; k < 3; ++k)
for (int l = 0; l < 3; ++l)
if (!(x + k == i && y + l == j) && mAllowed[x + k][y + l][n])
return 0;
return 1;
}
//If a number is 'allowed' in only one spot within a row, column or set, it's
//guaranteed to have to be there.
void checkOnlyAllowed()
{
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j)
if (!mBoard[i][j])
for (int m = 1; m <= 9; ++m)
if (mAllowed[i][j][m])
if (onlyInRow(m, i, j) || onlyInColumn(m, i, j) || onlyInSet(m, i, j))
set(i, j, m);
}
//Copy from a given board.
void copyBoard(int board[9][9])
{
filledIn = 0;
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j)
{
if (board[i][j] > 0)
++filledIn;
mBoard[i][j] = board[i][j];
}
}
//Try to solve by 'guessing'.
void guess()
{
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j)
for (int n = 1; n <= 9; ++n)
if (!mBoard[i][j])
if (mAllowed[i][j][n] == 1)
{
//Do a direct copy so that it gets the 'mAllowed'
//table too.
Sudoku s = *this;
//Try solving with this number at this spot.
s.set(i, j, n);
if (s.solve())
{
//It was able to do it! Copy and report success!
copyBoard(s.mBoard);
return;
}
}
}
//Print the board (for debug purposes)
void printBoard()
{
for (int i = 0; i < 9; ++i)
{
for (int j = 0; j < 9; ++j)
cout << mBoard[i][j] << " ";
cout << endl;
}
cout << endl;
char s[5];
cin >> s;
}
};
int main(int argc, char **argv)
{
//char filename[42];
//cout << "Enter filename: ";
//cin >> filename;
char *filename = argv[1];
Sudoku s(filename);
if (!s.solve())
error("Couldn't solve!");
cout << "Solved! Here's the solution:" << endl << endl;
for (int i = 0; i < 9; ++i)
{
for (int j = 0; j < 9; ++j)
cout << s.mBoard[i][j] << " ";
cout << endl;
}
return 0;
}
(包含行号的代码:http://sprunge.us/AiUc?cpp)
现在我明白它不是很好的风格,但它来自一个深夜的编码 session ,而且我们在学校实验室使用了一个旧的编译器,所以我不得不做一些不同的事情(在那个编译器中,标准 header 具有“.h”扩展名,for 循环中声明的变量在外部 for 范围内,...)。
文件应包含棋盘中每个位置的空白分隔数字,从左上角到左到右,从上到下,空白点用“0”表示。
对于以下文件,它工作得相当好:
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 6 0
8 0 0 0 6 0 0 0 3
4 0 0 8 0 3 0 0 1
7 0 0 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
但是,这个给它带来了麻烦:
0 9 4 0 0 0 1 3 0
0 0 0 0 0 0 0 0 0
0 0 0 0 7 6 0 0 2
0 8 0 0 1 0 0 0 0
0 3 2 0 0 0 0 0 0
0 0 0 2 0 0 0 6 0
0 0 0 0 5 0 4 0 0
0 0 0 0 0 8 0 0 7
0 0 6 3 0 4 0 0 8
如果我注释掉打印语句并跟踪进度,我可以看到它开始时在某些地方朝错误的方向前进。最终它会卡在最后,回溯永远不会回得足够远。我认为“checkOnlyAllowed”部分有问题...
您认为可能是什么问题?
此外 - 我知道我可以为“mAllowed”表使用位域,但我们在学校还没有正式了解按位运算。 :P
最佳答案
在第 170 行,您有一个 goto 跳出 for 循环,然后继续。这可能会给您带来一些奇怪的行为,继续错误的循环,这些行为可能取决于特定的编译器。
尝试将第 164-177 行替换为:
164 for (;;)
165 {
166 bool successfullyContributedToTheBoard = false;
167 for (int i = 0; i < 9; ++i)
168 for (int j = 0; j < 9; ++j)
169 if (!mBoard[i][j])
170 if (trySinglePoint(i, j))
171 successfullyContributedToTheBoard = true;
172 if (!successfullyContributedToTheBoard)
173 return;
174 }
关于c++ - 数独解算器由于某种原因不断卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3733191/
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!