java实现施密特正交化

今天线代课刚学了这个

施密特正交化

然后今天老师布置的作业就是这个
在这里插入图片描述
我这一看,这计算量,就我这计算水平,难免会有算错的

所以就自己写了个程序帮我计算,啊不对,是帮我验证我算的对不对

程序是用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;
    }
}

运行结果:

在这里插入图片描述

最后再提醒一下,用程序计算虽然可以减轻我们的计算负担,但是不要过度依赖程序哦,计算能力和耐心还是要锻炼的。

好了,就这些,不喜勿喷哦

ヾ(≧∪≦*)ノ〃

猜你喜欢

转载自blog.csdn.net/ycx60rzvvbj/article/details/106342575