热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

聊天室(c/s架构)

项目要求:(1)采用ClientServer架构。(2)ClientA登陆聊天服务器前,需要注册自己的ID和密码。(3)注册成功后,ClientA就可以通
项目要求:

(1)采用 Client/Server 架构 。 

(2) Client A 登陆聊天服务器前,需要注册自己的 ID 和密码。 

(3)注册成功后,ClientA 就可以通过自己的 ID 和密码登陆聊天服务器 。 

(4). 多个 Client X 可以同时登陆聊天服务器之后,与其他用户进行通讯聊天。 

(5).Client A 成功登陆后可以查看当前聊天室内其他在线用户 Client x。 

(6). Client A 可以选择发消息给某个特定的 Client X,即”悄悄话”功能。

(7). Client A 可以选择发消息全部的在线用户,即”群发消息”功能。 

(8). Client A 在退出时需要保存聊天记录。 

(9). Server 端维护一个所有登陆用户的聊天会的记录文件,以便备查。

1、服务器

#include 
#include
#include
#include
#include
#include
#include
#include
#include

#define PORT 9999

struct User //用户信息结构体
{
char name[20]; //储存用户名
char password[20]; //储存密码
char signature[50]; //储存个性签名
int socket; //储存套接字
int cmd; // 消息类型
char msg[1024]; // 消息内容
char toname[20];
char fromname[20];
char logout;
char file_name[20];
char file_msg[1024];
};

struct User user[5];

sqlite3 * database;

sqlite3 * server_sqlite() //数据库函数
{
sqlite3 * database;

// 打开数据库
int ret = sqlite3_open("usermes.db", &database);
if (ret != SQLITE_OK)
{
printf ("错误代码\n");
perror("sqlite3_open");
return NULL;
}

char *errmsg = NULL;
char *sql = "create table if not exists usermes(name TEXT, password TEXT, signature TEXT, primary key(name))";
ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
return NULL;
}
return database;
}

int init_socket() //套接字初始化
{
int listen_socket = socket (AF_INET, SOCK_STREAM, 0);
if(listen_socket == -1)
{
printf("错误代码55\n");
perror("socket");
return -1;
}

struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET; // 设置地址族
addr.sin_port = htons(PORT); // 设置本地端口
addr.sin_addr.s_addr = htonl(INADDR_ANY); // 使用本地的任意IP地址

int ret = bind(listen_socket, (struct sockaddr *)&addr, sizeof(addr)); //绑定套接字
if (ret == -1)
{
printf("错误代码69\n");
perror ("bind");
return -1;
}

// 3、监听本地套接字
ret = listen(listen_socket, 5);
if (ret == -1)
{
printf("错误代码78\n");
perror ("listen");
return -1;
}

printf("等待客户连接。。。。\n");
return listen_socket;
}

int MyAccept(int listen_socket) //连接客户端
{
struct sockaddr_in client_addr; // 用来保存客户端的ip和端口信息
int len = sizeof(client_addr);
int client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, &len);
if (client_socket == -1)
{
printf("错误代码93\n");
perror ("accept");
}

printf ("成功接收一个客户端: %s\n", inet_ntoa(client_addr.sin_addr));

return client_socket;
}

void reg(int client_socket, struct User *buf) //注册
{
char str[1024];
sqlite3 * database;
int i;
database = server_sqlite(); //打开数据库
char *errmsg = NULL;
sprintf (str, "insert into usermes values('%s', '%s', '666')", buf->name, buf->password);
int ret = sqlite3_exec(database, str, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
buf->cmd = -2;
write(client_socket, buf, sizeof(struct User));
}
else
{
printf("注册成功\n");
buf->cmd = 1000;
write(client_socket, buf, sizeof(struct User));
}
sqlite3_close(database); // 关闭数据库
}

