今天线代课刚学了这个
施密特正交化
然后今天老师布置的作业就是这个
我这一看,这计算量,就我这计算水平,难免会有算错的
所以就自己写了个程序帮我计算,啊不对,是帮我验证我算的对不对
程序是用java写的(需要装了jdk才能运行)
!!!只做了正交,单位化暂时还没做,如果以后做出来的话我会再上传的
想用可以直接把代码复制粘贴过去就能用了,如果想看怎么实现的话,我觉得我写的注释应该能看得懂,哈哈哈,如果有什么疑问的话,可以在评论区留言哦
那废话不多说
代码如下:
/*
本篇代码的命名极其的不规范(!!!请勿参考!!!)
英语不好,又懒得去百度翻译,所以好多命名就都是拼音,哈哈哈
*/
import java.util.Scanner;
/**
* <p><b>类名:</b>{@code Test}
* <p><b>功能:</b><br>用来测试和运行
*
* @author 60rzvvbj
* @data 2020/5/25
*/
class Test {
public static void main(String[] args) {
Shimitezhengjiao shimitezhengjiao = new Shimitezhengjiao();
shimitezhengjiao.on();
}
}
/**
* <p><b>类名:</b>{@code Shimitezhengjiao}
* <p><b>功能:</b><br>将向量组施密特正交化
* <p><b>方法:</b>
* <br>{@link #Shimitezhengjiao()}无参构造
* <br>{@link #on()}启动
*
* @author 60rzvvbj
* @data 2020/5/25
*/
public class Shimitezhengjiao {
Shimitezhengjiao() {
//啥也没写,哈哈哈
}
/**
* <p><b>方法名:</b>{@code on}
* <p><b>功能:</b><br>启动
*
* @author 60rzvvbj
* @data 2020/5/25
*/
public void on() {
Scanner sca = new Scanner(System.in);
//先打印几句废话
System.out.println("欢迎使用!");
System.out.println("本程序可以利用施密特正交化方法,将向量组化为正交的向量组(单位化还在开发中)");
System.out.println("作者: 60rzvvbj\n");
while (true) {
//提示语
System.out.println("请输入向量组中向量组的个数:");
int n = sca.nextInt();
sca.nextLine();
System.out.println("请输入向量组:");
//创建两个组向量,阿尔法和贝塔
XiangLiang[] aErfa = new XiangLiang[n];
XiangLiang[] beiTa = new XiangLiang[n];
//输入值
for (int i = 0; i < n; i++) {
String t = sca.nextLine();
aErfa[i] = new XiangLiang(t);
beiTa[i] = new XiangLiang(t);
}
//打印向量组阿尔法
System.out.println("输入的向量组为:");
for (int i = 0; i < n; i++) {
System.out.println("a" + (i + 1) + ":\t" + aErfa[i]);
}
//用施密特正交计算贝塔
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
beiTa[i] = beiTa[i].jian(beiTa[j].shuCheng((aErfa[i].shuLiangJi(beiTa[j])).chu(beiTa[j].shuLiangJi(beiTa[j]))));
}
}
//打印向量组贝塔
System.out.println("\n正交向量组为:");
for (int i = 0; i < n; i++) {
System.out.println("b" + (i + 1) + ":\t" + beiTa[i]);
}
//是否继续
System.out.println("\n按1继续,其它键退出");
String t = sca.nextLine();
if (!"1".equals(t)) {
break;
}
}
//释放资源
sca.close();
//卖一波萌
System.out.println("谢谢使用!\nヾ(≧∪≦*)ノ〃");
}
}
/**
* <p><b>类名:</b>{@code Fenshi}
* <p><b>功能:</b><br>分式类
* <p><b>方法:</b>
* <br>{@link #Fenshi(int)}构造方法(int)
* <br>{@link #Fenshi(Fenshi)}构造方法(Fenshi)
* <br>{@link #Fenshi(String)}构造方法(String)
* <br>{@link #getFenzi()}获取分子
* <br>{@link #getFenmu()}获取分母
* <br>{@link #toString()}重写的toString方法
* <br>{@link #jia(Fenshi)}加法
* <br>{@link #jian(Fenshi)}减法
* <br>{@link #cheng(Fenshi)}乘法
* <br>{@link #chu(Fenshi)}除法,除数为0会抛异常
*
* @author 60rzvvbj
* @data 2020/5/25
*/
class Fenshi {
/**
* 分子
*/
private int fenzi;
/**
* 分母
*/
private int fenmu;
/**
* 正负号(true为正,false为负)
*/
private boolean zhengfu = true;
/**
* <p><b>方法名:</b>{@code Fenshi}
* <p><b>功能:</b><br>用字符串创建一个分式,字符串格式为(-)+分子+/+分母
*
* @param str 满足分式格式的字符串
* @author 60rzvvbj
* @data 2020/5/25
*/
public Fenshi(String str) {
//用'/'分割字符串
String[] zm = str.split("/");
//分割后第一个转化成分子
fenzi = Integer.parseInt(zm[0]);
//调整正负号
if (fenzi < 0) {
fenzi = -fenzi;
zhengfu = false;
}
//如果有第二个,则把第二个转化成分母,如果没有,则分母为1
fenmu = zm.length == 2 ? Integer.parseInt(zm[1]) : 1;
//调整正负号
if (fenmu < 0) {
fenmu = -fenmu;
zhengfu = !zhengfu;
}
//约分
yueFen();
}
/**
* <p><b>方法名:</b>{@code Fenshi}
* <p><b>功能:</b><br>用一个分式创建一个新的分式
*
* @param f 分式
* @author 60rzvvbj
* @data 2020/5/25
*/
public Fenshi(Fenshi f) {
//将分子和分母赋值
fenzi = f.getFenzi();
fenmu = f.getFenmu();
//调整正负号
if (fenzi < 0) {
fenzi = -fenzi;
zhengfu = false;
}
}
/**
* <p><b>方法名:</b>{@code Fenshi}
* <p><b>功能:</b><br>将一个整数转化成分式
*
* @param x 整数
* @author 60rzvvbj
* @data 2020/5/25
*/
public Fenshi(int x) {
//调整正负号,分子赋值分母为1
if (x < 0) {
fenzi = -x;
zhengfu = false;
} else {
fenzi = x;
}
fenmu = 1;
}
/**
* <p><b>方法名:</b>{@code yueFen}
* <p><b>功能:</b><br>将分式约分
*
* @author 60rzvvbj
* @data 2020/5/25
*/
private void yueFen() {
//如果分子为0的话,直接把分母变成1
if (fenzi == 0) {
fenmu = 1;
return;
}
//当分子分母都不是1的时候才约分,否则没必要约
if (!(fenzi == 1 || fenmu == 1)) {
int t = Tool.gcd(fenzi, fenmu);
fenzi /= t;
fenmu /= t;
}
}
/**
* <p><b>方法名:</b>{@code toString}
* <p><b>功能:</b><br>将分式转化成字符串
*
* @author 60rzvvbj
* @data 2020/5/25
*/
@Override
public String toString() {
return (zhengfu ? "" : "-") + (fenmu == 1 ? fenzi : fenzi + "/" + fenmu);
}
/**
* <p><b>方法名:</b>{@code getFenzi}
* <p><b>功能:</b><br>获取分子
*
* @author 60rzvvbj
* @data 2020/5/25
*/
public int getFenzi() {
return zhengfu ? fenzi : -fenzi;
}
/**
* <p><b>方法名:</b>{@code getFenmu}
* <p><b>功能:</b><br>获取分母
*
* @author 60rzvvbj
* @data 2020/5/25
*/
public int getFenmu() {
return fenmu;
}
/**
* <p><b>方法名:</b>{@code jia}
* <p><b>功能:</b><br>返回this与x的和
*
* @param x 加数
* @author 60rzvvbj
* @data 2020/5/25
*/
public Fenshi jia(Fenshi x) {
//分子直接交叉相成在相加,分母是原来两个数的分母相乘
return new Fenshi((this.getFenzi() * x.getFenmu() + x.getFenzi() * fenmu) + "/" + (fenmu * x.getFenmu()));
}
/**
* <p><b>方法名:</b>{@code jian}
* <p><b>功能:</b><br>返回this与x的差
*
* @param x 减数
* @author 60rzvvbj
* @data 2020/5/25
*/
public Fenshi jian(Fenshi x) {
//分子直接交叉相成在相减,分母是原来两个数的分母相乘
return new Fenshi((this.getFenzi() * x.getFenmu() - fenmu * x.getFenzi()) + "/" + (fenmu * x.getFenmu()));
}
/**
* <p><b>方法名:</b>{@code cheng}
* <p><b>功能:</b><br>返回this与x的积
*
* @param x 乘数
* @author 60rzvvbj
* @data 2020/5/25
*/
public Fenshi cheng(Fenshi x) {
//分子相乘,分母相乘
return new Fenshi((this.getFenzi() * x.getFenzi()) + "/" + (fenmu * x.getFenmu()));
}
/**
* <p><b>方法名:</b>{@code jia}
* <p><b>功能:</b><br>返回this与x的商,除数为0会抛出异常
*
* @param x 除数
* @author 60rzvvbj
* @data 2020/5/25
*/
public Fenshi chu(Fenshi x) {
//如果除数为0则抛出异常
if (x.getFenzi() == 0) {
throw new ArithmeticException("除数不能为0");
}
//除就是乘倒数
return new Fenshi((this.getFenzi() * x.getFenmu()) + "/" + (fenmu * x.getFenzi()));
}
}
/**
* <p><b>类名:</b>{@code XiangLiang}
* <p><b>功能:</b><br>向量类,里面的坐标是分式
* <p><b>方法:</b>
* <br>{@link #XiangLiang(String)}构造方法(String)
* <br>{@link #XiangLiang(Fenshi[])}构造方法(Fenshi[])
* <br>{@link #getFenshi(int)}获取分式数组中某个分式
* <br>{@link #getFenshis()}获取分式数组
* <br>{@link #toString()}重写的toString方法
* <br>{@link #jia(XiangLiang)}向量加法
* <br>{@link #jian(XiangLiang)}向量减法
* <br>{@link #shuCheng(Fenshi)}向量数乘
* <br>{@link #shuLiangJi(XiangLiang)}求数量积
*
* @author 60rzvvbj
* @data 2020/5/25
*/
class XiangLiang {
/**
* 保存向量值的分式数组
*/
private final Fenshi[] fenshis;
/**
* <p><b>方法名:</b>{@code XiangLiang}
* <p><b>功能:</b><br>用字符串构造一个向量,字符串格式为 分式 分式 ... 分式 ,分式之间用空格隔开
*
* @param str 满足向量格式的字符串
* @author 60rzvvbj
* @data 2020/5/25
*/
public XiangLiang(String str) {
//用空格分割字符串
String[] t = str.split(" ");
//用分割出来的字符串数组对分式数组赋值
fenshis = new Fenshi[t.length];
for (int i = 0; i < t.length; i++) {
fenshis[i] = new Fenshi(t[i]);
}
}
/**
* <p><b>方法名:</b>{@code XiangLiang}
* <p><b>功能:</b><br>用分式数组构造向量
*
* @param f 分式数组
* @author 60rzvvbj
* @data 2020/5/25
*/
public XiangLiang(Fenshi[] f) {
//直接复制一份分式数组
fenshis = new Fenshi[f.length];
for (int i = 0; i < f.length; i++) {
fenshis[i] = new Fenshi(f[i]);
}
}
/**
* <p><b>方法名:</b>{@code toString}
* <p><b>功能:</b><br>将向量转化成字符串格式
*
* @author 60rzvvbj
* @data 2020/5/25
*/
@Override
public String toString() {
String str = "(";
for (int i = 0; i < fenshis.length; i++) {
str += fenshis[i] + ",";
}
str = str.substring(0, str.length() - 1);
str += ")";
return str;
}
/**
* <p><b>方法名:</b>{@code getFenshi}
* <p><b>功能:</b><br>获取分是数组中某个分式
*
* @param index 要获取的分式的索引
* @author 60rzvvbj
* @data 2020/5/25
*/
public Fenshi getFenshi(int index) {
return fenshis[index];
}
/**
* <p><b>方法名:</b>{@code getFenshis}
* <p><b>功能:</b><br>获取整个分式数组
*
* @author 60rzvvbj
* @data 2020/5/25
*/
public Fenshi[] getFenshis() {
return fenshis;
}
/**
* <p><b>方法名:</b>{@code jia}
* <p><b>功能:</b><br>返回当前向量与向量x相加后的结果
*
* @param x 向量x
* @author 60rzvvbj
* @data 2020/5/25
*/
public XiangLiang jia(XiangLiang x) {
//对应分量相加
Fenshi[] t = new Fenshi[fenshis.length];
for (int i = 0; i < fenshis.length; i++) {
t[i] = fenshis[i].jia(x.getFenshi(i));
}
return new XiangLiang(t);
}
/**
* <p><b>方法名:</b>{@code jian}
* <p><b>功能:</b><br>返回当前向量与向量x相减后的结果
*
* @param x 向量x
* @author 60rzvvbj
* @data 2020/5/25
*/
public XiangLiang jian(XiangLiang x) {
//对应分量相减
Fenshi[] t = new Fenshi[fenshis.length];
for (int i = 0; i < fenshis.length; i++) {
t[i] = fenshis[i].jian(x.getFenshi(i));
}
return new XiangLiang(t);
}
/**
* <p><b>方法名:</b>{@code shuCheng}
* <p><b>功能:</b><br>返回当前向量与分式f数乘后的结果
*
* @param f 分式f
* @author 60rzvvbj
* @data 2020/5/25
*/
public XiangLiang shuCheng(Fenshi f) {
//每个分量都乘f
Fenshi[] t = new Fenshi[fenshis.length];
for (int i = 0; i < fenshis.length; i++) {
t[i] = fenshis[i].cheng(f);
}
return new XiangLiang(t);
}
/**
* <p><b>方法名:</b>{@code shuLiangJi}
* <p><b>功能:</b><br>返回当前向量与向量x的数量积
*
* @param x 向量x
* @author 60rzvvbj
* @data 2020/5/25
*/
public Fenshi shuLiangJi(XiangLiang x) {
//对应分量相乘在相加
Fenshi t = new Fenshi(0);
for (int i = 0; i < fenshis.length; i++) {
t = t.jia(fenshis[i].cheng(x.getFenshi(i)));
}
return t;
}
}
/**
* <p><b>类名:</b>{@code Tool}
* <p><b>功能:</b><br>工具类
* <p><b>方法:</b>
* <br>{@link #gcd(int, int)}返回两个数的最大公约数
*
* @author 60rzvvbj
* @data 2020/5/25
*/
class Tool {
/**
* <p><b>方法名:</b>{@code gcd}
* <p><b>功能:</b><br>返回两个数的最大公约数
*
* @param a 第一个数
* @param b 第二个数
* @author 60rzvvbj
* @data 2020/5/25
*/
public static int gcd(int a, int b) {
//让a<b
if (a > b) {
a ^= b;
b ^= a;
a ^= b;
}
//然后遍历a到1
for (int i = a; i >= 1; i--) {
if (a % i == 0 && b % i == 0) {
return i;
}
}
return 0;
}
}
运行结果:
最后再提醒一下,用程序计算虽然可以减轻我们的计算负担,但是不要过度依赖程序哦,计算能力和耐心还是要锻炼的。
好了,就这些,不喜勿喷哦
ヾ(≧∪≦*)ノ〃