C语言探索之旅 | 第二部分第十课: 实战悬挂小人游戏答案

本文主要是介绍C语言探索之旅 | 第二部分第十课: 实战悬挂小人游戏答案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

作者 谢恩铭,公众号「程序员联盟」(微信号:coderhub)。
转载请注明出处。
原文:https://www.jianshu.com/p/b239b1774f4b

《C语言探索之旅》全系列

内容简介


  1. 前言
  2. 解方(1. 游戏的代码)
  3. 解方(2. 词库的代码)
  4. 第二部分第十一课预告

1. 前言


经过上一课 C语言探索之旅 | 第二部分第九课: 实战"悬挂小人"游戏 之后,相信大家都或多或少都写了自己的“悬挂小人”的游戏代码吧。

这一课我们就来"终结"这个游戏吧 (听着怎么有点吓人…)。

"Yes, you are terminated."

2. 解方(1. 游戏的代码)


如果你开始阅读这里,说明:

  • 或者你写完了游戏,想来看看我们怎么写。
  • 或者你没完成这个游戏,想来看看怎么写。

不管你是哪种情况,我都会介绍一下如何来完成这个游戏。

“说不说在我,听不听在您”~

事实上,我自己花了比想象中更多的时间来完成这游戏。

人生总是这样的,“理想丰满,现实骨感;看似美满,人艰不拆”。

但是,我还是坚信大家是有能力独自完成这个小游戏的(如果你认真学习了之前的 C语言课程),可以去查阅网上资料,花点时间(几十分钟,几小时,几天?),这并不是一次竞赛,所以不用着急。

我更希望您花了不少时间,最终实现了这个游戏; 比之您只花 5 分钟,然后就来看答案要好很多。

千万不要觉得我是一蹴而就写成这个游戏的,这个游戏虽小,但也还没简单到可以在脑中构思好一切,然后“下笔如有神”: 我也是一步步写出来的。

我们将会分 2 步来介绍我们的解方:

  1. 首先我们会演示如何一步步写游戏的主体部分,一开始我们会只有一个猜测的单词,而且是固定的;我选了 BOTTLE(表示“瓶子”),因为我们要测试对于单词中有大于等于两个相同字母的情况是否处理正确了(BOTTLE 中有 2 个 T)。

  2. 然后我们会演示如何加入词库的处理程序,以便每一轮游戏可以从词库中随机抽取一个单词。

牢记:重要的不是结果,而是我们思考的方式和过程。

分析 main 函数


大家都知道,我们的 C语言程序都是由 main 函数作为入口的。

我们也不要忘了引入一些标准库的头文件:stdio.h,stdlib.h,ctype.h(为了 toupper 函数)。

因此,我们的程序一开始会是这样的:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>int main(int argc, char* argv[])
{return 0;
}

是不是很简单啊,慢慢来么。

我们的 main 函数将控制游戏的大部分运作,并且调用我们将要写的不少函数。

我们来声明一些必要的变量吧。这些变量也不是一次就能全部想到的,都是写一点,想到一些。“罗马不是一日建成的, 小人也不是一日能悬挂完的”。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>int main(int argc, char* argv[])
{char letter = 0;  // 存储用户输入的字母char secretWord[] = "BOTTLE";  // 要猜测的单词int letterFound[6] = {0};  // 布尔值的数组。数组的每一个元素对应猜测单词的一个字母。0 = 还没猜到此字母, 1 = 已猜到字母int leftTimes = 7;  // 剩余猜测次数(0 = 失败)int i = 0;  // 为了遍历数组,需要一个下标return 0;
}

上述的变量中,起到关键作用的就是 letterFound 这个 int 型数组了。这个数组用于表示猜测的单词中哪些字母已经猜到,哪些还没猜到。

一开始,我们实现得简单些:我们的单词 BOTTLE 有 6 个字母,因此我们的数组就固定是 6 个元素的数组。