void log_in(int client_socket, struct User *buf) //登录
{
sqlite3 * database = server_sqlite();
char *errmsg = NULL;
char **resultp = NULL;
int nrow, ncolumn;
char *sql = "select * from usermes";
int ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
return;
}
printf("正在匹配账户和密码....\n");
int i;
int k;
for (i = 3; i <(nrow+1)*ncolumn; i++)
{
if(strncmp(resultp[i], buf->name, strlen(buf->name)) == 0)
{
if(strncmp(resultp[i+1], buf->password, strlen(buf->password)) == 0)
{
for(k = 0; k <5; k++)
{
if(user[k].socket == 0)
{
strcpy (user[k].name , buf->name);
user[k].socket = client_socket;
buf->cmd = 1001;
strcpy(buf->signature,resultp[i+2]);
write(client_socket, buf, sizeof(struct User));
printf("密码账号匹配成功\n");
break;
}
}
if(k == 5)
{
printf("在线人数已达上限\n");
buf->cmd = -3;
write(client_socket, buf, sizeof(struct User));
}
return;
}
printf("账户和密码匹配不成功\n");
buf->cmd = -4;
write(client_socket, buf, sizeof(struct User));
break;
}
}
if(i = (nrow+1)*ncolumn)
{
printf("没有此用户\n");
buf->cmd = -4;
write(client_socket, buf, sizeof(struct User));
}
sqlite3_free_table(resultp);
sqlite3_close(database);
}

void View_profile(int client_socket, struct User *buf) //查看在线好友
{
printf("%s 要查看在线好友\n", buf->name);
buf->cmd = 1002;
int i;
for(i = 0; i <5; i++)
{
if(user[i].socket != 0)
{
strcpy(buf->msg,user[i].name);
write(client_socket, buf, sizeof(struct User));
}
}
}

void Modify_the_signature(int client_socket, struct User *buf) //修改个签
{
sqlite3 * database = server_sqlite();
printf("%s 要修改个性签名\n", buf->name);
char *errmsg = NULL;
char sql[1024] ;
sprintf(sql, "update usermes set signature = '%s'where name = '%s'", buf->signature, buf->name);
int ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
buf->cmd = -1;
printf ("数据库操作失败:%s\n", errmsg);
sqlite3_close(database);
return;
}
buf->cmd = 1003;
write(client_socket, buf, sizeof(buf));
printf("个性签名修改成功\n");

sqlite3_close(database);
}

void Private_chat(int client_socket, struct User *buf) //私聊
{
sqlite3 * database = server_sqlite();
printf("%s 要进行私聊\n", buf->name);
int i;
char *errmsg = NULL;
char **resultp = NULL;
int nrow, ncolumn;
char *sql = "select name from usermes";
int ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
return;
}
for (i = 1; i <(nrow+1)*ncolumn; i++)
{
if(strncmp(resultp[i], buf->toname, strlen(buf->toname)) == 0)
{
break;
}
}
if(i == (nrow+1)*ncolumn)
{
buf->cmd = -3; //服务器不存在该用户
write(client_socket, buf, sizeof(struct User));
sqlite3_close(database);
return;
}

for(i = 0; i <5; i++)
{
if(strncmp(user[i].name, buf->toname, strlen(buf->toname)) == 0)
{
buf->cmd = 1004;
write(user[i].socket, buf, sizeof(struct User));
break;
}
}

if(i == 5)
{
buf->cmd = -2; //要发送消息的人不在线
write(client_socket, buf, sizeof(struct User));
}

sqlite3_close(database);
}

void Group_chat(int client_socket, struct User *buf) //群聊
{
printf("%s 要进行群聊\n", buf->name);
buf->cmd = 1005;
int i;
for(i = 0; i <5; i++)
{
if(user[i].socket != 0)
{
write(user[i].socket, buf, sizeof(struct User));
}
}
}

void Logout(int client_socket, struct User *buf) //注销函数
{
printf("%s 要注销此用户\n", buf->name);
sqlite3 * database = server_sqlite();
int i;
char *errmsg = NULL;
char **resultp = NULL;
int nrow, ncolumn;
char sql[1024];
sprintf(sql,"delete from usermes where name = '%s'", buf->name);
int ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
return;
}
buf->cmd = 1006;
printf("此用户已经成功注销\n");
write(client_socket, buf, sizeof(struct User));
sqlite3_close(database);
}

