在做头歌平台的程序题时可以用getchar来依次获取字符吗
在编写音乐播放平台的程序时,一般不会直接使用 getchar
来获取用户输入的字符,尤其是涉及到歌曲名称、歌手名等较长的文本输入。这是因为 getchar
主要是设计用于交互式命令行环境下的单个字符输入,适合于接收用户的一个个输入指令,而不是批量输入长字符串。
对于这类需求,你会更倾向于使用 fgets
函数(或者其他字符串输入函数),它一次可以从标准输入流(如键盘)读取一行字符串,包括空格和其他特殊字符。例如:
#include <stdio.h>
#define MAX_LINE_LENGTH 100 // 设置最大输入长度
void getSongInput(char song[], int max_length) {
fgets(song, max_length, stdin);
song[strlen(song)-1] = '\0'; // 去除末尾的换行符
}
int main() {
char song[MAX_LINE_LENGTH];
getSongInput(song, MAX_LINE_LENGTH);
printf("用户输入的歌曲名: %s\n", song);
return 0;
}
上述代码中,getSongInput
函数会获取用户的一行输入,并将其存储到 song
字符数组中。
算法设计与分析(第二章 贪心算法作业1-必做头歌
贪心算法第二章必做题目分析与设计
贪心算法是一种通过一系列局部最优选择来达到全局最优解的策略。它通常用于解决优化问题,在某些特定条件下能够提供高效的解决方案[^3]。以下是关于贪心算法第二章可能涉及的一些典型作业题及其分析。
1. 活动选择问题
这是一个典型的贪心算法应用案例,目标是从一组活动中选出最大数量的互不冲突的活动集合。假设每项活动都有一个开始时间和结束时间,则可以通过按结束时间排序并依次选取最早结束且与已选活动无冲突的活动来解决问题[^4]。
def activity_selection(activities):
activities.sort(key=lambda x: x[1]) # 按照结束时间排序
selected = []
last_end_time = float('-inf')
for start, end in activities:
if start >= last_end_time:
selected.append((start, end))
last_end_time = end
return selected
此代码实现了基于贪心原则的活动选择方法。
2. 区间覆盖问题
给定一条线段以及若干条较短的小线段,如何用最少的数量完全覆盖这条长线?可以将所有小线段按照右端点升序排列,然后从左至右扫描整个区域,每次都尝试找到能延伸最远距离的一段作为候选者加入最终方案中去[^5]。
3. 硬币找零问题
假设有几种不同面值的钱币无限供应量,问怎样凑成指定金额所需的总枚数最少? 这里需要注意的是并非所有的货币体系都适合采用简单的贪婪法则;只有当存在某种特殊关系时才可以直接运用这种方法得出正确结论。
def coin_change(coins, amount):
coins.sort(reverse=True)
count = 0
for coin in coins:
if amount == 0:
break
num_coins = amount // coin
count += num_coins
amount -= num_coins * coin
return count if amount == 0 else -1
上述函数展示了利用贪心思路解决硬币兑换难题的过程。
4. 装载问题
考虑一艘船的最大载重量W及N件物品各自的重量wi(i=1,...n),试确定能否把这些货物全部装入船上而不超重。如果允许拆分单个物体的话则可转化为分数背包形式处理; 否则需借助其他更复杂的手段比如回溯法或者分支限界法等进一步探讨最佳组合方式。
Status InsFirst(LinkList *L, Link h, Link s) /* 形参增加L,因为需修改L */ { /* h指向L的一个结点,把h当做头结点,将s所指结点插入在第一个结点之前 */ s->next = h->next; h->next = s; if (h == (*L).tail) /* h指向尾结点 */ (*L).tail = h->next; /* 修改尾指针 */ (*L).len++; return OK; } Position GetHead(LinkList L) { /* 返回线性链表L中头结点的位置 */ return L.head; } Status SetCurElem(Link p, ElemType e) { /* 已知p指向线性链表中的一个结点,用e更新p所指结点中数据元素的值 */ p->data = e; return OK; }
这段代码是关于线性链表的操作。
函数InsFirst
接受一个指向指针的指针L
,一个指向要插入位置前一个节点的指针h
,和一个要插入的节点指针s
作为参数。它将要插入的节点s
的next指针指向节点h->next
,然后将节点h
的next指针指向节点s
,这样就完成了在第一个节点之前插入新节点的操作。如果节点h
是链表的尾节点,则需要修改链表的尾指针为节点s
。最后,将链表的长度加1,并返回一个代表成功的状态值。
函数GetHead
接受一个线性链表L
作为参数,返回线性链表的头结点位置。
函数SetCurElem
接受一个指向节点的指针p
和要更新的元素e
作为参数,将节点p
的数据域更新为元素e
,并返回一个代表成功的状态值。
这些函数都是对线性链表进行操作的函数,可以完成链表的插入、获取头结点和更新节点数据等功能。需要注意的是,在使用这些函数之前,需要先创建一个空的线性链表,并将其头结点赋值给相应的指针变量。
相关推荐












