1

How to print out the number of a specific digit along with the digit itself in form "nxw." n is the frequency of the number, w is the number itself.

So, for example, if the user's input was 1 1 1. The output would be 3x1.

If the user's input was 1 1 1 at the first line and 7 7 1 1 0 at the second line. The output would be 3x1.2x7.2x1.1x0. with no spaces.

Note:

  • loop ends with a dot.

  • numbers don't have to be in a specific order

  • user can input as many digits as they want.

So for example, Input can be 1 1 1 at the first line 7 7 1 1 0 at the second ... etc.

This is my code so far. But I know that it's not true.

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();
}
        
}
Ihab98
  • 19
  • 6
  • 1
    What's wrong with the current code specifically? Can you give an example where it fails, with input, expected output, and actual output? – Brian McCutchon Nov 29 '20 at 15:58
  • How do you know when the user has finished inputting integers? – Gilbert Le Blanc Nov 29 '20 at 16:09
  • Are the digits entered in a sorted order or can they be in any random order? – Progman Nov 29 '20 at 16:13
  • @Brian McCutchon If the input is 0 0 0 .. Output is 3x0. which is correct. BUT if the input 0 0 1 .. Output is 1x1. and if the input is 0 0 0 at the first line and 2 2 2 at the second, then the output is 3x2. When it should be 0x3.3x2. – Ihab98 Nov 29 '20 at 16:14
  • @Gilbert Le Blanc when the user enters "." or anything other than an integer – Ihab98 Nov 29 '20 at 16:15
  • @Progman They can be in any order – Ihab98 Nov 29 '20 at 16:16
  • @Ihab98 Please [edit] your question to include this information to your question. It is important to know that the digits can be random and are not necessary sorted in any way. – Progman Nov 29 '20 at 18:41
  • @Progman, this information is available in the initial post when OP described an input and expected output: _If the user's input was 1 1 1 at the first line and 7 7 1 1 0 at the second line. The output would be 3x1.2x7.2x1.1x0._ – Nowhere Man Nov 29 '20 at 18:46
  • Lets clarify: @Ihab98 Is the input like "2 4 5 2 9 0 1 4" a valid possible sequence of digits which can be entered like that? – Progman Nov 29 '20 at 18:51
  • @Progman yes it is valid – Ihab98 Nov 29 '20 at 20:52
  • @Ihab98 What would be the output generated by the input "2 4 5 2 9 0 1 4"? – Progman Nov 30 '20 at 15:28

2 Answers2

1

Existing code needs to be slightly refactored to print the frequency and integer value as soon as a sub-sequence of the same values ends.

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

Tests:

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

Output:

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.
--------

Update If separate digits need to be counted only (not the integer numbers), e.g. input 11 11 11 should be converted to 6x1. instead of 3x11. as shown above, the method should be refactored to process the digits inside numbers:

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

Output for tests: "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

Nowhere Man
  • 19,170
  • 9
  • 17
  • 42
  • the code has a bug. if the input was 1 1 1 on the first line and 7 7 2 2 1 on the second, the output is 3x1.2x7.2x2. which is not correct because it doesn't include the last digit which is one. so, in the end, there should be 1x1 – Ihab98 Nov 29 '20 at 20:56
  • Are you ready to bet on this? [This demo](https://ideone.com/M4HgMf) among other tests prints the results of `"1 1 1\n7 7 2 2 1",` for both methods as `test=[1 1 1 7 7 2 2 1] Numbers: 3x1.2x7.2x2.1x1. Digits: 3x1.2x7.2x2.1x1.` – Nowhere Man Nov 29 '20 at 21:24
0

You have to save the count of each individual digit. You can do this by creating an int array of size 10, for the digits 0 to 9. Then it's a simple loop like

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

After that you check each element in the array and output the count of the digit, when it is bigger than 0. It can look like this:

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

Keep in mind that you have to check if the number entered by the user is in the limit of 0 to 9, otherwise you run into ArrayIndexOutOfBoundsExceptions.

Progman
  • 16,827
  • 6
  • 33
  • 48