专栏文章

求函数值域

学习·文化课参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@minqouhh
此快照首次捕获于
2025/12/02 06:47
3 个月前
此快照最后确认于
2025/12/02 06:47
3 个月前
查看原文
CPP
#include <iostream>
#include <cmath>
#include <string>
#include <chrono>
#include <iomanip>
#include <algorithm>

using namespace std;
using namespace chrono;

// 显示函数类型对应表
void printFunctionTypes() {
	cout << "函数类型对应表:" << endl;
	cout << "1: 一次函数 (y = kx + b)" << endl;
	cout << "2: 二次函数 (y = ax2 + bx + c)" << endl;
	cout << "3: 三次函数 (y = ax3 + bx2 + cx + d)" << endl;
	cout << "4: 绝对值函数 (y = |kx + b| + c)" << endl;
	cout << "5: 幂函数 (y = x^a)" << endl;
	cout << "6: 指数函数 (y = a^x + b)" << endl;
	cout << "7: 对数函数 (y = log_a(x) + b)" << endl;
	cout << "8: 对勾函数 (y = x + a/x)" << endl;
	cout << "9: 反比例函数 (y = k/x + b)" << endl;
}

// 计算函数在x处的值
double calculateFunction(int funcType, double params[], double x) {
	switch(funcType) {
		case 1:
			return params[0] * x + params[1]; // 一次函数
		case 2:
			return params[0] * x * x + params[1] * x + params[2]; // 二次函数
		case 3:
			return params[0] * x * x * x + params[1] * x * x + params[2] * x + params[3]; // 三次函数
		case 4:
			return fabs(params[0] * x + params[1]) + params[2]; // 绝对值函数
		case 5:
			return pow(x, params[0]); // 幂函数
		case 6:
			return pow(params[0], x) + params[1]; // 指数函数
		case 7:
			return log(x) / log(params[0]) + params[1]; // 对数函数
		case 8:
			return x + params[0] / x; // 对勾函数
		case 9:
			return params[0] / x + params[1]; // 反比例函数
		default:
			return 0;
	}
}

// 检查x是否在区间内
bool isInInterval(double x, double interval[]) {
	return x >= interval[0] && x <= interval[1];
}

// 根据函数类型、参数和区间计算值域
string getIntervalRange(int funcType, double params[], double interval[]) {
	double a = interval[0];
	double b = interval[1];
	double minVal, maxVal;
	bool first = true;

	// 特殊点集合(端点和可能的极值点)
	vector<double> criticalPoints;
	criticalPoints.push_back(a);
	criticalPoints.push_back(b);

	// 根据函数类型添加可能的极值点
	switch(funcType) {
		case 1: {
			// 一次函数 - 单调,只需端点
			break;
		}

		case 2: {
			// 二次函数 - 顶点为极值点
			double a_coeff = params[0];
			double b_coeff = params[1];
			if (a_coeff != 0) {
				double vertexX = -b_coeff / (2 * a_coeff);
				if (isInInterval(vertexX, interval)) {
					criticalPoints.push_back(vertexX);
				}
			}
			break;
		}

		case 3: {
			// 三次函数 - 可能有两个极值点
			double a_coeff = params[0];
			double b_coeff = params[1];
			double c_coeff = params[2];
			if (a_coeff != 0) {
				double discriminant = b_coeff * b_coeff - 3 * a_coeff * c_coeff;
				if (discriminant > 0) {
					double sqrtD = sqrt(discriminant);
					double x1 = (-b_coeff - sqrtD) / (3 * a_coeff);
					double x2 = (-b_coeff + sqrtD) / (3 * a_coeff);

					if (isInInterval(x1, interval)) {
						criticalPoints.push_back(x1);
					}
					if (isInInterval(x2, interval)) {
						criticalPoints.push_back(x2);
					}
				}
			}
			break;
		}

		case 4: {
			// 绝对值函数 - 转折点
			double k = params[0];
			double b_coeff = params[1];
			if (k != 0) {
				double turningPoint = -b_coeff / k;
				if (isInInterval(turningPoint, interval)) {
					criticalPoints.push_back(turningPoint);
				}
			}
			break;
		}

		case 5: {
			// 幂函数 - 可能在0点有极值
			double exponent = params[0];
			if (exponent != 1 && isInInterval(0, interval)) {
				criticalPoints.push_back(0);
			}
			break;
		}

		case 8: {
			// 对勾函数 - 极值点
			double coeff = params[0];
			if (coeff > 0) {
				double x1 = sqrt(coeff);
				double x2 = -sqrt(coeff);
				if (isInInterval(x1, interval)) {
					criticalPoints.push_back(x1);
				}
				if (isInInterval(x2, interval)) {
					criticalPoints.push_back(x2);
				}
			}
			break;
		}

		case 9: {
			// 反比例函数 - 渐近线x=0
			if (a < 0 && b > 0) {
				// 区间包含奇点,需要分开处理
				// 这里简化处理,只检查端点
				break;
			}
			break;
		}
	}

	// 计算所有特殊点的函数值,找到最大值和最小值
	for (double x : criticalPoints) {
		// 检查函数定义域
		if ((funcType == 7 && x <= 0) ||  // 对数函数定义域
		        (funcType == 8 && x == 0) ||   // 对勾函数x不能为0
		        (funcType == 9 && x == 0)) {   // 反比例函数x不能为0
			continue;
		}

		double y = calculateFunction(funcType, params, x);
		if (first) {
			minVal = y;
			maxVal = y;
			first = false;
		} else {
			if (y < minVal) minVal = y;
			if (y > maxVal) maxVal = y;
		}
	}

	// 如果没有有效点(定义域问题)
	if (first) {
		return "在指定区间内函数无定义";
	}

	// 处理反比例函数特殊情况(区间包含奇点)
	if (funcType == 9 && params[0] != 0 && a < 0 && b > 0) {
		return "(-∞, +∞)"; // 区间包含奇点时,反比例函数值域为全体实数
	}

	// 格式化输出
	stringstream ss;
	ss << fixed << setprecision(4);
	ss << "[" << minVal << ", " << maxVal << "]";
	return ss.str();
}