如果元素为 0,表示对应的那个字母还没猜到;如果为 1,则表示已猜到。随着游戏的进行,这个数组的元素值会被修改。

例如,如果当下我们玩游戏直到:

B*TT*E

那么,letterFound 这个数组的值应该是这样:

101101

之后我们要测试游戏的一轮是否已经胜利也就比较简单了:只需要测试 letterFound 数组的所有元素是否都等于 1。

我们就来写判断一轮是否胜利的函数吧,取名为 win(表示 “胜利”)好了。

int win(int letterFound[])
{int i = 0;int win = 1;  // 1 为胜利,0 为失败for (i = 0 ; i < 6 ; i++){if (letterFound[i] == 0)win = 0;}return win;
}

可以看到,我们的 win 函数的参数是一个 int 型数组,我们在 main 函数中调用 win 函数时,会将我们的 letterFound 数组传给它。

这个函数很简单:遍历数组,只要还有一个元素为 0,那游戏还没胜利;如果所有元素都为 1,则游戏胜利。

为了与此函数搭配,我们还需要写一个函数,起名叫 researchLetter,这个函数将有两个功能:

  1. 返回一个布尔值(在 C语言里用 int 型表示),用于表示所猜的字母是否存在于单词中。

  2. 更新 letterFound 数组的元素,如果所猜的字母在单词中,那么就把对应的元素值修改为 1。

int researchLetter(char letter, char secretWord[], int letterFound[])
{int i = 0;int correctLetter = 0;  // 0 表示字母不在单词里,1 表示字母在单词里// 遍历单词数组 secretWord,以判断所猜字母是否在单词中for (i = 0 ; secretWord[i] != '\0' ; i++){if (letter == secretWord[i])  // 如果字母在单词中{correctLetter = 1;  // 表示猜对了一个字母letterFound[i] = 1;  // 对于所有等于所猜字母的数组位置,都使其数值变为 1}}return correctLetter;
}

researchLetter 这个函数的好处还在于:不会在找到第一个存在的字母后就停止,而会继续查找,所以对于像 BOTTLE 这样有两个字母相同的单词就可以一次揭示两个 T 了。

好,写完这两个函数(放在 main 函数后面),我们继续写我们的 main 函数。我们添加一句欢迎词:

printf("欢迎来到悬挂小人游戏!\n");

然后添加一个主循环,是一个 while 循环:

while (leftTimes > 0 && !win(letterFound))
{
}

每轮游戏在 leftTimes(剩余猜测机会)大于 0 并且还没胜利的情况下,是不会停止的。

  • 如果剩余次数为 0,则本轮游戏失败。
  • 如果胜利,那本轮就赢了。

在这两种情况下,都要停止游戏。

我们在 while 循环里添加如下代码:

printf("\n\n您还剩 %d 次机会", leftTimes);
printf("\n神秘单词是什么呢 ? ");/* 我们显示猜测的单词,将还没猜到的字母用*表示例如 : *O**LE */
for (i = 0 ; i < 6 ; i++)
{if (letterFound[i])  // 如果第 i+1 个字母已经猜到printf("%c", secretWord[i]);  // 打印出来elseprintf("*");  // 还没猜到,打印一个星号 *
}

上面的代码用于:

  • 打印剩余机会数。
  • 打印单词(其中还没猜到的字母用星号 * 表示)。

接下来,我们写请求用户输入一个字母的代码:

printf("\n输入一个字母 : ");
letter = readCharacter();

还记得我们之前写的函数 readCharacter 吗?它用于读取用户的第一个输入的字母,读到回车符结束,而且它会把该字母转成大写。

// 如果用户输入的字母不存在于单词中
if (!researchLetter(letter, secretWord, letterFound))
{leftTimes--;  // 将剩余猜测机会数减 1
}

以上代码调用 researchLetter 函数在单词中查找用户输入的字母,如果没找到,则剩余猜测机会数扣除一次。

