如何在 java 中直观地比较两个字符串?

how to compare two strings visually in java?

到目前为止,我正在制作一个小程序,用于比较两个字符串的真假结果。但是,如果视觉上看起来相同,则程序需要判断为真。例如,如果它说 box 和 b0x 那么它就是真的。截至目前,结果看起来是错误的,如下所示。

  Enter First String:
  box
  Enter Second String:
  b0x
  false

下面的字符串需要被认为是相同的

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

下面是我目前的作品

   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);
            }
    
    }
}

}

是否有任何我可以使用的算法或程序可以检测为真的任何方式,即使它们在视觉上是相同的。感谢您的帮助,谢谢

这个问题(以及关于字符串模式匹配的大多数问题)的答案是正则表达式。您需要做的就是对所有字符转换使用 replaceAll 以规范化字符串。

喜欢:

str1 = str1.replaceAll("[oQ]", 0);
str1 = str1.replaceAll("[IT]", 1);

另一种选择是构建一个在相似值之间具有公共标识符的映射。可能有点复杂,但应该比多次循环 replaceAll 以标准化两个值更高效。

import java.util.HashMap;
import java.util.Map;

public class VisuallySimilar
{
  public static int id = 0;
  public static Map<Character, Integer> map = new HashMap<>();
  
  public static void similarChars(Character... chars) {
    for(Character c : chars) {
      map.put(c, id);
    }
    id++;
  }
  
  public static boolean areSimilar(String val1, String val2) {
    if(val1.length() != val2.length())
      return false;
    
    char[] char1 = val1.toCharArray();
    char[] char2 = val2.toCharArray();
    
    for(int i = 0; i < char1.length; i++) {
      if(char1[i] == char2[i] || map.get(char1[i]) == map.get(char2[i]))
        continue;
      return false;
    }
    return true;
  }
  
  public static void main(String[] args) {
    similarChars('0', 'o', 'O', 'Q');
    similarChars('T', 'I', '1');
    
    String val1 = "b0x";
    String val2 = "box";
    
    System.out.println("Are Similar: " + areSimilar(val1, val2));
  }
}

首先,当你声明String变量时,你不必每次都调用构造函数。

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

然后,我建议你创建一个所有应该看起来相同的字符的集合。

遍历第一个输入的所有字符,并检查是否:

  • 第一个输入的每个字符等于第二个输入的每个字符
  • 如果它是“视觉上看起来相同的字符”,请检查第二个输入是否包含关联的字符。

根据你提供的数据,我建议你这个解决方案,虽然它不是完美的:

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');
}

}


一些输出:



我想这样就可以了。如果有任何问题,请不要犹豫,在调试模式下执行它。我快速编码这个,我可能会犯错误

但总的来说,我建议您:使用正则表达式。这是由另一个答案提出的,我认为那只能比这更好。然而,正则表达式可能很难理解...