【数据结构】---发纸牌、八皇后问题、memset出现的错误

  • 发纸牌问题

PlayCard.h

#pragma once
#include <iostream>
#include <cstring>
#include <ctime>

using namespace std;

int sign[4][13] = { 0 };
string str1[4] = { "梅花", "黑桃", "红桃", "方块" };
string str2[13] = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" };

class PlayCard
{
public:
	PlayCard();
	~PlayCard();
	void SendCards(int n);
	void PrintCards();

private:
	string card[13];//最多发13张牌
	int num;//发牌张数
};

PlayCard::PlayCard()
{
	this->num = 0;
}

PlayCard::~PlayCard()
{

}

void PlayCard::SendCards(int n)
{
	int count1, count2;
	this->num = n;//没有这一步打印不出来数据
	srand(time(nullptr));//初始化随机种子为当前系统时间
	memset(sign, 0, n);//初始化标志数组,所有牌均为发出
	for (int i = 0; i < n;)
	{
		count1 = rand() % 4;//0~3
		count2 = rand() % 13;//0~12
		if (sign[count1][count2] == 1)//这张牌已经发出
		{
			continue;//跳过循环体余下语句,注意k的值不变
		}
		else
		{
			card[i] = str1[count1] + str2[count2];//连接str1和str2
			sign[count1][count2] = 1;//标识这张牌已经发出
			i++;//满足不是重复的情况下再计数器叠加
		}
	}
}

void PlayCard::PrintCards()
{
	for (int i = 0; i < this->num; i++)
	{
		cout << this->card[i] << endl;
	}
}

发纸牌问题.cpp

#include "Playcard.h"

int main()
{
	int n;
	PlayCard p;
	cout << "请输入要发牌的张数:";
	cin >> n;
	p.SendCards(n);
	p.PrintCards();

	return 0;
}

  • 八皇后问题

在这里插入图片描述

在这里插入图片描述
重点在坐标的关系k行x[k]列, 还有皇后必须满足的约束条件

#include <iostream>
#include <cstring>

using namespace std;

class Queen
{
public:
	Queen(int n);
	~Queen();
	void SetQueen();//填写n皇后
	void PrintQueen();//打印皇后位置

private:
	int Place(int k);//判断皇后k是否发生冲突
	int* x;//皇后位置
	int num;//皇后个数
};

Queen::Queen(int n)
{
	x = new int[n];
//	fill(x, x + n, -1);
//	memset(x, -1, n);
/*
你提到的问题是关于使用 memset 初始化动态分配的数组的正确性。
确实,memset 函数并不适用于初始化动态分配的数组,因为它只能对连续内存块进行填充。
在这种情况下,我们需要使用其他方法来初始化动态分配的数组。
*/
	for (int i = 0; i < n; i++)//初始化数组为-1
	{
		x[i] = -1;
	}
	num = n;
}

Queen::~Queen()
{
	delete[] x;
}

void Queen::SetQueen()
{
	int k = 0, count = 0;

	while (k >= 0)
	{
		x[k]++;
		while (x[k] < num && Place(k) == 1)
		{
			x[k]++;//皇后k试探下一列
		}

		//k == num - 1表示是最后一个皇后 x[k] < num表示列在格子范围内
		if (x[k] < num && k == num - 1)
		{
			count++;
			cout << "第" << count << "个解是:";
			PrintQueen();
		}
		else if (k < num -1 && x[k] < num)//尚有皇后未摆放
		{
			k += 1;
		}
		else
		{
			//重置x[k],回溯,重新摆放皇后k
			x[k] = -1;
			k--;
		}
	}
}

void Queen::PrintQueen()
{
	for (int i = 0; i < num; i++)
	{
		cout << x[i] + 1 << "\t";
	}
	cout << endl;
}

int Queen::Place(int k)
{
	for (int i = 0; i < k; i++)
	{
		//判断是否冲突的标志是|行-行| != |列-列|
		if (abs(i - k) == abs(x[i] - x[k]) || x[i] == x[k])
		{
			return 1;//冲突的标志
		}
	}
	return 0;
}

int main()
{
	int n;
	cout << "请输入皇后的个数(n>=4):";
	cin >> n;
	Queen Q(n);
	Q.SetQueen();

	return 0;
}

你提到的问题是关于使用 memset 初始化动态分配的数组的正确性。
确实,memset 函数并不适用于初始化动态分配的数组,因为它只能对连续内存块进行填充。
在这种情况下,我们需要使用其他方法来初始化动态分配的数组。
解决办法:for循环、fill函数(代码注释中已实现)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值