如果字母存在于单词中,则 researchLetter 函数还会更新 letterFound 数组(每个元素对应了神秘单词的每一个字母的猜测情况),将其中对应的 0(还没猜到)改为 1(已经猜到)。

这样,win 函数在判断的时候,如果 letterFound 数组的每一个元素都为 1,则返回 1,表示本轮胜利,猜到单词的全部字母了。

暂时,while 循环体的内容就到这里了,然后我们还要写跳出 while 循环之后的代码(或者胜利或者失败):

if (win(letterFound))printf("\n\n胜利了! 神秘单词是 : %s\n", secretWord);
elseprintf("\n\n失败了! 神秘单词是 : %s\n", secretWord);

游戏主体部分的代码就到这里了,给出我们到目前为止的完整程序:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>int win(int letterFound[]);
int researchLetter(char letter, char secretWord[], int letterFound[]);
char readCharacter();int main(int argc, char* argv[])
{char letter = 0;  // 存储用户输入的字母char secretWord[] = "BOTTLE";  // 要猜测的单词int letterFound[6] = {0};  // 布尔值的数组。数组的每一个元素对应猜测单词的一个字母。0 = 还没猜到此字母,1 = 已猜到字母int leftTimes = 7;  // 剩余猜测次数(0 = 失败)int i = 0;  // 为了遍历数组,需要一个下标printf("欢迎来到悬挂小人游戏!\n");while (leftTimes > 0 && !win(letterFound)){printf("\n\n您还剩 %d 次机会", leftTimes);printf("\n神秘单词是什么呢 ? ");/* 我们显示猜测的单词,将还没猜到的字母用 * 表示例如 : *O**LE */for (i = 0 ; i < 6 ; i++){if (letterFound[i])  // 如果第 i+1 个字母已经猜到printf("%c", secretWord[i]);  // 打印出来elseprintf("*");  // 还没猜到,打印一个*}printf("\n输入一个字母 : ");letter = readCharacter();// 如果用户输入的字母不存在于单词中if (!researchLetter(letter, secretWord, letterFound)){leftTimes--;  // 将剩余猜测机会数减 1}}if (win(letterFound))printf("\n\n胜利了! 神秘单词是 : %s\n", secretWord);elseprintf("\n\n失败了! 神秘单词是 : %s\n", secretWord);return 0;
}int win(int letterFound[])
{int i = 0;int win = 1;  // 1 为胜利,0 为失败for (i = 0 ; i < 6 ; i++){if (letterFound[i] == 0)win = 0;}return win;
}int researchLetter(char letter, char secretWord[], int letterFound[])
{int i = 0;int correctLetter = 0;  // 0 表示字母不在单词里,1 表示字母在单词里// 遍历单词数组 secretWord,以判断所猜字母是否在单词中for (i = 0 ; secretWord[i] != '\0' ; i++){if (letter == secretWord[i])  // 如果字母在单词中{correctLetter = 1;  // 表示猜对了一个字母letterFound[i] = 1; // 对于所有等于所猜字母的数组位置,都将其数值变为1}}return correctLetter;
}char readCharacter()
{char character = 0;character = getchar();  // 读取一个字母character = toupper(character);  // 把这个字母转成大写// 读取其他的字符,直到 \n(为了忽略它)while (getchar() != '\n');return character;  // 返回读到的第一个字母
}

这一部分的程序,你可以将其存放在一个 .c 文件中,例如叫 hangman.c。

然后用 gcc 编译(如果是在 IDE 里面,例如 CodeBlocks,那直接点击编译运行):

gcc hangman.c -o hangman

运行:

./hangman

接下来我们要开始第二部分:词库的代码

根据这部分的代码,我们还会接着修改和添加 main 函数的内容。

好吧,稍作休息,继续前进!

3. 解方(2. 词库的代码)


我们已经编写了游戏主体部分的基本代码,但是我们的游戏目前还不能做到每轮随机抽取一个单词。

因此,接下来我们就带大家编写处理词库的代码。

首先,我们需要创建一个文件,用于存放所有的单词。

