C++多项式求根程序仅输出一个解,如何修改以输出全部实根
多项式多实根输出修改方案
核心问题说明
你当前的代码仅实现了单起点的牛顿迭代逻辑,本身只能收敛到初始点附近的1个实根,要输出指定区间内的所有实根,按以下步骤修改即可:
第一步:修复现有代码的基础错误
- 你当前将
q = root + 1的赋值逻辑放在了读取root变量之前,属于未定义行为,需要将这行代码移到cin >> root;之后执行 - 输入区间的第二个提示文案错误,将第二个
cout << "Enter the beginning: ";改为cout << "Enter the ending: "; - 所有浮点数相等判断都要替换为绝对值小于误差阈值的逻辑,禁止直接使用
==判断,否则精度误差会导致根的判断出错,你可以提前定义误差常量:const float EPS = 1e-6;,判断根的逻辑改为fabs(algHor(0,results)) < EPS
第二步:增加区间分段扫描逻辑,识别所有含根区间
将你原来的单次牛顿迭代逻辑替换为区间分段扫描+逐段求根+根去重的逻辑,参考代码如下:
#include <vector> // 新增头文件,用于存储多个根 const float STEP = 0.05; // 分段步长,可根据需求调整,步长越小漏根概率越低 vector<float> allRoots; // 扫描整个输入区间 for (float x = beginning; x < ending; x += STEP) { float f_x = algHor(0, x); float f_xnext = algHor(0, x + STEP); // 跳过已识别的根,避免重复存储 if (fabs(f_x) < EPS) { bool isExist = false; for (auto r : allRoots) if (fabs(r - x) < EPS * 10) isExist = true; if (!isExist) allRoots.push_back(x); continue; } if (fabs(f_xnext) < EPS) continue; // 区间两端函数值异号,说明区间内存在实根 if (f_x * f_xnext < 0) { // 选导数绝对值更大的点作为迭代起点,提升收敛速度 float curRes = fabs(derivative(1, x) * f_x) < fabs(derivative(1, x + STEP) * f_xnext) ? x + STEP : x; // 牛顿迭代求解 for (int k = 0; k < iteration; k++) { float f = algHor(0, curRes); float df = derivative(1, curRes); if (fabs(f) < EPS || fabs(df) < EPS) break; // 导数接近0时停止迭代,避免除以0 curRes -= f / df; } // 校验根的有效性并去重 bool isExist = false; for (auto r : allRoots) if (fabs(r - curRes) < EPS * 10) isExist = true; if (!isExist && curRes >= beginning && curRes <= ending && fabs(algHor(0, curRes)) < EPS) { allRoots.push_back(curRes); } } }
第三步:输出所有实根
将你原来的单根输出逻辑替换为遍历存储所有根的容器输出即可:
cout << "\n指定区间内共找到" << allRoots.size() << "个实根:\n"; for (int i = 0; i < allRoots.size(); i++) { cout << "根" << i + 1 << ": " << setprecision(5) << allRoots[i] << endl; }
可选优化(处理重根场景)
如果你的使用场景存在重根,可在每次找到一个根后,用多项式除法将原多项式除以(x - 已找到的根)得到降阶后的多项式,再对降阶多项式重复求根操作,直到多项式阶数为0,即可覆盖重根场景。
内容的提问来源于stack exchange,提问作者user15374677
相关产品推荐
相关产品推荐

