7.2.2搜索的例子(还挺复杂)

文章讲述了如何使用C语言编写程序,根据输入的硬币面额来查找并输出对应的名称。首先提出了使用两个数组分别存储面额和名称,然后通过搜索函数查找面额在数组中的位置。接着提出使用结构体数组的优化方案,将面额和名称存储在一个结构体内,提高代码的效率和可读性。
摘要由CSDN通过智能技术生成

美元中,penny(一美分)、nickel(5美分)、dime(10美分)、quarter(25美分)、half-dollar(50美分)。  做这样一个程序:输入一个面额,输出面额对应的名称。

数据结构中有一种:散列表(hash table),很适合做这件事。比如将10作为key存入hash表中,对应的value就是dime。  但还没学,先尝试用C语言来解决。

方法一:构建两个数组,在对应的位置上有对应的值。  比如,输入10,得到在这个数组上的位置是2,那么在另一个数组位置2上可以得到dime。

#include <stdio.h>

int amount[] = {1,5,10,25,50}; //定义了一个整形数组amount,里面存储了不同面额的硬币 
const char *name[] = {"penny", "nickel", "dime", "quarter", "half-dollar"};  /*定义了一个字符串指针数组name,
其中数组中的每个元素都是指向一个字符串常量的指针,这些字符串常量是用花括号括起来的一组字符串字面值。
这些字符串分别代表一些硬币的名称。
具体来说, const char *name[] 中:
- const 表示这些字符串是常量,不能被修改。
- char * 表示每个元素是一个指向字符的指针,也可以表示字符串。
- [] 表示这是一个数组,它的每个元素都是指向字符的指针。
- name 是这个数组的名称。
- = {"penny", "nickel", "dime", "quarter", "half-dollar"} 则是在初始化数组。
大括号中的每一个字符串常量依次被赋值给了数组中的元素,也就是每个指针。
因此,可以使用name[0]访问"penny",name[1]访问"nickel",以此类推。

'字符串字面值'指的是一串由双引号包围的字符序列。
在C语言中,字符串字面值的类型是const char[],意味着在程序运行时,字符串字面值的值是不可改变的。
如:"penny"就是一个字符串字面值,它的类型是const char[]。  */ 

int search(int key, int a[], int len) /*`search`函数用于在数组中查找一个值的位置,它接收三个参数:要查找的值 `key`、
要查找的数组 `a`、以及数组长度 `len`。函数使用循环遍历数组,如果找到了目标值,
就将其在数组中的位置作为返回值返回;否则,返回 `-1`。*/ 
{
	int ret = -1;
	for ( int i=0; i<len; i++)
	{
		if ( key == a[i] )
		{
			ret = i;
			break;
		}
	}
	return ret;
}

int main() /*`main` 函数是程序的主要入口。它首先要求用户输入一个面额,
然后调用 `search` 函数查找该面额在 `amount` 数组中的位置。如果找到了,就输出面额对应的名称;否则,输出提示信息。*/
{
	int k;
	printf("请输入面额:");
	scanf("%d", &k); 
	int r = search(k, amount, sizeof(amount)/sizeof(amount[0]));
	if ( r > -1 )
	{
		printf("%s\n", name[r]);  //%s是输出字符串
	} else {
		printf("不在范围内\n");
	}
	
	return 0;
 } 

①如果直接使用char *name[] = {}; 会出现warning:deprecated conversion from string constant to 'char *'       因为char *背后的含义是:给我个字符串,我要修改它。

而理论上,我们传给函数的字面常量是没法被修改的

所以说,比较合理的办法是把参数类型修改为const char *。

这个类型背后的含义是:给我个字符串,我只要读取它。

②割裂的两个数组对高速缓冲存储器(Cache)是不友好的。因此考虑更好的做法。

方法二:希望是一个数组,需要用到结构体,结构体数组

#include <stdio.h>

int amount[] = {1,5,10,25,50}; //定义了一个整形数组amount,里面存储了不同面额的硬币 
const char *name[] = {"penny", "nickel", "dime", "quarter", "half-dollar"};  /*定义了一个常量字符指针数组name,
里面存储了对应面额硬币的名称(是字符串)。 */ 

struct x {
	int amount;
	const char *name;
} coins[] = {
    {1, "penny"},
    {5, "nickel"},
    {10, "dime"},
    {25, "quarter"},
    {50, "half-dollar"}
}; /* 这段代码定义了一个结构体 `x`,其中包含两个成员:`amount` 存储货币的面值(整型),`name` 存储货币的名称(常量字符串指针)。
然后定义了一个长度为5的 `coins` 结构体数组,用于存储不同的硬币。数组元素的类型是结构体 `x`。
`coins[]` 中的初始化列表包含5个元素,每个元素都是一个结构体 `x` 类型的值,对应5种硬币(分别是1分、5分、10分、25分和50分),
并且每个结构体中的 `amount` 和 `name` 成员都用相应的值进行了初始化。
这样就可以通过数组索引的方式访问硬币数组中的元素,并获取对应的硬币面值和名称。
*/ 

int search(int key, int a[], int len) /*`search`函数用于在数组中查找一个值的位置,它接收三个参数:要查找的值 `key`、
要查找的数组 `a`、以及数组长度 `len`。函数使用循环遍历数组,如果找到了目标值,
就将其在数组中的位置作为返回值返回;否则,返回 `-1`。*/ 
{
	int ret = -1;
	for ( int i=0; i<len; i++)
	{
		if ( key == a[i] )
		{
			ret = i;
			break;
		}
	}
	return ret;
}

int main() /*`main` 函数是程序的主要入口。它首先要求用户输入一个面额,
然后调用 `search` 函数查找该面额在 `amount` 数组中的位置。如果找到了,就输出面额对应的名称;否则,输出提示信息。*/
{
	int k;
	printf("请输入面额:");
	scanf("%d", &k); 
	
	for ( int i=0; i<sizeof(coins)/sizeof(coins[0]); i++ ) /* 循环的次数为`sizeof(coins)/sizeof(coins[0])`(也就是`coins`数组的元素个数),
	每循环一次,`i`的值会自增1。循环体中,首先判断`k`是否等于`coins[i].amount`,如果是,就会执行输出`coins[i].name`的语句并跳出循环。
	`coins`数组的类型是一个结构体数组,其中包含`name`和`amount`两个成员,`name`用于存放硬币的名字,`amount`用于存放硬币的面值。
	因此,这段代码的作用是:在`coins`数组中查找面值等于`k`的硬币,并输出该硬币的名称。如果没有找到面值等于`k`的硬币,则不会有任何输出。 */ 
	{
		if ( k == coins[i].amount){
			printf("%s\n", coins[i].name);
			break;
		}
	}
	
	return 0;
 } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值