在 Linux / Unix / macOS 操作系统下,我们都可以直接创建一个不带后缀名的文件。在 Windows 下可以创建 .txt 结尾的文本文件。

我写这个游戏是在 Linux 系统下,所以直接用 Vim 或 Emacs 或其他编辑器创建一个文件, 位于我们源文件的相同目录下:dictionary。

在里面写入以下单词(每行一个,用回车符隔开):

YOU
MOTHER
LOVE
PANDA
BOTTLE
FUNNY
HONEY
LIKE
JAZZ
MUSIC
BREAD
APPLE
WATER
PEOPLE
DOG
CAT
GLASS
SKY
GOD
ZERO

当然了,我这里只是举个例子,你可以创建属于自己的词库。

新建两个文件


处理这个文件的代码将会不少(至少,我是这么预感的),因此,我们新建一个 .c 源文件,可以命名为 dictionary.c。

顺便,我们也创建 dictionary.h 这个头文件,其中存放 dictionary.c 中的函数的原型,这样我们在 main 函数里就可以通过

#include "dictionary.h"

来引入这些函数的定义了。

在 dictionary.c 中,首先我们引入一些头文件:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>  // 我们需要这里面的随机数函数,还记得我们的第一个小游戏“或多或少”吗? 
#include <string.h>  // 我们需要 strlen 这个计算字符串长度的函数#include "dictionary.h"

chooseWord 函数


这个函数用于从文件 dictionary 中随机选取一个单词,此函数只有一个参数: 指向内存中可以写入单词的地址的指针,这个指针实参将由 main 函数提供。

函数返回值是 int 变量:1 表示一切顺利;0 表示出现错误。

此函数的开头是这样:

int chooseWord(char *wordChosen)
{FILE* dictionary = NULL;  // 指向我们的文件 dictionary(词库)的文件指针int wordNum = 0;  // 词库中单词总数int chosenWordNum = 0;  // 选中的单词编号int i = 0;  // 下标int characterRead = 0;  // 读入的字符
}

声明了一些变量,我们接着写:

dictionary = fopen("dictionary", "r");  // 以只读模式打开词库(dictionary 文件)if (dictionary == NULL)  // 如果打开文件不成功
{printf("\n无法装载词库\n");return 0;  // 返回 0 表示出错
}

这段代码不难吧,就是尝试打开词库(dictionary 文件),并检测 dictionary 文件指针是否为 NULL。

如果为 NULL,表示打开失败。如果打开文件失败,则程序中止,因为没有进行下去的必要了。

// 统计词库中的单词总数,也就是统计回车符 `\n` 的数目
do
{characterRead = fgetc(dictionary);if (characterRead == '\n')wordNum++;
} while (characterRead != EOF);

上面这段代码中,我们借助 fgetc 函数遍历整个文件(一个字符一个字符读取)。

我们统计读到的回车符(\n)的数目,每读到一个 \n,我们对 wordNum(单词总数)的值加 1。

我们通过以上代码,就可以知道词库中的单词总数了,就是 wordNum 的值。

然后,我们需要一个函数,根据 wordNum 的值计算一个伪随机数出来,作为随机选取的单词编号,我们就来写一个函数,命名为:randomNum。

randomNum 函数


此函数里的代码我们之前编写第一个 C语言小游戏: “或多或少” 时已经用过了,就是简单的伪随机数生成。

作用:用于返回一个介于 0 ~ (单词总数 - 1) 之间的随机数。

int randomNum(int maxNum)
{srand(time(NULL));return (rand() % maxNum);
}

写好了 randomNum 函数,我们立即来使用它:

chosenWordNum = randomNum(wordNum);  // 随机选取一个单词(编号)

接着,我们需要重新回到文件开始处来进行读取,为了回到文件开始处,可以调用函数 rewind。

