Search code examples
javaalgorithmexponentsuperscriptfactorization

Prime factorization with superscript exponents java


I would like to have my outputs from my Prime Factorization module in my calculator program to be in this form: 247500 = 2² · 3² · 5⁴ · 11 instead of 2^2 * 3^2 * 5^4 * 11 or 2 2 3 3 5 5 5 5 11.

The problem is that due to my extremely limited programming knowledge, my implementation of exponent sorting and displaying slows my program down "exponentially" (pun intended) for larger numbers. I have tried to find a more efficient way of doing the operation, but cannot find any other way.

I devised the following method...it works, but its very slow. I apologize if conventions are not being followed (I am a learner programmer).

The prime numbers are stored in the array FACTOR[c]...I'm using BigInteger in my factorization module.

if (counter == 0) {
                            
  OUTPUT = "prime number";
                            
}
                        
else {
                            
  OUTPUT = OUTPUT + FACTOR[c];
  c ++;
                            
  do {
                                
     if (FACTOR[c].compareTo(FACTOR[c-1]) == 0) {
                                    
       exponent++;
                                    
       if (c == counter) {  // condition if the number with exponent is the last in derivation.
                                        
      exp = String.valueOf(exponent);
      str.conversion (exp);
                                        
      OUTPUT = OUTPUT + exp;
      break;
                                        
       }
                                    
     }
                            
     else if (((FACTOR[c].compareTo(FACTOR[c-1]) == 1 || (FACTOR[c].compareTo(FACTOR[c-1]) ==  -1))&& exponent > 1)) {
    
       if (c == counter) {  // condition if the number with exponent is the last in derivation.
                                        
         exp = String.valueOf(exponent);
         str.conversion (exp);
                                        
         OUTPUT = OUTPUT + exp + " · " + FACTOR[c];
                                        
         break;
                                        
       }
                                    
       exp = String.valueOf(exponent);
       str.conversion (exp);
                                    
       OUTPUT = OUTPUT + exp + " · " + FACTOR[c];
                                    
       exponent = 1;
                                
    }
                            
    else if (((FACTOR[c].compareTo(FACTOR[c-1]) == 1 || (FACTOR[c].compareTo(FACTOR[c-1]) == -1)) && exponent == 1)) {
                                    
     OUTPUT = OUTPUT + " · " + String.valueOf(FACTOR[c]);
                                
     }
                            
     c++;
                                
  } while (c!= counter+1);
                            
}
                        
answer = firstword + " = " + OUTPUT;

class Convtonum {
    
    void conversion (String str) {
        
            // Converts 0-9 numbers into superscript form
            str = str.replaceAll("0", "\u2070");
        str = str.replaceAll("1", "\u00b9");
        str = str.replaceAll("2", "\u00b2");
        str = str.replaceAll("3", "\u00b3");
        str = str.replaceAll("4", "\u2074");
        str = str.replaceAll("5", "\u2075");
        str = str.replaceAll("6", "\u2076");
        str = str.replaceAll("7", "\u2077");
        str = str.replaceAll("8", "\u2078");
        str = str.replaceAll("9", "\u2079");       

        CALCULATOR.exp = str;
        
    }

}

How could this be made to be more faster / efficient?


Solution

  • It would be useful to show more of your code in an Minimal, Reproducible Example

    One specific problem is that you try to replace a digit with the unicode value whether that digit is present or not. There may be better solutions than the following but this processes the digits in the exponent as ints and limits the string handling.

    Store the symbols in a list, in order of their index.

    static List<String> sups = List.of("\u2070", "\u00b9", "\u00b2", "\u00b3",
            "\u2074", "\u2075", "\u2076", "\u2077", "\u2078", "\u2079");
    

    Now define a lambda to call to convert to the exponent.

    • first, covert to positive and save sign if required
    • then, iterate over the number, getting each digit using the remainder % operator. Then using that digit, index into the list of unicode characters and prepend the digit, building the exponent from right to left.
    • then prepend the sign and return the string.
    Function<Integer, String> toExp = exp -> {
        String sign = "";
        if (exp < 0) {
            sign = "\u207B"; // minus sign
            exp = -exp;
        }
        String result = sups.get(exp % 10);
        while (exp > 10) {
            exp /= 10;
            result = sups.get(exp % 10) + result;
        }
        return sign + result;
    };
    
    System.out.printf("%d%s%n", 3, toExp.apply(12));
    System.out.printf("%d%s%n", 12, toExp.apply(-329));
    

    prints

    3¹²
    12⁻³²⁹