【问题标题】:Run-length encoding in java [closed]java中的游程编码[关闭]
【发布时间】:2020-11-29 15:44:49
【问题描述】:

如何以“nxw”的形式打印出特定数字的编号以及数字本身。 n 是数字的频率,w 是数字本身。

因此,例如,如果用户的输入是 1 1 1。输出将是 3x1。

如果用户的输入是第一行的 1 1 1 和第二行的 7 7 1 1 0。输出为 3x1.2x7.2x1.1x0。没有空格。

注意:

  • 循环以点结束。

  • 数字不必按特定顺序排列

  • 用户可以输入任意数量的数字。

例如,输入可以是 1 1 1 在第一行 7 7 1 1 0 在第二行 ... 等等。

到目前为止,这是我的代码。但我知道这不是真的。

import java.util.*;

public class LaufLaengenKodierung {

public static void main(String[] args) {
        
    Scanner sc = new Scanner(System.in);
        
    int freq = 0;
    int oldNum = 0;
    int num = 0;
    boolean first = true;
        
    while(sc.hasNextInt()) {
            
        int i = sc.nextInt();
            
        if(i == oldNum) {
                
            freq++;
            num = i;
                
        } else if(i != oldNum) {
                
            freq = 1;
            oldNum = i;
            num = i;
                
            if(first) {
                    
                first = false;
                num = i;
                freq = 1;
                    
            }
        }
    }
        
    System.out.print(freq + "x" + num + ".");
    sc.close();
}
        
}

【问题讨论】:

  • 当前代码具体有什么问题?你能举一个失败的例子,包括输入、预期输出和实际输出吗?
  • 如何知道用户何时输入完整数?
  • 输入的数字是按排序顺序还是随机顺序?
  • @Brian McCutchon 如果输入为 0 0 0 .. 输出为 3x0。哪个是对的。但是如果输入 0 0 1 .. 输出是 1x1。如果第一行的输入为 0 0 0,第二行的输入为 2 2 2,则输出为 3x2。什么时候应该是 0x3.3x2。
  • @Gilbert Le Blanc 当用户输入“.”时或除整数以外的任何内容

标签: java run-length-encoding


【解决方案1】:

现有代码需要稍微重构,以便在相同值的子序列结束后立即打印频率和整数值。

static void printRLE(String input) {
    Scanner sc = new Scanner(input);
    int freq = 0;
    int oldNum = 0;
    boolean first = true;
        
    while(sc.hasNextInt()) {
            
        int i = sc.nextInt();
        
        if (i != oldNum || first) {
            if (first)
                first = false;
            else // integer value changed
                System.out.printf("%dx%d.", freq, oldNum);
            oldNum = i;
            freq = 1;
        } else {
            freq++;
        }
    }
    if (!first)    
        System.out.printf("%dx%d.%n", freq, oldNum);
    else 
        System.out.println("No integer found"); // or print 0x0 if it's correct
    sc.close();    
}

测试:

String[] tests = {
    "",
    "abc.",
    "11 11 11",
    "1 1 1\n7 7 1 1 0",
    "0 0 0",
};    

for (String test: tests) {
    System.out.println("test=[" + test + "]");
    printRLE(test);
    System.out.println("--------");
}

输出:

test=[]
No integer found
--------
test=[abc.]
No integer found
--------
test=[11 11 11]
3x11.
--------
test=[1 1 1
7 7 1 1 0]
3x1.2x7.2x1.1x0.
--------
test=[0 0 0]
3x0.
--------

更新 如果单独的数字只需要计算(不是整数),例如输入11 11 11应转换为6x1.而不是如上所示的3x11.,该方法应重构为处理数字内的数字:

static void printRLEDigits(String input) {
    Scanner sc = new Scanner(input);
    int freq = 0;
    int oldNum = 0;
    boolean first = true;
        
    out: while(sc.hasNext()) {
            
        String s = sc.next(); // getting "number" delimited with whitespaces
        for (char c: s.toCharArray()) {
            if (!Character.isDigit(c)) {
                break out;
            }
            int i = c - '0';
            if (i != oldNum || first) {
                if (first)
                    first = false;
                else // digit changed
                    System.out.printf("%dx%d.", freq, oldNum);
                oldNum = i;
                freq = 1;
            } else {
                freq++;
            }
        }
    }
    if (!first)    
        System.out.printf("%dx%d.%n", freq, oldNum);
    else 
        System.out.println("No integer found");
    sc.close();    
}

测试输出:"11 11 11", "112 223", "1 1 1\n7 7 1 1 0", "0 0 0":

test=[11 11 11]
6x1.
--------
test=[112 223]
2x1.3x2.1x3.
--------
test=[1 1 1
7 7 1 1 0]
3x1.2x7.2x1.1x0.
--------
test=[0 0 0]
3x0.
--------

Online demo of both methods printRLE and printRLEDigits

【讨论】:

  • 代码有错误。如果第一行的输入为 1 1 1,第二行的输入为 7 7 2 2 1,则输出为 3x1.2x7.2x2。这是不正确的,因为它不包括最后一位数字。所以,最后应该有 1x1
  • 您准备好下注了吗? This demo 在其他测试中将两种方法的"1 1 1\n7 7 2 2 1", 的结果打印为test=[1 1 1 7 7 2 2 1] Numbers: 3x1.2x7.2x2.1x1. Digits: 3x1.2x7.2x2.1x1.
【解决方案2】:

您必须保存每个数字的计数。您可以通过为数字 09 创建一个大小为 10 的 int 数组来做到这一点。然后是一个简单的循环,比如

while(sc.hasNextInt()) {
        
    int i = sc.nextInt();
    
    countArray[i]++;
}

然后你检查数组中的每个元素并输出数字的计数,当它大于0时。它看起来像这样:

for (int i=0; i<countArray.length; i++) {
    if (countArray[i] > 0) {
        System.out.printf("%dx%d.", countArray[i], i);
    }
}

请记住,您必须检查用户输入的数字是否在 0 到 9 的范围内,否则您会遇到ArrayIndexOutOfBoundsExceptions。

【讨论】:

    猜你喜欢
    • 2010-09-09
    • 2012-03-06
    • 1970-01-01
    • 2011-03-10
    • 2012-03-09
    • 1970-01-01
    • 2014-01-30
    • 2015-05-27
    • 1970-01-01
    相关资源
    最近更新 更多