// 我们重新从文件开始处读取(rewind 函数),直到遇到选中的那个单词
rewind(dictionary);while (chosenWordNum > 0)
{characterRead = fgetc(dictionary);if (characterRead == '\n')chosenWordNum--;
}/* 文件指针已经指向正确位置,我们就用fgets来读取那一行(也就是那个选中的单词)*/
fgets(wordChosen, 100, dictionary);// 放置 \0 字符用于表示字符串结束
wordChosen[strlen(wordChosen) - 1] = '\0';fclose(dictionary);return 1; // 一切顺利,返回1

dictionary.h 文件


其中包含我们的 dictionary.c 中的函数原型,内容如下:

#ifndef DICTIONARY_H
#define DICTIONARY_Hint chooseWord(char *wordChosen);
int randomNum(int maxNum);#endif

完整的 dictionary.c 文件

/*
悬挂小人游戏dictionary.c
------------这里定义了两个函数:1. chooseWord 用于每轮从 dictionary 文件中随机抽取一个单词
2. randomNum 用于返回一个介于 0 ~ (单词总数 - 1) 之间的随机数*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>#include "dictionary.h"int chooseWord(char *wordChosen)
{FILE* dictionary = NULL;  // 指向我们的文件 dictionary 的文件指针int wordNum = 0;  // 单词总数int chosenWordNum = 0;  // 选中的单词编号int i = 0;  // 下标int characterRead = 0;  // 读入的字符dictionary = fopen("dictionary", "r");  // 以只读模式打开词库(dictionary 文件)if (dictionary == NULL)  // 如果打开文件不成功{printf("\n无法装载词库\n");return 0;  // 返回 0 表示出错}// 统计词库中的单词总数,也就是统计回车符 \n 的数目do{characterRead = fgetc(dictionary);if (characterRead == '\n')wordNum++;} while (characterRead != EOF);chosenWordNum = randomNum(wordNum);  // 随机选取一个单词(编号)// 我们重新从文件开始处读取(rewind 函数),直到遇到选中的那个单词rewind(dictionary);while (chosenWordNum > 0){characterRead = fgetc(dictionary);if (characterRead == '\n')chosenWordNum--;}/* 文件指针已经指向正确位置,我们就用fgets来读取那一行(也就是那个选中的单词)*/fgets(wordChosen, 100, dictionary);// 放置 \0 字符用于表示字符串结束wordChosen[strlen(wordChosen) - 1] = '\0';fclose(dictionary);return 1; // 一切顺利,返回1
}int randomNum(int maxNum)
{srand(time(NULL));return (rand() % maxNum);
}

修改 hangman.c 文件


现在,既然我们的处理词库的函数已经写完了,也就是在 dictionary.c 中,那么我们需要相应地修改我们的 hangman.c 文件中的 main 函数和其他几个子函数:

有了之前所有课程的知识,靠着注释,应该不难看懂。

完整的 hangman.c 文件