// 计算整个定义域上的值域
string getGlobalRange(int funcType, double params[]) {
	switch(funcType) {
		case 1: {
			double k = params[0], b = params[1];
			if (k == 0) {
				return "{" + to_string(b) + "}";
			} else {
				return "(-∞, +∞)";
			}
		}

		case 2: {
			double a = params[0], b = params[1], c = params[2];
			if (a == 0) {
				double tempParams[2] = {b, c};
				return getGlobalRange(1, tempParams);
			}

			double vertexY = (4*a*c - b*b) / (4*a);
			stringstream ss;
			ss << fixed << setprecision(4) << vertexY;
			if (a > 0) {
				return "[" + ss.str() + ", +∞)";
			} else {
				return "(-∞, " + ss.str() + "]";
			}
		}

		case 3:
			return "(-∞, +∞)";

		case 4: {
			double k = params[0], b = params[1], c = params[2];
			if (k == 0) {
				return "{" + to_string(fabs(b) + c) + "}";
			} else {
				return "[" + to_string(c) + ", +∞)";
			}
		}

		case 5: {
			double a = params[0];
			if (a > 0) {
				return "[0, +∞)";
			} else if (a < 0) {
				return "(0, +∞)";
			} else {
				return "{1}";
			}
		}

		case 6: {
			double a = params[0], b = params[1];
			if (a <= 0 || a == 1) {
				return "无效的底数,指数函数底数需满足a > 0且a ≠ 1";
			}
			return "(" + to_string(b) + ", +∞)";
		}

		case 7: {
			double a = params[0], b = params[1];
			if (a <= 0 || a == 1) {
				return "无效的底数,对数函数底数需满足a > 0且a ≠ 1";
			}
			return "(-∞, +∞)";
		}

		case 8: {
			double a = params[0];
			if (a > 0) {
				double sqrtA = sqrt(a);
				stringstream ss;
				ss << fixed << setprecision(4) << -2*sqrtA << ", " << 2*sqrtA;
				return "(-∞, " + to_string(-2*sqrtA) + "] ∪ [" + to_string(2*sqrtA) + ", +∞)";
			} else if (a < 0) {
				return "(-∞, +∞)";
			} else {
				return "(-∞, +∞)";
			}
		}

		case 9: {
			double k = params[0], b = params[1];
			if (k == 0) {
				return "{" + to_string(b) + "}";
			}
			return "(-∞, " + to_string(b) + ") ∪ (" + to_string(b) + ", +∞)";
		}

		default:
			return "无效的函数类型";
	}
}