void Send_file(int client_socket, struct User *buf) //文件传输函数
{
sqlite3 * database = server_sqlite();
printf("%s 要向 %s 发送文件\n", buf->name, buf->toname);

int i;
for(i = 0;i <5; i++)
{
if(strncmp(user[i].name, buf->toname, strlen(buf->toname)) == 0)
{
strcpy(buf->file_name, buf->name);
buf->cmd = 1007;
write(user[i].socket, buf, sizeof(struct User));
printf("文件发送中。。。\n");
break;
}
}
}

void exit_chat(int client_socket, struct User *buf) //退出聊天室
{
printf("%s 要退出聊天室\n", buf->name);

int i;
for(i = 0; i <5; i++)
{
if(strcmp(user[i].name, buf->name) == 0)
{
memset(&user[i], 0, sizeof(struct User));
printf("聊天室退出成功\n");
buf->cmd = 1008;
write(client_socket, buf, sizeof(struct User));
break;
}
}
}

void exchang_password(int client_socket, struct User *buf) //修改密码
{
printf("%s 要修改密码\n", buf->name);
sqlite3 * database;
int i;
char str[1024];
database = server_sqlite(); //打开数据库
char *errmsg = NULL;
sprintf (str, "update usermes set password = '%s'where name = '%s'", buf->password, buf->name);
int ret = sqlite3_exec(database, str, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
buf->cmd = -4;
write(client_socket, buf, sizeof(struct User));
}
else
{
printf("密码修改成功\n");
buf->cmd = 1009;
write(client_socket, buf, sizeof(struct User));
}
sqlite3_close(database); // 关闭数据库
}

void *hanld_client(void *v)
{
int client_socket = (int)v;
struct User buf;

while(1)
{
// 从客户端读一个结构体数据
int ret = read(client_socket, &buf, sizeof(buf));
if (ret == -1)
{
printf("错误代码\n");
perror ("read");
break;
}

if(ret == 0)
{
printf("客户端退出\n");
break;
}

switch (buf.cmd)
{
case 1 : // 客户端进行注册
printf("客户进行注册\n");
reg(client_socket, &buf);
break;
case 2 : // 客户端进行登录
log_in(client_socket, &buf);
break;
case 3 : // 客户端退出
printf("客户端退出\n");
break;
case 4: //查看在线好友
View_profile(client_socket, &buf);
memset(&buf, 0, sizeof(buf));
break;
case 5: //修改个性签名
Modify_the_signature(client_socket, &buf);
break;
case 6: //私聊
Private_chat(client_socket, &buf);
break;
case 7: //群聊
Group_chat(client_socket, &buf);
break;
case 8: //注销此用户
Logout(client_socket, &buf);
break;
case 9: //发送文件
Send_file(client_socket, &buf);
break;
case 10: //退出聊天室
exit_chat(client_socket, &buf);
break ;
case 11: //修改密码
exchang_password(client_socket, &buf);
break;
default:
printf("输入有误,请重新输入\n");
break;
}
}
}

int main()
{
int listen_socket = init_socket(); //初始化监听套接字

while (1)
{
// 获取与客户端连接的套接字
int client_socket = MyAccept(listen_socket);

// 创建一个线程去处理客户端的请求,主线程依然负责监听
pthread_t id;
pthread_create(&id, NULL, hanld_client, (void *)client_socket);

pthread_detach(id); // 线程分离
}

close (listen_socket);

return 0;
}

2、客户端

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define PORT 9999

struct User //用户信息结构体
{
char name[20]; //储存用户名
char password[20]; //储存密码
char signature[50]; //储存个性签名
int socket; //储存套接字
int cmd; // 消息类型
char msg[1024]; // 消息内容
char toname[20];
char fromname[20];
char logout[2];
char file_name[20];
char file_msg[1024];
};

