【问题标题】:Is there an approach to finding the ASCII distance between two strings of 5 characters有没有一种方法可以找到两个 5 个字符的字符串之间的 ASCII 距离
【发布时间】:2020-09-27 18:55:33
【问题描述】:

我正在尝试找到一种方法来计算和打印来自用户输入的字符串之间的 Ascii 距离

 Scanner scan = new Scanner(System.in);
    System.out.print("Please enter a string of 5 uppercase characters:");
    String userString = scan.nextLine();
    

和一个随机生成的字符串

 int leftLimit = 65; // Upper-case 'A'
    int rightLimit = 90; // Upper-case 'Z'
    int stringLength = 5;
    Random random = new Random();
    String randString = random.ints(leftLimit, rightLimit + 1)
        .filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
        .limit(stringLength)
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();

有没有一种方法可以计算距离,而不必将每个单独的字符从两个字符串中分离出来,比较它们并将它们重新加在一起?

【问题讨论】:

  • “ASCII 距离”是什么意思?此外,您的流过滤器很奇怪;它什么都不过滤。可以生成的每个数字都适合该过滤器。 “HELLO”与“ABCDE”的“ascii 距离”是多少?
  • 感谢@rzwitserloot 的回复我相信你很明显我是一个极端的初学者。我想知道你所说的奇异是什么意思,因为我一点也不怀疑。我确实知道它会产生我正在寻找的随机字符串。 ASCII 距离为 37。您将“H”的 ascii 编号与“A”的 ascii 编号进行比较,依此类推,然后将差异加在一起得到 37。
  • @rzwitserloot,你是对的。 “.filter”行是不必要的

标签: java string distance


【解决方案1】:

使用Edit distance (Levenshtein distance)

你可以

你也可以检查

【讨论】:

    【解决方案2】:

    顾名思义,流就是流。它们不能很好地工作,除非您可以严格根据一个输入定义一个操作:流中的一个元素,而不知道它的索引或引用整个集合。

    这里,这是一个问题;毕竟,要对输入中的“H”进行操作,您需要随机代码中的匹配字符。

    我不知道为什么你觉得“将每个单独的字符分开,比较它们,然后将它们重新加在一起”对你来说如此令人反感。这不是从问题描述到计算机运行指令的非常清晰的映射吗?

    替代方案更复杂:您可以尝试创建一个包含字母及其索引的混合对象,流过它,并使用索引查找第二个字符串中的字符。或者,您可以尝试创建一个包含两个字符的混合对象(因此,对于输入 ABCDE 和 HELLO,一个包含 A 和 H 的对象),但是您将编写更多代码来进行设置,然后是简单的,无流方式。

    那么,让我们从简单的方法开始:

    int difference = 0;
    for (int i = 0; i < stringLength; i++) {
        char a = inString.charAt(i);
        char b = randomString.charAt(i);
        difference += difference(a, b);
    }
    

    您必须自己编写差异方法 - 但它会是一个非常简单的单行代码。

    尝试获取某种类型的两个集合,并从中创建一个流,其中流中的每个元素都匹配来自每个集合的元素(因此,["HA", "EB", "LC", "LD", "OE"] 的流)通常称为“压缩”(没有关系到流行的文件压缩算法和产品),而java并不真正支持它(还没有?)。有一些第三方库可以做到这一点,但鉴于上述内容非常简单,我认为压缩不是您要在这里寻找的。​​p>

    如果你绝对必须,我想我看起来像:

    // a stream of 0,1,2,3,4
    IntStream.range(0, stringLength)
    // map 0 to "HA", 1 to "EB", etcetera
    .mapToObj(idx -> "" + inString.charAt(idx) + randomString.charAt(idx))
    // map "HA" to the difference score
    .mapToInt(x -> difference(x))
    // and sum it.
    .sum();
    
    public int difference(String a) {
       // exercise for the reader
    }
    

    【讨论】:

      【解决方案3】:

      创建一个二维数组,用距离填充数组 - 您可以直接索引到二维数组以提取字符之间的距离。 所以一个表达式总结了一组数组访问。

      【讨论】:

      • 你能给我举个例子来说明你在说什么吗?
      【解决方案4】:

      这是我在 MATLAB 中的代码(ASCII 距离)

      function z = asciidistance(input0)
      
      if nargin ~= 1
      
          error('please enter a string');
      
      end
      
      size0 = size(input0);
      
      if size0(1) ~= 1
      
          error ('please enter a string');
      
      end
      
      length0 = size0(2);
      
      rng('shuffle');
      
      a = 32;
      b = 127;
      
      string0 = (b-a).*rand(length0,1) + a;
      
      x = char(floor(string0));
      
      z = (input0 - x);
      
      ascii0 = sum(abs(z),'all');
      ascii1 = abs(sum(z,'all'));
      
      disp(ascii0);
      disp(ascii1);
      
      disp(ascii0/ascii1/length0);
      
      end
      

      此脚本还区分基于每个字符的绝对 ASCII 距离与基于每个字符串的绝对 ASCII 距离,从而为 ASCII 距离返回两个整数。

      我还包括了这两个值的限制,其值接近被比较字符串长度的倒数。这实际上近似于运行时每个随机字符串生成事件的熵 E。

      在标准错误检查之后,脚本首先查找输入字符串的长度。 rnd 函数为随机数生成器提供种子。 ab 变量定义 ASCII 表减去不可打印字符,包括以 126 结尾。 127实际上用作上限,以便下一行代码可以生成输入长度的随机变量字符串。以下代码行将字符串转换为 ASCII 表提供的字母数字字符。以下代码行按元素减去两个字符串并存储结果。接下来的两行代码以第一段中提到的两种方式总结了 ASCII 距离。最后,打印出这些值,并提供随机字符串生成事件的熵 E。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-19
        • 1970-01-01
        • 1970-01-01
        • 2016-05-25
        • 1970-01-01
        • 1970-01-01
        • 2022-11-15
        • 2019-06-07
        相关资源
        最近更新 更多