Search code examples
javastringstring-comparison

how to compare two strings visually in java?


As of now I am making a small program that compares two string with the outcome of true and false. However, the program needs to say true if it visually looks the same. for example if it say box and b0x then it would be true. As of now the outcome is looking false as shown below.

  Enter First String:
  box
  Enter Second String:
  b0x
  false

the string below needs to be considered the same

0, o and Q
1, I and T 
2 and Z
5 and S 
8 and B

below is my current work

   import java.util.Scanner;

   public class Program {

public static void main(String[] args) {
    {
        
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter First String:");
        String str1 = sc.nextLine();
        System.out.println("Enter Second String:");
        String str2 = sc.nextLine();
        sc.close();
        
        
            String string1 = new String("0"); 
            String string2 = new String("o"); 
            String string3 = new String("q"); 
            String string4 = new String("1");
            String string5 = new String("l"); 
            String string6 = new String("T"); 
            String string7 = new String("2"); 
            String string8 = new String("z"); 
            String string9 = new String("5"); 
            String string10 = new String("s"); 
            String string11 = new String("8"); 
            String string12 = new String("b"); 
      
       
            
      
            // Comparing for String 3 = String 4 
            if (str1.equals(str2))
            {
                System.out.print(true);
            }
         
            else if(string1.equals(str1))
            {
                System.out.print(true);
            }
            
            else if(string2.equals(str2))
            {
                System.out.print(true);
            }
            
            else 
            {
                System.out.print(false);
            }
    
    }
}

}

Is there any algorithm that I can use or any way where the program can detect as true even when they are visually the same. I appreciate any help, thank you


Solution

  • First of all, when you declare String variables, you don't have to make a constructor call each time.

    String string1 = "0" // that is fine. No need to call constructor.
    

    Then, I advise you to create a collection of all the characters that are supposed to look the same.

    Iterate over all the characters of the first input, and check if :

    • each character of the first input is equal to each character of the second input
    • if it is a "look visually the same character", check if second input contains the associated(s) character(s).

    According to the data you provided, I suggest you this solution, though it is not the perfect one :

    import javafx.util.Pair;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    public class Main {
    
    private static List<List<Character>> charactersVisuallyLookingTheSame = new ArrayList<>();
    
    public static void main(String[] args) {
        initCharactersThatLookTheSame();
    
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter First String:");
        String str1 = sc.nextLine();
        System.out.println("Enter Second String:");
        String str2 = sc.nextLine();
        sc.close();
        boolean equal = equalsVisually(str1, str2);
        System.out.println(equal);
    }
    
    private static boolean equalsVisually(String first, String second)
    {
        // some checks just in case...
        if(first == null || second == null)
        {
            return false;
        }
        // to be equal visually, they must have the same length.
        if(first.length() != second.length())
        {
            return false;
        }
    
        char[] firstAsArray = first.toCharArray();
        char[] secondAsArray = second.toCharArray();
    
        for(int i = 0; i < firstAsArray.length; i++)
        {
            // if it is different
            if(firstAsArray[i] != secondAsArray[i])
            {
                if(!isCharVisuallyLookingTheSame(firstAsArray[i], secondAsArray[i]))
                {
                    return false;
                }
            }
        }
        return true;
    }
    
    private static boolean isCharVisuallyLookingTheSame(char first, char second)
    {
        // we check if it looks visually the same
        for(List<Character> visuallyTheSameList : charactersVisuallyLookingTheSame)
        {
            boolean doesFirstStringContainVisualChar = false;
            for(Character c1 : visuallyTheSameList)
            {
                if(first == c1)
                {
                    boolean doesSecondStringCharVisuallyEquals = false;
                    for(Character c2 : visuallyTheSameList)
                    {
                        if((second == c2))
                        {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
    
    
    private static void initCharactersThatLookTheSame()
    {
        // these lists contain all the characters that look visually the same.
        // add in here any list of characters that visually look the same.
    
        List<Character> o = new ArrayList<>();
        charactersVisuallyLookingTheSame.add(o);
        o.add('0');
        o.add('o');
        o.add('Q');
    
        List<Character> i = new ArrayList<>();
        charactersVisuallyLookingTheSame.add(i);
        i.add('1');
        i.add('I');
        i.add('T');
    
        List<Character>  z = new ArrayList<>();
        charactersVisuallyLookingTheSame.add(z);
        z.add('2');
        z.add('Z');
    
        List<Character> S = new ArrayList<>();
        charactersVisuallyLookingTheSame.add(S);
        S.add('5');
        S.add('S');
    
        List<Character> B = new ArrayList<>();
        charactersVisuallyLookingTheSame.add(B);
        B.add('8');
        B.add('B');
    }
    

    }


    Some outputs :

    258 and ZSB


    oQI528 and 0oTSZB


    I guess that will do the job. don't hesitate to execute it in debug mode if there are any problems. I fast coded this and I could have made mistakes.

    But overall, I suggest you to : use regular expressions. It was suggested by another answer and I think that can only be better than this. Nevertheless, regular expressions can be hard to understand...