int init_socket()
{
int client_socket = socket (AF_INET, SOCK_STREAM, 0);
if(client_socket == -1)
{
printf("\t\t错误代码\n");
perror("socket");
return -1;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET; // 设置地址族
addr.sin_port = htons(PORT); // 设置本地端口
inet_aton("127.0.0.1",&(addr.sin_addr));


// 连接服务器,如果成功,返回0,如果失败,返回-1
// 成功的情况下,可以通过socketfd与服务器进行通信
int ret = connect(client_socket, (struct sockaddr *)&addr, sizeof(addr));
if (ret == -1)
{
perror ("connect");
return -1;
}
return client_socket;
}

void Home_interface() //主界面
{
system("clear");
printf("\n\n\n\n");
printf("\t\t请输入对应功能的号码\n");
printf("\t\t\t1、注册\n");
printf("\t\t\t2、登录\n");
printf("\t\t\t3、退出\n");
}

sqlite3 * chat_sqlite() //聊天数据库,保存聊天记录
{
sqlite3 * database;

// 打开数据库
int ret = sqlite3_open("chathistory.db", &database);
if (ret != SQLITE_OK)
{
printf ("错误代码\n");
perror("sqlite3_open");
return NULL;
}

char *errmsg = NULL;
char *sql = "create table if not exists chathistory(fromname TEXT, toname TEXT, msg TEXT)";
ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
return NULL;
}
return database;
}

void func_interface(struct User *user) //功能界面
{
system("clear");
printf("☺:%s\n", user->signature);
printf("\n\n");
printf("\t\t请输入对应功能的号码\n");
printf("\t\t\t1、查看在线好友\n");
printf("\t\t\t2、修改个性签名\n");
printf("\t\t\t3、私聊\n");
printf("\t\t\t4、群聊\n");
printf("\t\t\t5、注销此用户\n");
printf("\t\t\t6、发送文件\n");
printf("\t\t\t7、查看聊天记录\n");
printf("\t\t\t8、退出聊天室\n");
printf("\t\t\t9、修改密码\n");

}

void reg(int client_socket) //注册函数
{
struct User user;
user.cmd = 1;
//printf("\n\n\n\n");
printf("\t\t请输入用户名:");
scanf("%s", user.name);
printf("\t\t请输入密码:");
scanf("%s", user.password);

write(client_socket, &user, sizeof(user));

read(client_socket, &user, sizeof(user));
if(user.cmd == -2)
{
printf("\t\t已有用户,请重新注册\n");
}
if(user.cmd == 1000)
{
printf("\t\t注册成功\n");
}
else
{
printf("\t\t注册失败,请重新注册\n");
sleep(1);
}
}

void View_profile(int client_socket,struct User *user) //查看在线好友
{
user->cmd = 4;
write(client_socket, user, sizeof(struct User));

printf("\t\t请按回车键返回主界面\n");
getchar();
getchar();
}

void Modify_the_signature(int client_socket,struct User *user) //修改个签
{
user->cmd = 5;
printf("\t\t请输入你想输入的个性签名:\n");
scanf("%s", user->signature);
write(client_socket, user, sizeof(struct User));
}

void Private_chat(int client_socket,struct User *user) //私聊
{
sqlite3 * database = chat_sqlite();

user->cmd = 6;
printf("\t\t请输入你想聊天的对象:");
scanf("%s", user->toname);
strcpy(user->fromname, user->name);
printf("\t\t请输入聊天内容:");
scanf("%s", user->msg);
write(client_socket, user, sizeof(struct User));

char *errmsg = NULL;
char str[1024];
sprintf (str, "insert into chathistory values('%s', '%s', '%s')",user->fromname, user->toname, user->msg);
int ret = sqlite3_exec(database, str, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
perror("sqlite3_exec");
}

sqlite3_close(database);
}

