首页 > 其他分享 >C语言实践:基础通讯录实现

C语言实践:基础通讯录实现

时间:2025-01-11 21:30:03浏览次数:3  
标签:sz void 联系人 实践 C语言 pc 通讯录 printf t%

一、通讯录基本功能

1.增加联系人    2.删除联系人    3.查找联系人    4.修改联系人信息

5.显示通讯录    6.排序

二、联系人信息格式

姓名+性别+年龄+地址+电话

三、实现思路

 1.第一步,我们为了让使用者可以知道我们通讯录的功能一个显示面板是必不可少的。直接printf即可。但使用者不可能只使用一次就不继续使用,这时就要用到do-while循环和switch语句了。代码如下。

int main()
{
	int a;
	do
	{
		//mun为菜单
		mun();
		printf("请输入对应功能的数字:");
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
			break;
		case 6:
			break;
		case 0:
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (a != 0);
}
void mun(void)
{
	printf("********************************************\n");
	printf("*******1.添加联系人       2.删除联系人*******\n");
	printf("*******3.查找联系人       4.修改联系人*******\n");
	printf("*******5.显示通讯录       6.排序通讯录*******\n");
	printf("*******            0.退出            *******\n");
	printf("********************************************\n");
}

效果如图所示:

这时,我们的菜单就做好了,我们知道一个联系人的信息有姓名、性别、年龄、地址、电话。如果我们用多个不同类型的数组去存储就太过麻烦了,我们可以使用结构体来存储一个联系人的信息,代码如下:

//创建一个存储联系人信息的结构体
struct context
{
	//姓名
	char name[20];
	//性别
	char sex[5];
	//年龄
	int age;
	//地址
	char site[50];
	//电话
	char phone[12];
};
//再创建一个结构体方便context类型数组的使用
struct con
{
	//MAX为一个常量,100。
	struct context p[MAX];
	//sz用于记录,在后续代码中有很大的用处
	int sz;
};

接下来,我们还需将cun进行初始化以确保代码运行正常,我们可以写一个初始化函数,代码如下

void rise(con* pc)
{
	//使用memset函数对cun进行初始化
	memset(pc->p, 0, sizeof(pc->p));
}

接下来,我们就可以按照通讯录的功能逐步写代码实现。

2.增加联系人:想要添加联系人,我们要先判断p数组中是否还有存储空间,总不能p数组已经存储了100个联系人信息,还添加吧。若通讯录中联系人信息未存满,则进行添加。代码如下:

void add(struct con* pc)
{
	//我们知道sz是用来计数的,因此我们可以用sz来判断是否存储满
	if (pc->sz == MAX)
	{
		printf("通讯录已存满,请删除一些联系人后重试\n");
		return;
	}
	else
	{
		printf("请输入姓名>");
		scanf("%s", pc->p[pc->sz].name);
		printf("请输入姓别>");
		scanf("%s", pc->p[pc->sz].sex );
		printf("请输入年龄>");
		scanf("%d", &pc->p[pc->sz].age );
		printf("请输入地址>");
		scanf("%s", pc->p[pc->sz].site );
		printf("请输入电话>");
		scanf("%s", pc->p[pc->sz].phone );
		pc->sz++;
	}
}

3.删除联系人:通常,我们一看到数组中的删除就会想到,将要删除的数的后一位向前移,覆盖掉要删除的数,后面的数重复这样的操作,从而达到删除这一个数的操作,且这样做数的存储顺序不会发生改变。代码如下:

void del(struct con* pc)
{
	char a[20];
	printf("请输入要删除联系人的姓名>");
	//因为a就是数组首元素的地址,所以不需要再取地址
	scanf("%s", a);
	//for循环遍历寻找
	int i;
	for (i = 0; i <= pc->sz; i++)
	{
		if (strcmp(pc->p[i].name, a) == 0)
		{
			//找到就跳出循环
			break;
		}
	}
	if (i == pc->sz+1)
	{
		printf("未找到要删除的联系人");
		return;
	}
	//然后进行删除
	for (i; i < pc->sz; i++)
	{
		pc->p[i] = pc->p[i + 1];
	}
	printf("删除成功");
	//删除一个,所以计数sz回退一下
	pc->sz--;
}

3.查找联系人:这个功能的实现其实就是遍历再打印查找到的联系人信息,这里要考虑查找不到联系人信息这一情况出现。代码如下:

void find(struct con* pc)
{
        //查找到联系人则加1
        int b=0;
        printf("请输入姓名>");
        char a1[20];
        scanf("%s", a1);
        printf("%-20s\t%-5s\t%-5s\t%-30s\t%-12s\t\n", "姓名", "性别", "年龄", " 地址", "电话");
        for (int i = 0; i <= pc->sz; i++)
        {
	        if (strcmp(a1, pc->p[i].name) == 0)
	        {
		        printf("%-20s\t%-5s\t%-5d\t%-30s\t%-12s\t\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].site, pc->p[i].phone);
		        b++;
	        }
        }
        if (b == 0)
        {
	        printf("未查找到联系人,请重新输入\n");
        }
}

如果你想要更加全面的查找,也可以按结构体的成员来作为条件进行查找,代码如下:

//查找功能中选择查找条件的菜单
void mua(void)
{
	printf("********************************************\n");
	printf("*******1.姓名      2.年龄            *******\n");
	printf("*******3.性别      4.地址            *******\n");
	printf("*******5.电话号码  0.退出            *******\n");
	printf("********************************************\n");
}

void find(con* pc)
{
	mua();
	int a;
	do
	{
		int b = 0;
		printf("请输入查找条件对应的数字");
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			printf("请输入姓名>");
			char a1[20];
			scanf("%s", a1);
			printf("%-20s\t%-5s\t%-5s\t%-30s\t%-12s\t\n", "姓名", "性别", "年龄", " 地址", "电话");
			for (int i = 0; i <= pc->sz; i++)
			{
				if (strcmp(a1, pc->p[i].name) == 0)
				{
					printf("%-20s\t%-5s\t%-5d\t%-30s\t%-12s\t\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].site, pc->p[i].phone);
					b++;
				}
			}
			if (b == 0)
			{
				printf("未查找到联系人,请重新输入\n");
			}
			break;
		case 2:
			printf("请输入年龄>");
			int a2;
			scanf("%d",&a2);
			printf("%-20s\t%-5s\t%-5s\t%-30s\t%-12s\t\n", "姓名", "性别", "年龄", " 地址", "电话");
			for (int i = 0; i <= pc->sz; i++)
			{
				if (pc->p [i].age ==a2)
				{
					printf("%-20s\t%-5s\t%-5d\t%-30s\t%-12s\t\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].site, pc->p[i].phone);
					b++;
				}
			}
			if (b == 0)
			{
				printf("未查找到联系人,请重新输入\n");
			}
			break;
		case 3:
			printf("请输入性别>");
			char a3[5];
			scanf("%s", a3);
			printf("%-20s\t%-5s\t%-5s\t%-30s\t%-12s\t\n", "姓名", "性别", "年龄", " 地址", "电话");
			for (int i = 0; i <= pc->sz; i++)
			{
				if (strcmp(a3, pc->p[i].name) == 0)
				{
					printf("%-20s\t%-5s\t%-5d\t%-30s\t%-12s\t\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].site, pc->p[i].phone);
					b++;
				}
			}
			if (b == 0)
			{
				printf("未查找到联系人,请重新输入\n");
			}
			break;
		case 4:
			printf("请输入地址>");
			char a4[50];
			scanf("%s", a4);
			printf("%-20s\t%-5s\t%-5s\t%-30s\t%-12s\t\n", "姓名", "性别", "年龄", " 地址", "电话");
			for (int i = 0; i <= pc->sz; i++)
			{
				if (strcmp(a4, pc->p[i].name) == 0)
				{
					printf("%-20s\t%-5s\t%-5d\t%-30s\t%-12s\t\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].site, pc->p[i].phone);
					b++;
				}
			}
			if (b == 0)
			{
				printf("未查找到联系人,请重新输入\n");
			}
			break;
		case 5:
			printf("请输入电话号码>");
			char a5[20];
			scanf("%s", a5);
			printf("%-20s\t%-5s\t%-5s\t%-30s\t%-12s\t\n", "姓名", "性别", "年龄", " 地址", "电话");
			for (int i = 0; i <= pc->sz; i++)
			{
				if (strcmp(a5, pc->p[i].name) == 0)
				{
					printf("%-20s\t%-5s\t%-5d\t%-30s\t%-12s\t\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].site, pc->p[i].phone);
					b++;
				}
			}
			if (b == 0)
			{
				printf("未查找到联系人,请重新输入\n");
			}
			break;
		case 0:
			printf("退出查找");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
    } while (a != 0);
}

4.修改联系人信息:这个功能无非就是先遍历查找,再修改。这个就可以借用查找联系人功能的代码,来进行一个完善的查找,这里就提供一个基础的修改代码。

void revise(con* pc)
{
	printf("请输入要修改的联系人姓名>");
	char a[20];
	scanf("%s", a);
	int i;
	for (i = 0; i <=pc->sz; i++)
	{
		if (strcmp(a, pc->p[i].name) == 0)
		{
			break;
		}
	}
	if (i > pc->sz)
	{
		printf("未找到要修改的联系人");
		return;
	}
	else
	{
		printf("请输入姓名>");
		scanf("%s", pc->p[i].name);
		printf("请输入姓别>");
		scanf("%s", pc->p[i].sex);
		printf("请输入年龄>");
		scanf("%d", &pc->p[i].age);
		printf("请输入地址>");
		scanf("%s", pc->p[i].site);
		printf("请输入电话>");
		scanf("%s", pc->p[i].phone);
	}
}

5.显示通讯录:这个功能的实现只需将结构体数组遍历打印即可,代码如下:

void show(struct con* pc)
{
	printf("%-20s\t%-5s\t%-5s\t%-30s\t%-12s\t\n", "姓名", "性别", "年龄"," 地址","电话" );
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5s\t%-5d\t%-30s\t%-12s\t\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].site, pc->p[i].phone);
	}
}

%-20s,20是打印字符串的宽度,它的正负代表其对齐方式,如%-20s是左对齐,%20s是右对齐。

这样做可以使其更美观。效果如下:

6.排序:排序我们可以直接使用qsort函数来进行排序,代码如下:

int mvf(const void* a, const void* b)
{
	return (*(struct context*)a).name > (*(struct context*)b).name ? 1 :-1;
}
int mve(const void* a, const void* b)
{
	return (*(struct context*)a).name > (*(struct context*)b).name ? -1 : 1;
}
//将排序单独列出,以使代码更简便。
void cs1(struct con* pa, int b)
{
	if (b < 0)
	{
		qsort(pa->p, pa->sz, sizeof(pa->p[0]), mvf);
	}
	else
	{
		qsort(pa->p, pa->sz, sizeof(pa->p[0]), mve);
	}
}
void sort(con* pc)
{
	printf("请输入排序顺序\n中间以空格隔开,大于0为正序,小于0为到序");
	int b;
	scanf("%d",&b);
	cs1(pc, b);
	printf("排序成功");
}

自此,基础通讯录就完成了。完整代码如下:

shengming.h

#pragma once
#pragma warning(disable : 4996)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100
//主菜单
void mun(void);
//创建一个存储联系人信息的结构体
struct context
{
	//姓名
	char name[20];
	//性别
	char sex[5];
	//年龄
	int age;
	//地址
	char site[50];
	//电话
	char phone[12];
};
//再创建一个结构体方便context类型数组的使用
struct con
{
	//MAX为一个常量,100。
	struct context p[MAX];
	//sz用于记录,在后续代码中有很大的用处
	int sz;
};
//cun初始化
void rise(struct con* pc);
//添加联系人
void add(struct con* pc);
//删除联系人
void del(struct con* pc);
//展示联系人
void show(struct con* pc);
//查找联系人
void find(struct con* pc);
//修改联系人信息
void revise(struct con* pc);
//排序
void sort(struct con* pc);

zhuwenjian.c

#include"shengming.h"
int main()
{
	int a;
	struct con cun;
	//cun初始化
	rise(&cun);
	do
	{
		//mun为菜单
		mun();
		printf("请输入对应功能的数字:");
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			//添加联系人
			add(&cun);
			break;
		case 2:
			del(&cun);
			break;
		case 3:
			find(&cun);
			break;
		case 4:
			revise(&cun);
			break;
		case 5:
			show(&cun);
			break;
		case 6:
			sort(&cun);
			break;
		case 0:
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (a != 0);
	return 0;
}

fuwenjian.c

#include"shengming.h"
void mun(void)
{
	printf("********************************************\n");
	printf("*******1.添加联系人       2.删除联系人*******\n");
	printf("*******3.查找联系人       4.修改联系人*******\n");
	printf("*******5.显示通讯录       6.排序通讯录*******\n");
	printf("*******            0.退出            *******\n");
	printf("********************************************\n");
}
//查找功能中选择查找条件的菜单
void mua(void)
{
	printf("********************************************\n");
	printf("*******1.姓名      2.年龄            *******\n");
	printf("*******3.性别      4.地址            *******\n");
	printf("*******5.电话号码  0.退出            *******\n");
	printf("********************************************\n");
}
void rise(struct con* pc)
{
	//使用memset函数对cun进行初始化
	memset(pc->p, 0, sizeof(pc->p));
	pc->sz = 0;
}

void add(struct con* pc)
{
	//我们知道sz是用来计数的,因此我们可以用sz来判断是否存储满
	if (pc->sz == MAX)
	{
		printf("通讯录已存满,请删除一些联系人后重试\n");
		return;
	}
	else
	{
		printf("请输入姓名>");
		scanf("%s", pc->p[pc->sz].name);
		printf("请输入姓别>");
		scanf("%s", pc->p[pc->sz].sex );
		printf("请输入年龄>");
		scanf("%d", &pc->p[pc->sz].age );
		printf("请输入地址>");
		scanf("%s", pc->p[pc->sz].site );
		printf("请输入电话>");
		scanf("%s", pc->p[pc->sz].phone );
		pc->sz++;
	}
}

void del(struct con* pc)
{
	char a[20];
	printf("请输入要删除联系人的姓名>");
	//因为a就是数组首元素的地址,所以不需要再取地址
	scanf("%s", a);
	//for循环遍历寻找
	int i;
	for (i = 0; i <= pc->sz; i++)
	{
		if (strcmp(pc->p[i].name, a) == 0)
		{
			//找到就跳出循环
			break;
		}
	}
	if (i == pc->sz+1)
	{
		printf("未找到要删除的联系人");
		return;
	}
	//然后进行删除,用后一位覆盖前一位
	for (i; i < pc->sz; i++)
	{
		pc->p[i] = pc->p[i + 1];
	}
	printf("删除成功");
	//删除一个,所以计数sz回退一下
	pc->sz--;
}

void show(struct con* pc)
{
	printf("%-20s\t%-5s\t%-5s\t%-30s\t%-12s\t\n", "姓名", "性别", "年龄"," 地址","电话" );
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5s\t%-5d\t%-30s\t%-12s\t\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].site, pc->p[i].phone);
	}
}

void find(con* pc)
{
	mua();
	int a;
	do
	{
		int b = 0;
		printf("请输入查找条件对应的数字");
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			printf("请输入姓名>");
			char a1[20];
			scanf("%s", a1);
			printf("%-20s\t%-5s\t%-5s\t%-30s\t%-12s\t\n", "姓名", "性别", "年龄", " 地址", "电话");
			for (int i = 0; i <= pc->sz; i++)
			{
				if (strcmp(a1, pc->p[i].name) == 0)
				{
					printf("%-20s\t%-5s\t%-5d\t%-30s\t%-12s\t\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].site, pc->p[i].phone);
					b++;
				}
			}
			if (b == 0)
			{
				printf("未查找到联系人,请重新输入\n");
			}
			break;
		case 2:
			printf("请输入年龄>");
			int a2;
			scanf("%d",&a2);
			printf("%-20s\t%-5s\t%-5s\t%-30s\t%-12s\t\n", "姓名", "性别", "年龄", " 地址", "电话");
			for (int i = 0; i <= pc->sz; i++)
			{
				if (pc->p [i].age ==a2)
				{
					printf("%-20s\t%-5s\t%-5d\t%-30s\t%-12s\t\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].site, pc->p[i].phone);
					b++;
				}
			}
			if (b == 0)
			{
				printf("未查找到联系人,请重新输入\n");
			}
			break;
		case 3:
			printf("请输入性别>");
			char a3[5];
			scanf("%s", a3);
			printf("%-20s\t%-5s\t%-5s\t%-30s\t%-12s\t\n", "姓名", "性别", "年龄", " 地址", "电话");
			for (int i = 0; i <= pc->sz; i++)
			{
				if (strcmp(a3, pc->p[i].name) == 0)
				{
					printf("%-20s\t%-5s\t%-5d\t%-30s\t%-12s\t\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].site, pc->p[i].phone);
					b++;
				}
			}
			if (b == 0)
			{
				printf("未查找到联系人,请重新输入\n");
			}
			break;
		case 4:
			printf("请输入地址>");
			char a4[50];
			scanf("%s", a4);
			printf("%-20s\t%-5s\t%-5s\t%-30s\t%-12s\t\n", "姓名", "性别", "年龄", " 地址", "电话");
			for (int i = 0; i <= pc->sz; i++)
			{
				if (strcmp(a4, pc->p[i].name) == 0)
				{
					printf("%-20s\t%-5s\t%-5d\t%-30s\t%-12s\t\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].site, pc->p[i].phone);
					b++;
				}
			}
			if (b == 0)
			{
				printf("未查找到联系人,请重新输入\n");
			}
			break;
		case 5:
			printf("请输入电话号码>");
			char a5[20];
			scanf("%s", a5);
			printf("%-20s\t%-5s\t%-5s\t%-30s\t%-12s\t\n", "姓名", "性别", "年龄", " 地址", "电话");
			for (int i = 0; i <= pc->sz; i++)
			{
				if (strcmp(a5, pc->p[i].name) == 0)
				{
					printf("%-20s\t%-5s\t%-5d\t%-30s\t%-12s\t\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].site, pc->p[i].phone);
					b++;
				}
			}
			if (b == 0)
			{
				printf("未查找到联系人,请重新输入\n");
			}
			break;
		case 0:
			printf("退出查找");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
    } while (a != 0);
}

void revise(con* pc)
{
	printf("请输入要修改的联系人姓名>");
	char a[20];
	scanf("%s", a);
	int i;
	for (i = 0; i <=pc->sz; i++)
	{
		if (strcmp(a, pc->p[i].name) == 0)
		{
			break;
		}
	}
	if (i > pc->sz)
	{
		printf("未找到要修改的联系人");
		return;
	}
	else
	{
		printf("请输入姓名>");
		scanf("%s", pc->p[i].name);
		printf("请输入姓别>");
		scanf("%s", pc->p[i].sex);
		printf("请输入年龄>");
		scanf("%d", &pc->p[i].age);
		printf("请输入地址>");
		scanf("%s", pc->p[i].site);
		printf("请输入电话>");
		scanf("%s", pc->p[i].phone);
	}
}
int mvf(const void* a, const void* b)
{
	return (*(struct context*)a).name > (*(struct context*)b).name ? 1 :-1;
}
int mve(const void* a, const void* b)
{
	return (*(struct context*)a).name > (*(struct context*)b).name ? -1 : 1;
}
//将排序单独列出,以使代码更简便。
void cs1(struct con* pa, int b)
{
	if (b < 0)
	{
		qsort(pa->p, pa->sz, sizeof(pa->p[0]), mvf);
	}
	else
	{
		qsort(pa->p, pa->sz, sizeof(pa->p[0]), mve);
	}
}
void sort(con* pc)
{
	printf("请输入排序顺序\n中间以空格隔开,大于0为正序,小于0为到序");
	int b;
	scanf("%d",&b);
	cs1(pc, b);
	printf("排序成功");
}

标签:sz,void,联系人,实践,C语言,pc,通讯录,printf,t%
From: https://blog.csdn.net/2401_86688820/article/details/145077971

相关文章

  • C语言基础(一)
    常量与变量常量:在程序运行过程中不能被改变的量变量:在程序运行过程中能被改变的量例如:inti;i=123456;i为变量,在程序运行过程中,其值被改变为123456;而123456为常量,在程序运行过程中不能被改变。使用常量给变量赋值时,在计算机RAM中使用小端字节序,即高地址放高位,低地址放......
  • C语言基础(三)
    C程序的组成包括以下部分(main.c文件只能有一个)c语句分为五类:赋值语句赋值语句就是赋值表达式加上一个分号构成而“=”的左右即分为左值和右值,以下是左值和右值的两个解释locatable  可定位,左值(变量),在RAM中可以通过其地址定位到;readable  可读,右值(常量),只能读取,在......
  • C语言基础(二)
    变量初始化在定义变量的同时使变量初始化,例如:inta=3;此时,a被初始化为3,比定义变量后再赋值的效率高各种数据类型间的混合运算整型(int)、浮点型(float)、字符型(char)之间可以混合运算,在运算时,不同的数据先转换为同一类型,再进行运算,右图为转换时的规则。向左的箭头表示必定的转......
  • C语言基础
    1、运算符:    1、算数运算符:        +    -    *    /(后面不可以除0)    %(不可以对浮点数取余)        ++ --的两种形式:            i++:先用后加         ++......
  • 用C语言写一个简单的五子棋游戏,新手刚上路做的第一个小项目
    1/*23451.制作15*15的棋盘,放到二维数组中,制作成一个函数;62.for循环,输入坐标,结构分两部分,第一部分为甲,第二部分为乙7(1)根据坐标,指向棋盘的某个位置,更改常量,并刷新棋盘8(2)判断是否有重复下子,有刷新棋盘,并提示重新下子9(3)根据输入的坐标,判断横竖......
  • 指针(全解)—C语言进阶
    目录字符指针例题指针数组(数组)数组指针再次讨论数组名数组指针来源理解练习:数组传参4.数组参数和指针参数4.1 一维数组传参4.2二维数组传参4.3 一级指针传参4.4 二级指针传参5.函数指针例子函数指针的用法函数指针数组函数指针数组的用法:指向函数指......
  • 模数转换器(ADC)入门指南:从原理到实践
    1ADC基础概念模数转换器(Analog-to-DigitalConverter,ADC)是一种将连续的模拟信号转换成离散数字信号的器件。在STM32微控制器中,ADC模块扮演着连接模拟世界与数字世界的桥梁角色。它能够将外部传感器输入的模拟电压值转换为微控制器可以处理的数字量。模数转换器(ADC)是将......
  • 使用自然语言查询 Supabase 的实践指南
    在本篇文章中,我们将介绍如何使用自然语言结构化查询Supabase数据库。Supabase是一个开源的Firebase替代品,构建在PostgreSQL之上。通过使用pgvector来存储嵌入向量,可以使得数据库的查询更为智能和高效。技术背景介绍Supabase提供了一种现代化的数据库管理方式,通......
  • P1433 吃奶酪(C语言)
    题目描述房间里放着 n 块奶酪。一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在 (0,0)点处。输入格式第一行有一个整数,表示奶酪的数量 nn。第 2 到第(n+1) 行,每行两个实数,第 (i+1)(i+1) 行的实数分别表示第 ii 块奶酪的横纵坐标 xi,yi。输出格式......
  • 使用Ollama和OpenAI实现多查询RAG的实践指南
    在本文中,我们将深入探讨如何使用Ollama和OpenAI来实现基于多查询检索增强生成(RAG)的应用。多查询检索器通过将用户的输入查询转换为多个不同视角的查询,从而在更广泛的背景下检索相关文档。这种方法可以提升答案生成的准确性和丰富性。技术背景介绍RAG(Retrieval-AugmentedG......