引用chatgpt部分指引作答:
第一题:以下是使用函数指针实现的通用函数代码,计算出给定函数在指定区间上的积分值:
#include <stdio.h>
#include <math.h>
double sigma(double(* fn)(double), double lower, double upper) {
const int n = 100;
const double h = M_PI / n;
double sum = 0.0;
for (int i = 0; i <= n; i++) {
double x = lower + i * h;
sum += fn(x) * h;
}
return sum;
}
double sin_fn(double x) {
return sin(x);
}
double cos_fn(double x) {
return cos(x);
}
int main() {
double sin_integral = sigma(sin_fn, 0.0, M_PI);
double cos_integral = sigma(cos_fn, 0.0, M_PI);
printf("Approximation of sin(x) integral: %f\n", sin_integral);
printf("Approximation of cos(x) integral: %f\n", cos_integral);
return 0;
}
这段代码中,sigma 函数接受一个指向双精度浮点函数的指针 fn、积分区间的下限 lower 和上限 upper 作为参数,并返回函数 fn 在区间 [lower, upper] 上的近似积分值。该函数使用梯形法来计算积分值,将积分区间分为 n 个小段,每个小段的宽度为 h,然后计算每个小段上 fn 函数值的平均值并将其与小段宽度相乘,最后将所有小段的积分值相加得到最终的近似积分值。
在 main 函数中,我们将 sin_fn 和 cos_fn 函数作为参数传递给 sigma 函数来分别计算出函数 sin(x) 和 cos(x) 在区间 [0, π] 上的积分值,并将结果输出到控制台。
第二题:以下是使用C语言循环程序线结构设计实现的代码,计算函数 f(x)=ln(2+x^2)-sin(x) 在给定节点上的函数值并输出到控制台:
#include <stdio.h>
#include <math.h>
double f(double x) {
return log(2 + pow(x, 2)) - sin(x);
}
int main() {
const double lower = 0.0;
const double upper = 2.0;
const int n = 10;
const double h = (upper - lower) / n;
printf("x\tf(x)\n");
for (int i = 0; i <= n; i++) {
double x = i * h;
double fx = f(x);
printf("%.2f\t%.5f\n", x, fx);
}
return 0;
}
这段代码中,我们使用了循环程序线结构设计来计算函数 f(x)=ln(2+x^2)-sin(x) 在给定节点上的函数值,并将结果输出到控制台。具体来说,我们首先定义了区间 [lower, upper] 和节点数 n,然后计算出节点之间的距离 h。在循环中,我们使用变量 i 从 0 循环到 n,在每次循环中计算节点 x_i 和对应的函数值 f(x_i),并将其格式化输出到控制台。最后,我们返回 0 表示程序执行成功。
#include <stdio.h>
#include <math.h>
double sigma(double (*fn)(double), double lower, double upper);
double sin_fn(double x);
double cos_fn(double x);
int main() {
double pi = 3.14159265359;
double si = sigma(sin_fn, 0, pi);
double co = sigma(cos_fn, 0, pi);
printf("The integral of sin(x) from 0 to pi is %f\n", si);
printf("The integral of cos(x) from 0 to pi is %f\n", co);
return 0;
}
double sigma(double (*fn)(double), double lower, double upper) {
int i, N = 100;
double h = (upper - lower) / N;
double sum = 0.0;
for (i = 0; i < N; i++) {
sum += fn(lower + (i + 0.5) * h) * h;
}
return sum;
}
double sin_fn(double x) {
return sin(x);
}
double cos_fn(double x) {
return cos(x);
}
#include <stdio.h>
#include <math.h>
double func(double x);
int main() {
double lower = 0, upper = 2, h = 0.2;
int num_points = (upper - lower) / h + 1; // 计算点的个数
double points[num_points]; // 存放各个点
double values[num_points]; // 存放各个点的函数值
for (int i = 0; i < num_points; i++) {
points[i] = lower + i * h; // 计算点的位置
values[i] = func(points[i]); // 计算对应点上的函数值
printf("%d %f\n", i, values[i]); // 输出对应点的索引和函数值
}
return 0;
}
double func(double x) {
return log(2 + x * x) - sin(x);
}
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这个题目可以使用滑动窗口的思想来解决,具体来说,我们可以使用双指针,即一个左指针和一个右指针,来维护一个窗口。左指针从左端点开始向右移动,右指针从左指针右侧开始向右移动,直到找到一个合法的子串为止。
具体步骤如下:
具体实现参见以下C语言代码:
#include <stdio.h>
#include <string.h>
#define MAXN 100005
char s[MAXN]; // 输入字符串
char p[MAXN]; // 目标子串
int cnt[MAXN]; // 哈希表,用于记录窗口中每个字符出现的次数
int main() {
scanf("%s", s);
scanf("%s", p);
int lenS = strlen(s);
int lenP = strlen(p);
// 统计目标子串中每个字符出现的次数
int target[26] = {0};
for (int i = 0; i < lenP; i++) {
target[p[i] - 'a']++;
}
// 双指针
int left = 0, right = 0;
int hasFound = 0; // 已经找到的目标子串中的字符个数
int minLen = lenS + 1, startPos = 0; // 最小长度和对应的起始位置
while (right < lenS) {
// 如果当前窗口不满足条件,就扩大窗口
if (hasFound < lenP) {
if (cnt[s[right] - 'a'] < target[s[right] - 'a']) {
hasFound++;
}
cnt[s[right] - 'a']++;
right++;
}
// 如果当前窗口满足条件,就缩小窗口
while (hasFound == lenP) {
if (right - left < minLen) {
minLen = right - left;
startPos = left;
}
if (cnt[s[left] - 'a'] == target[s[left] - 'a']) {
hasFound--;
}
cnt[s[left] - 'a']--;
left++;
}
}
if (minLen == lenS + 1) {
printf("No solution.\n");
} else {
s[startPos + minLen] = '\0'; // 注意字符串的末尾要加上'\0',否则可能会输出一些奇怪的字符
printf("%s\n", s + startPos);
}
return 0;
}
时间复杂度为O(n),其中n为字符串长度。
如果我的回答解决了您的问题,请采纳!
void Login()
{
Users a, b;//同理,a是用来给用户输入的,b是用来是水的(从文件中读取到b中,用b和a匹配比较)
FILE* pf = fopen("users.dat", "rb");//以只读的方式打开文件
if (!pf)//如果读取失败
{
printf("%s\n", strerror(errno));//上面有讲过~
return;
}
printf("欢迎来到登录界面!\n");
Sleep(1000);
fread(&b, sizeof(Users), 1, pf);//先从文件中读取一个用户试试水
printf("请输入账号>>");
scanf("%s", a.id);
while (1)
{
if (!strcmp(a.id, b.id))//在文件中找到了与用户输入相同的id
{
break;
}
else
{
if (!feof(pf))//没读到文件末尾,继续读取文件中的id到b中
{
fread(&b, sizeof(Users), 1, pf);//继续从文件中读取用户信息进b,直到在文件中找到一个和a的信息相同的
}
else//读到文件末尾了,没有找到与用户输入相同的账号
{
printf("此账号不存在!请重新输入!\n");
Sleep(500);
fclose(pf);
pf = NULL;
return;
}
}
}
do
{
printf("请输入密码>>");
Getpwd(a.pwd);//获取密码,在下面会讲
if (!strcmp(a.pwd, b.pwd))//输入的密码与文件中的相同
{
printf("\n登录成功!欢迎使用!\n");
Sleep(500);
fclose(pf);//用完当然要把文件关啦
pf = NULL;//置空,避免野指针
return;
}
else
{
printf("\n密码输入错误,请重新输入\n");
}
} while (strcmp(a.pwd, b.pwd));
}
大概思路就是用户先输入账号(id),接着b从文件中读取用户,直到找到与用户输入id相同的,然后就是输入密码判断密码对不对咯。 里面用到了一个库函数strcmp,判断字符串是不是一样的,如果一样则返回0,不一样则返回一个非0值。
很抱歉没有找到您提到的特定题目的算法,如果您能提供更具体的问题描述或题目,则我可以尝试回答。另外,在学习新的算法时,可以结合参考资料和相关文献,多尝试不同的写法和思路,加深自己的理解和掌握程度。同时,注重基础知识的掌握和练习也是至关重要的,可参考参考资料中的例题和练习,不断提升自己的编程能力。