void Group_chat(int client_socket,struct User *user)
{
sqlite3 * database = chat_sqlite();
user->cmd = 7;
printf("请输入聊天内容:");
scanf("%s", user->msg);
write(client_socket, user, sizeof(struct User));

char *errmsg = NULL;
char str[1024];
sprintf (str, "insert into chathistory values('%s', 'everyone', '%s')",user->name, user->msg);
int ret = sqlite3_exec(database, str, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
perror("sqlite3_exec");
}

sqlite3_close(database);
}

void * readMsg(void *v) //读写分离
{
sqlite3 * database = chat_sqlite();
int client_socket = (int)v;
struct User buf;
char str[1024];
int ret;
char *errmsg = NULL;
char file_name[20];
while (1)
{
int ret = read (client_socket, &buf, sizeof(buf));
if(ret == -1)
{
perror("read");
break;
}
switch (buf.cmd)
{
case 1002: //查看好友
system("clear");
printf("\n\n\n\n");
printf("\t\t在线的人有:%s\n", buf.msg);
break;
case 1003: //修改个签
printf("个性签名修改成功\n");
sleep(1);
break;
case -1:
printf("个性签名修改失败\n");
sleep(1);
break;
case 1004: // 私聊
printf("\n");
printf ("%s 给你发一条消息:%s\n", buf.fromname, buf.msg);
sprintf (str, "insert into chathistory values('%s', '%s', '%s')",buf.fromname, buf.toname, buf.msg);
ret = sqlite3_exec(database, str, NULL, NULL, &errmsg);
break;
case -2:
printf("该对象不在线\n");
break;
case -3:
printf("不存在该对象\n");
break;
case 1005: // 群聊
printf("\n");
printf ("收到一条群消息: %s\n", buf.msg);
sprintf (str, "insert into chathistory values('%s', 'everyone', '%s')",buf.name, buf.msg);
ret = sqlite3_exec(database, str, NULL, NULL, &errmsg);
break;
case 1006: //注销
printf("注销成功\n");
sleep(1);
sqlite3_close(database);
return ;
case 1008:
printf("成功退出聊天室\n");
sleep(1);
sqlite3_close(database);
return;
case 1009:
printf("密码修改成功\n");
sleep(1);
break;
case -4:
printf("密码修改失败\n");
sleep(1);
break;
case 1007:
printf("\n");
printf("%s 要给你传输文件\n", buf.name);

ret = open("text", O_WRONLY | O_CREAT, 0777);
if(ret == -1)
{
perror ("open ret");
break;
}
write(ret, buf.file_msg, strlen(buf.file_msg));
close(ret);
printf("成功接收到文件!\n");
break;
}

}
}

int Logout(int client_socket,struct User *user)
{
char buf[] = "y";
printf("是否注销此用户,请输入y/n \n");
scanf("%s", user->logout);

if(strcmp(user->logout, buf) == 0)
{
user->cmd = 8;
write(client_socket, user, sizeof(struct User));
printf("正在注销。。。\n");
sleep(1);
return 1;
}
else
{
return 0;
}
}

void Send_file(int client_socket,struct User *user) //发送文件
{
user->cmd = 9;
printf("请输入要发送文件的对象:");
scanf("%s", user->toname);
printf("请选择要发送的文件:");
scanf("%s", user->file_name);
int fd = open(user->file_name, O_RDWR);
if(fd == -1)
{
printf("文件打开失败\n");
perror("open");
return;
}
printf("文件正在发送\n");
int ret;

while(ret = read(fd, user->file_msg, 1024))
{
if(ret == -1)
{
printf("文件读取失败\n");
perror("read");
return;
}
write(client_socket, user, sizeof(struct User));
usleep(5);
}
printf("文件发送成功\n");
close(fd);
}

void chat_history() //查看聊天记录函数
{
sqlite3 * database = chat_sqlite();
char *errmsg = NULL;
char **resultp = NULL;
int nrow, ncolumn;
char *sql = "select * from chathistory";
int ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
return;
}
int i;
for(i = 0; i <(nrow+1)*ncolumn; i++)
{
if (i % ncolumn == 0)
printf ("\n");
printf("%-16s", resultp[i]);
}
printf("\n");
printf("请按回车键返回主界面\n");
getchar();
getchar();

