This commit is contained in:
hairrrrr
2020-04-07 20:17:52 +08:00
parent 0f78eed4fe
commit ab2e829f6d
7 changed files with 460 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
#include<stdio.h>
#include<stdbool.h>
bool is_prime(int n) {
int divisor;
if (n <= 1)
return false;
for (divisor = 2; divisor * divisor <= n; divisor++) {
if (n % divisor == 0)
return false;
}
return true;
}
int main(void) {
int n;
printf("Enter a number: ");
scanf("%d", &n);
if (is_prime(n))
printf("Prime\n");
else
printf("Not Prime\n");
return 0;
}

View File

@@ -0,0 +1,10 @@
#### 程序:判断素数
编写程序提示用户录入数,然后给出一条信息说明此数是否为素数。
```c
Enter a number: 24
Not prime
```
把判断素数的实现写到另外一个函数中,此函数返回值为 true 就表示是素数,返回 false 表示不是素数。

View File

@@ -0,0 +1,74 @@
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX_NUMBER 100
int secret_number;// 要猜的数
void generate_secret_number();// 随机数生成
void read_guesses(); // 猜的实现
int main(void) {
char command;
printf("Guess the secret number between 1 and 100.\n");
do {
generate_secret_number();
printf("A new number has been chosen.\n");
read_guesses();
printf("Play again?(Y/N)");
scanf(" %c", &command);// 注意 %c 前的空格,这很重要
printf("\n");
} while (command == 'y' || command == 'Y');
return 0;
}
// 可以用这样的注释将函数的功能写在函数的定义的上方
// 我个人比较喜欢将简单的注释写在函数原型处
/****************************************************************************
*
* generate_secret_number: Initilizes the random number generator using the
* time of day.Randomly selects a number between
* 1 and MAX_NUMBER and stores it in secret_number
*
*****************************************************************************/
void generate_secret_number() {
srand((unsigned)time(NULL));
secret_number = rand() % MAX_NUMBER + 1;
}
/*****************************************************************
*
* read_guessesRepeatedly reads user guesses and gives hints
* When guess is right,prints the total number of
* guesses and returns
*
******************************************************************/
void read_guesses() {
int guess, count = 0;
for (;;) {
printf("Enter guess: ");
scanf("%d", &guess);
count++;
if (guess > secret_number) {
printf("Too high; try again\n");
}
else if (guess < secret_number) {
printf("Too low; try again.\n");
}
else {
printf("You won in %d guesses!\n\n", count);
return;
}
}

View File

@@ -0,0 +1,59 @@
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX_NUMBER 100
int generate_secret_number();// Ëæ»úÊýÉú³É
void read_guesses(int secret_number); // ²ÂµÄʵÏÖ
int main(void) {
char command;
int secret_number;
printf("Guess the secret number between 1 and 100.\n");
do {
secret_number = generate_secret_number();
printf("A new number has been chosen.\n");
read_guesses(secret_number);
printf("Play again?(Y/N)");
scanf(" %c", &command);
printf("\n");
} while (command == 'y' || command == 'Y');
return 0;
}
int generate_secret_number() {
srand((unsigned)time(NULL));
int secret_number = rand() % MAX_NUMBER + 1;
return secret_number;
}
void read_guesses(int secret_number) {
int guess, count = 0;
for (;;) {
printf("Enter guess: ");
scanf("%d", &guess);
count++;
if (guess > secret_number) {
printf("Too high; try again\n");
}
else if (guess < secret_number) {
printf("Too low; try again.\n");
}
else {
printf("You won in %d guesses!\n\n", count);
return;
}
}
}

View File

@@ -0,0 +1,19 @@
#### 程序:猜数
程序产生一个 1 ~ 100 的随机数,用户尝试用尽可能少的次数猜出这个数。程序运行如下:
```c
Guess the secret number between 1 and 100.
A new number has been chosen.
Enter guess:55
Too low; try again.
Enter guess:65
Too high; try again.
Enter guess: 60
You won in 3 guesses!
Play again?(Y/N) n
```
使用两种方法:使用全局变量/不使用全局变量

View File

@@ -0,0 +1,209 @@
/*
* 程序难点思路:
* 1为了判定手中的牌是否重复我们需要一个布尔类型数组存储整副牌初始化整个数组为 false。如果一张牌已经在我们手上那么我们将数组对应的元素置为 true
* 2用两个分别数组来存储每个点数和花色的个数这样方便我们后面判断牌的类型
* 38 种牌的类型,我们可拆成 同花顺子4张3张对子值为 012这五种基础类型的组合。
*
* 程序结构:
* 通过上面的分析,我们发现:这个程序需要 3 个数组和 5 个变量,如果都作为函数参数传参,显得有些笨。
* 而且,前面我们说过,函数只能返回一个值,那如果要将函数分离, 5 种基础类型就得放进数组;或者使用指针,而指针我们没有学习,而且指针还是逃不开传参
* 这样一分析,貌似使用全局变量是最好的做法了。对于初学者来说,这样可能确实是最好的。
* 但是,使用大量的全局变量是很不好的习惯,我不能让自己去写这样的代码。我认为:宁可这道题不做,也不能有坏的代码风格去写!
* 后面我们会学习自定义类型:结构体,它可能是这种问题最好的解决方法。
*
* 下面是这个问题的 4 种解决方法:
* 1)应用全局变量
* 2应用指针作为函数参数
* 3将判断卡牌类型的函数与打印函数合并
* 4使用结构体
*
* 在这里,我坚持使用结构体来解决这类问题。全局变量大家只要知道概念即可,对于这道题来说,比起方法,可能设计程序的模块化思路更值得学习。
* 即使使用结构体,程序的主要逻辑也不会变。如果你非要用全局变量写,那你可以改写一下。
*/
#include<stdio.h>
#include<stdbool.h>
#define RANK 13
#define SUIT 4
#define CARD 5
typedef struct CardType {
bool flush; //同花
bool straight; //顺子
bool four; //四张
bool three; //三张
int pair; // 对子
// 0 表示不是 1 表示 1个对子 2 表示两个对子
bool cardInHand[SUIT][RANK]; // 判断此牌是否已在手中
int numRank[RANK]; // 每个点数的个数
int numSuit[SUIT]; // 每个花色的个数
}CardType;
void initCardType(CardType* card); // 初始化
void readCard(CardType* card); // 读取输入
void analyseCard(CardType* card); // 分析手牌
void printResult(CardType* card); //打印结果
int main(void) {
CardType card;
for (; ;) {
initCardType(&card);
readCard(&card);
analyseCard(&card);
printResult(&card);
}
return 0;
}
void initCardType(CardType* card) {
card->flush = false;
card->straight = false;
card->four = false;
card->three = false;
card->pair = 0;
int i, j;
for (i = 0; i < SUIT; i++) {
card->numSuit[i] = 0;
for (j = 0; j < RANK; j++) {
card->cardInHand[i][j] = false;
}
}
for (i = 0; i < RANK; i++) {
card->numRank[i] = 0;
}
}
void readCard(CardType* card) {
int card_read = CARD, rank, suit;
bool bad_card;
char ch;
while (card_read) {
bad_card = false; // 不要忘记重置坏牌的标记
printf("Enter a card : ");
// 判断点数
ch = getchar();
switch (ch) {
case '0': exit(0); break;
case '2': rank = 0; break;
case '3': rank = 1; break;
case '4': rank = 2; break;
case '5': rank = 3; break;
case '6': rank = 4; break;
case '7': rank = 5; break;
case '8': rank = 6; break;
case '9': rank = 7; break;
case 't':case 'T': rank = 8; break;
case 'j':case 'J': rank = 9; break;
case 'q':case 'Q': rank = 10; break;
case 'k':case 'K': rank = 11; break;
case 'a':case 'A': rank = 12; break;
default:bad_card = true; break;
}
ch = getchar();
switch (ch) {
case 'c': case 'C': suit = 0; break;
case 'd': case 'D': suit = 1; break;
case 'h': case 'H': suit = 2; break;
case 's': case 'S': suit = 3; break;
default: bad_card = true; break;
}
// 精华 1
// 检测输入是否多于两个字符
while ((ch = getchar()) != '\n') {
if (ch != ' ')
bad_card = true;
}
if (bad_card)
printf("Bad card; ignored.\n");
else if (card->cardInHand[suit][rank])
printf("Duplicated card; ignored.\n");
else {
++card->numRank[rank];
++card->numSuit[suit];
card->cardInHand[suit][rank] = true;
card_read--;
}
}
}
void analyseCard(CardType* card) {
int i, count;
// 同花是五张牌相同花色
for (i = 0; i < SUIT; i++) {
if (card->numSuit[i] == 5)
card->flush = true;
}
// 精华 2
// 顺子是五张连续的牌,中间不能隔断
i = 0;
// 找到数组种第一张存在的牌
while (card->numRank[i] == 0)
i++;
count = 0;
for (; i < RANK && card->numRank[i] != 0; i++) {
count++;
}
// 顺子必须是五张
if (count == CARD) {
card->straight = true;
return; // 顺子肯定不是对子
}
for (i = 0; i < RANK; i++) {
if (card->numRank[i] == 4)
card->four = true;
if (card->numRank[i] == 3)
card->three = true;
if (card->numRank[i] == 2)
++card->pair;
}
}
void printResult(CardType* card) {
if (card->flush && card->straight)
printf("Stright flush\n");
else if (card->four)
printf("Four of a kind\n");
else if (card->three && card->pair == 1)
printf("Full house\n");
else if (card->flush)
printf("flush\n");
else if (card->straight)
printf("straight\n");
else if (card->three)
printf("Three of a kind\n");
else if (card->pair == 2)
printf("Two pairs\n");
else if (card->pair == 1)
printf("pair\n");
else
printf("High card\n");
printf("\n\n");
}

View File

@@ -0,0 +1,56 @@
#### 程序:手牌分类
编写程序对手牌进行读取和分类。手中的每张牌都有花色方块梅花红桃和黑桃和等级23456789TJQK 和 A。不允许使用王牌并且假设 A 是最高等级的。一手 5 张牌,然后把手中的牌分为下列某一类(列出的顺序从好到坏)。
- 同花顺(顺序连续且同花色)
- 四张4 张牌等级相同)
- 葫芦3 张牌等级一样另外2 张等级一样)
- 同花5 张牌同花色)
- 顺子5 张牌等级顺序连续)
- 三张3 张牌等级连续)
- 两对
- 一对2 张牌等级一样)
- 其他牌
如果一手牌可以分为两种或多种类别,程序将选择最好的一种。
为了便于输入,将牌的等级和花色简化如下:
- 等级: 23456789TJQK A
- 花色c d h s
如果用户输入非法牌或者输入同一张牌两次,程序将此牌忽略掉,产生错误信息,然后要求输入另一张牌。如果输入为 0 而不是一张牌,就会导致程序终止。
与程序的会话如下:
```c
Enter a card : 2s
Enter a card : 5s
Enter a card : 4s
Enter a card : 3s
Enter a card : 6s
Straight flush
Enter a card : 8c
Enter a card : as
Enter a card : 8c
Duplicated card; ignored.
Enter a card : 7c
Enter a card : ad
Enter a card : 3h
Pair
Enter a card : 6s
Enter a card : d2
Bad card; ignored.
Enter a card : 2d
Enter a card : 9c
Enter a card : 4h
Enter a card : ts
High card
Enter a card: 0
```