int main() {
	auto startTime = high_resolution_clock::now();

	// 显示函数类型
	printFunctionTypes();

	// 获取用户输入的函数类型
	int funcType;
	cout << "\n请输入函数类型的序号 (1-9): ";
	cin >> funcType;

	if (cin.fail() || funcType < 1 || funcType > 9) {
		cout << "请输入1-9之间的有效数字" << endl;
		return 1;
	}
	// 获取区间
	cout<<"\n请问是否求区间? 1.是 0.否"<<endl;
	int opp;
	cin>>opp;
	double interval[2];
	if(opp==1) {
		cout << "请输入x的取值区间 [a, b]" << endl;
		cout << "a = ";
		cin >> interval[0];
		cout << "b = ";
		cin >> interval[1];
		if (cin.fail() || interval[0] > interval[1]) {
			cout << "请输入有效的区间 (a ≤ b)" << endl;
			return 1;
		}
	}
	// 根据函数类型获取参数
	double params[4];  // 最多需要4个参数
	bool inputValid = true;

	try {
		if (funcType == 1) {
			// 一次函数:k, b
			cout << "请输入k的值: ";
			cin >> params[0];
			cout << "请输入b的值: ";
			cin >> params[1];
		} else if (funcType == 2) {
			// 二次函数:a, b, c
			cout << "请输入a的值: ";
			cin >> params[0];
			cout << "请输入b的值: ";
			cin >> params[1];
			cout << "请输入c的值: ";
			cin >> params[2];
		} else if (funcType == 3) {
			// 三次函数:a, b, c, d
			cout << "请输入a的值: ";
			cin >> params[0];
			cout << "请输入b的值: ";
			cin >> params[1];
			cout << "请输入c的值: ";
			cin >> params[2];
			cout << "请输入d的值: ";
			cin >> params[3];
		} else if (funcType == 4) {
			// 绝对值函数:k, b, c
			cout << "请输入k的值: ";
			cin >> params[0];
			cout << "请输入b的值: ";
			cin >> params[1];
			cout << "请输入c的值: ";
			cin >> params[2];
		} else if (funcType == 5) {
			// 幂函数:a
			cout << "请输入指数a的值: ";
			cin >> params[0];
		} else if (funcType == 6) {
			// 指数函数:a, b
			cout << "请输入底数a的值 (a > 0且a ≠ 1): ";
			cin >> params[0];
			cout << "请输入b的值: ";
			cin >> params[1];
		} else if (funcType == 7) {
			// 对数函数:a, b
			cout << "请输入底数a的值 (a > 0且a ≠ 1): ";
			cin >> params[0];
			cout << "请输入b的值: ";
			cin >> params[1];

			// 检查对数函数区间有效性
			if (interval[0] <= 0) {
				cout << "警告:对数函数定义域为x > 0,区间将自动调整为(" << max(interval[0], 1e-9) << ", " << interval[1] << "]" << endl;
				interval[0] = max(interval[0], 1e-9);
			}
		} else if (funcType == 8) {
			// 对勾函数:a
			cout << "请输入a的值: ";
			cin >> params[0];

			// 检查对勾函数区间有效性
			if (interval[0] <= 0 && interval[1] >= 0) {
				cout << "警告:对勾函数在x=0处无定义,区间包含0点可能导致结果不准确" << endl;
			}
		} else if (funcType == 9) {
			// 反比例函数:k, b
			cout << "请输入k的值 (k ≠ 0): ";
			cin >> params[0];
			cout << "请输入b的值: ";
			cin >> params[1];

			// 检查反比例函数区间有效性
			if (interval[0] <= 0 && interval[1] >= 0) {
				cout << "警告:反比例函数在x=0处无定义,区间包含0点" << endl;
			}
		}
		if (cin.fail()) {
			printf("输入无效\n");
		}
	} catch (...) {
		cout << "请输入有效的数字参数" << endl;
		return 1;
	}
	// 计算并显示值域
	if(opp==0){
		string globalResult = getGlobalRange(funcType, params);
		cout << "\n函数的全局值域为: " << globalResult << endl;
	}
	else{
	    string intervalResult = getIntervalRange(funcType, params, interval);
		cout << "函数在区间[" << interval[0] << ", " << interval[1] << "]内的值域为: " << intervalResult << endl;
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...