/*
悬挂小人游戏main.c
------------游戏的主体代码
*/#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>#include "dictionary.h"int win(int letterFound[], long wordSize);
int researchLetter(char letter, char secretWord[], int letterFound[]);
char readCharacter();int main(int argc, char* argv[])
{char letter = 0;  // 存储用户输入的字母char secretWord[100] = {0};  // 要猜测的单词int *letterFound = NULL;  // 布尔值的数组. 数组的每一个元素对应猜测单词的一个字母。0 = 还没猜到此字母, 1 = 已猜到字母int leftTimes = 7;  // 剩余猜测次数 (0 = 失败)int i = 0;  // 下标long wordSize = 0;  // 单词的长度(字母数目)printf("欢迎来到悬挂小人游戏!\n");// 从词库(文件 dictionary)中随机选取一个单词if (!chooseWord(secretWord))exit(0); // 退出游戏// 获取单词的长度wordSize = strlen(secretWord);letterFound = malloc(wordSize * sizeof(int));  // 动态分配数组的大小,因为我们一开始不知道单词长度if (letterFound == NULL)exit(0);// 初始化布尔值数组,都置为 0,表示还没有字母被猜到for (i = 0 ; i < wordSize ; i++)letterFound[i] = 0;// 主while循环,如果还有猜测机会并且还没胜利,继续while (leftTimes > 0 && !win(letterFound, wordSize)){printf("\n\n您还剩 %d 次机会", leftTimes);printf("\n神秘单词是什么呢 ? ");/* 我们显示猜测的单词,将还没猜到的字母用*表示例如 : *O**LE */for (i = 0 ; i < wordSize ; i++){if (letterFound[i])  // 如果第 i+1 个字母已经猜到printf("%c", secretWord[i]); // 打印出来elseprintf("*"); // 还没猜到,打印一个*}printf("\n输入一个字母 : ");letter = readCharacter();// 如果用户输入的字母不存在于单词中if (!researchLetter(letter, secretWord, letterFound)){leftTimes--; // 将剩余猜测机会数减 1}}if (win(letterFound, wordSize))printf("\n\n胜利了! 神秘单词是 : %s\n", secretWord);elseprintf("\n\n失败了! 神秘单词是 : %s\n", secretWord);return 0;
}// 判断是否胜利
int win(int letterFound[], long wordSize)
{int i = 0;int win = 1;  // 1 为胜利,0 为失败for (i = 0 ; i < wordSize ; i++){if (letterFound[i] == 0)win = 0;}return win;
}// 在所要猜的单词中查找用户输入的字母
int researchLetter(char letter, char secretWord[], int letterFound[])
{int i = 0;int correctLetter = 0;  // 0 表示字母不在单词里,1 表示字母在单词里// 遍历单词数组 secretWord,以判断所猜字母是否在单词中for (i = 0 ; secretWord[i] != '\0' ; i++){if (letter == secretWord[i])  // 如果字母在单词中{correctLetter = 1;  // 表示猜对了一个字母letterFound[i] = 1;  // 对于所有等于所猜字母的数组位置,都将其数值变为1}}return correctLetter;
}char readCharacter()
{char character = 0;character = getchar();  // 读取一个字母character = toupper(character);  // 把这个字母转成大写// 读取其他的字符,直到 \n (为了忽略它)while (getchar() != '\n');return character; // 返回读到的第一个字母
}

好了,这个小游戏已经写完了,用 gcc 编译并运行看看吧!

gcc dictionary.c hangman.c -o hangman

然后:

./hangman

4. 第二部分第十一课预告


今天的课就到这里,一起加油吧!

下一课:C语言探索之旅 | 第二部分第十一课:练习题和习作


我是 谢恩铭,公众号「程序员联盟」(微信号:coderhub)运营者,慕课网精英讲师 Oscar 老师,终生学习者。
热爱生活,喜欢游泳,略懂烹饪。
人生格言:「向着标杆直跑」

这篇关于C语言探索之旅 | 第二部分第十课: 实战悬挂小人游戏答案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/499380

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

闲置电脑也能活出第二春?鲁大师AiNAS让你动动手指就能轻松部署

对于大多数人而言,在这个“数据爆炸”的时代或多或少都遇到过存储告急的情况,这使得“存储焦虑”不再是个别现象,而将会是随着软件的不断臃肿而越来越普遍的情况。从不少手机厂商都开始将存储上限提升至1TB可以见得,我们似乎正处在互联网信息飞速增长的阶段,对于存储的需求也将会不断扩大。对于苹果用户而言,这一问题愈发严峻,毕竟512GB和1TB版本的iPhone可不是人人都消费得起的,因此成熟的外置存储方案开

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

滚雪球学Java(87):Java事务处理:JDBC的ACID属性与实战技巧!真有两下子!

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~ 🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!! 环境说明:Windows 10

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

poj 3104 二分答案

题意: n件湿度为num的衣服,每秒钟自己可以蒸发掉1个湿度。 然而如果使用了暖炉,每秒可以烧掉k个湿度,但不计算蒸发了。 现在问这么多的衣服,怎么烧事件最短。 解析: 二分答案咯。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <c

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的