mercredi 25 novembre 2020

Java if-else for encoding not work properly [duplicate]

So, i'm still developing an Arithmetic Coding to decode and encode

Here's My Code

I encountered Problem When I input Pass == 1 the program just skip everything

import java.util.Scanner;
class ArithmeticCodingFull{
    public static void main(String[] args) {
        Scanner read = new Scanner(System.in);
        char[] symbol       = {'a', 'b', 'c', 'd'}; //Change this if want other words
        double[] probHigh   = {0.2, 0.50, 0.75, 1};
        double[] probLow    = {0, 0.20, 0.50, 0.75};

        System.out.print("Input pass(1/2): ");
        int pass = read.nextInt();

        if (pass == 1){
            System.out.println("\n-----Take a Note This only works for abcd alphabetical words-----");
            System.out.print("Input: ");
            String input = read.nextLine();
            int i_length = input.length();

            int[] I_Entry = InputEntry(symbol, probHigh, probLow, input.toCharArray());

            System.out.println("Arithmetic Encoding: " + ArithmeticCoding(I_Entry, probHigh, probLow));

            double Code = ArithmeticCoding(I_Entry, probHigh, probLow);
            System.out.println("\n-----Encoding/Decoding-----");
            char[] result = ArithmeticDecoding(symbol, probHigh, probLow, i_length, Code);
            System.out.println("Encoded Symbol = " + Code);
            System.out.print("Decoded Symbol = ");

            for (int x = 0; x < i_length; x++) {
                System.out.print(result[x]);
            }
        }
        else if (pass == 2){
            System.out.print("Input String Length:");
            int i_length = read.nextInt();
            System.out.print("Input Your Code(Numeric): ");
            double Code = read.nextDouble();

            char[] result = ArithmeticDecoding(symbol, probHigh, probLow, i_length, Code);

            System.out.println("Probability = " + Code);
            System.out.print("Decoded Symbol = ");

            for (int x = 0; x < i_length; x++) {
                System.out.print(result[x]);
            }
        }
    }
    public static int[] InputEntry(char[] symbol, double[] probHigh, double[] probLow, char[] input){
        int[] I_Entry = new int[input.length];
        for (int x = 0; x < input.length; x++){
            for (int y = 0; y < symbol.length; y++) {
                if (input[x] == symbol[y]){
                    I_Entry[x] = y;
                }
            }
        }
        return I_Entry;
    }
    public static double ArithmeticCoding(int[] I_Entry, double[] probHigh, double[] probLow){
        double[] NewHigh = probHigh;
        double[] NewLow  = probLow;
        double max = 0, min = 0;

        for (int x = 0; x < I_Entry.length; x++){
            max = NewHigh[I_Entry[x]];
            min = NewLow[I_Entry[x]];

            NewLow = UpdateLow(I_Entry, probHigh, probLow, min, x+1);
            NewHigh = UpdateHigh(I_Entry, probHigh, probLow, min, x+1);
        }

        return (max+min)/2;
    }

    public static char[] ArithmeticDecoding (char[] symbol, double[] probHigh, double[] probLow, int i_length, double Code){
        double[] NewHigh = probHigh;
        double[] NewLow  = probLow;
        double max = 0, min = 0;
        int[] I_Entry = new int[i_length];
        char[] result = new char[i_length];

        for (int x = 0; x < i_length; x++){
            for (int y = 0; y < symbol.length; y++){
                if (Code < NewHigh[y] && Code > NewLow[y]){
                    I_Entry[x] = y;
                    result[x] = symbol[y];

                    max = NewHigh[y];
                    min = NewLow[y];

                    NewLow = UpdateLow(I_Entry, probHigh, probLow, min, x + 1);
                    NewHigh = UpdateHigh(I_Entry, probHigh, probLow, min, x + 1);

                    break;
                }
            }
        }

        return result;
    }

    public static double[] UpdateHigh(int[] I_Entry, double[] probHigh, double[] probLow, double min, int c_itteration){
        double[] NewHigh = new double[probHigh.length];
        for (int x = 0; x < probHigh.length; x++) {
            NewHigh[x] = probHigh[x] * Range(I_Entry, probHigh, probLow, c_itteration, 0) + min;
        }

        return NewHigh;
    }

    public static double[] UpdateLow(int[] I_Entry, double[] probHigh, double[] probLow, double min, int c_itteration){
        double[] NewLow = new double[probLow.length];
        for (int x = 0; x < probLow.length; x++) {
            NewLow[x] = probLow[x] * Range(I_Entry, probHigh, probLow, c_itteration, 0) + min;
        }

        return NewLow;
    }

    public static double Range(int[] I_Entry, double[] probHigh, double[] probLow, int c_itteration, int i){
        if (i >= c_itteration) {
            return 1;
        }
        return (probHigh[I_Entry[i]] - probLow[I_Entry[i]]) * Range(I_Entry, probHigh, probLow, c_itteration, i+1);
    }

}

When it is run properly I expect it will be like this below where input (aca) is manual

-----Take a Note This only works for abcd alphabetical words-----
Input: aca
Arithmetic Encoding: 0.10500000000000001

-----Encoding/Decoding-----
Encoded Symbol = 0.10500000000000001
Decoded Symbol = aca
Process finished with exit code 0

But Instead. it is just Skipping everything and resulting in this

-----Take a Note This only works for abcd alphabetical words-----
Input: Arithmetic Encoding: 0.0

-----Encoding/Decoding-----
Encoded Symbol = 0.0
Decoded Symbol = 
Process finished with exit code 0

It is just Skipping the input and goes with 0

How do I fix this? am I forgetting something?

Note: this all happening when I use pass == 1, when it is == 2 it is works properly

Aucun commentaire:

Enregistrer un commentaire