sqlite3_close(database);
}

void exit_chat(int client_socket,struct User *user)
{
user->cmd = 10;
write(client_socket, user, sizeof(struct User));
printf("正在退出....\n");
sleep(1);
}

void exchang_password(int client_socket,struct User *user)
{
user->cmd = 11;
printf("请输入要修改的密码:");
scanf("%s", user->password);
write(client_socket, user, sizeof(struct User));

printf("正在修改密码\n");
sleep(1);
}

void log_in(int client_socket)
{
struct User user;
user.cmd = 2;

while(1)
{
printf("\n\n\n\n");
printf("\t\t请输入用户名:");
scanf("%s", user.name);
printf("\t\t请输入密码:");
scanf("%s", user.password);

write(client_socket, &user, sizeof(user));

read(client_socket, &user, sizeof(user));
if(user.cmd == -3)
{
printf("\t\t客户已达上限,请稍后登录\n");
return;
}
if(user.cmd == -4)
{
printf("\t\t密码或用户名不对,请重新输入\n");
return;
}
if(user.cmd == 1001)
{
printf("\t\t正在登录。。。。。。\n");
//sleep(2);
printf("\t\t登录成功\n");
//sleep(1);

pthread_t id;
pthread_create(&id, NULL, readMsg, (void *)client_socket);
pthread_detach(id); // 读写分离

int ret;
int i;
while(1)
{
func_interface(&user); // 功能界面函数
printf("\t\t请输入对应功能的号码:");
scanf("%d",&i);
switch(i)
{
case 1:
View_profile(client_socket, &user); //查看在线好友
break;
case 2:
Modify_the_signature(client_socket, &user); //修改个性签名
break;
case 3:
Private_chat(client_socket, &user); //私聊
break;
case 4:
Group_chat(client_socket, &user); //群聊
break;
case 5:
ret = Logout(client_socket, &user); //注销此用户
if(ret == 1)
return;
break;
case 6:
Send_file(client_socket, &user); //发送文件
break;
case 7:
chat_history(); //查看聊天记录
break;
case 8: //退出聊天室
exit_chat(client_socket, &user);
return;
case 9: //修改密码
exchang_password(client_socket, &user);
break ;
default:
printf("\t\t输入有误,请重新输入\n");
break;
}
}
}
}
}

int main()
{
int client_socket = init_socket (); //客户端初始化套接字
while(1)
{
struct User user;
Home_interface();
printf("\t\t请输入对于功能的号码:");
scanf("%d", &user.cmd);
printf("\n");
switch(user.cmd)
{
case 1:
reg(client_socket); //注册函数
break;
case 2:
log_in(client_socket); //登录函数
break;
case 3:
write(client_socket, &user, sizeof(user));
exit(0);
break;
default:
printf("\t\t输入有误,请重新输入\n");
break;
}
}
return 0;
}



推荐阅读
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 实现一个通讯录系统,可添加、删除、修改、查找、显示、清空、排序通讯录信息
    本文介绍了如何实现一个通讯录系统,该系统可以实现添加、删除、修改、查找、显示、清空、排序通讯录信息的功能。通过定义结构体LINK和PEOPLE来存储通讯录信息,使用相关函数来实现各项功能。详细介绍了每个功能的实现方法。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文讨论了一个数列求和问题,该数列按照一定规律生成。通过观察数列的规律,我们可以得出求解该问题的算法。具体算法为计算前n项i*f[i]的和,其中f[i]表示数列中有i个数字。根据参考的思路,我们可以将算法的时间复杂度控制在O(n),即计算到5e5即可满足1e9的要求。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • 本文介绍了在go语言中利用(*interface{})(nil)传递参数类型的原理及应用。通过分析Martini框架中的injector类型的声明,解释了values映射表的作用以及parent Injector的含义。同时,讨论了该技术在实际开发中的应用场景。 ... [详细]
author-avatar
伸手以后
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有