Home > Software design >  Counting the Ones and Zeros of an String in Java, and putting them in order?
Counting the Ones and Zeros of an String in Java, and putting them in order?

Time:11-17

I do have a big problem coding something that should be easy:

I need to create a static public method which returns a string and also gets a binary number in form of an string.

public static String encode(String a) {

This method has to count the consecutive zeros and ones. If the number changes there has to be a blank. Also if the first number isn't Zero, the program has to just write a zero as first number.

Example: 11100110111 => "0 3 2 2 1 3"

Other Examples are:
encode("0") --> "1" 
encode("000") --> "3" 
encode("11") --> "0 2" 
encode("011") --> "1 2" 
encode("101") --> "0 1 1 1" 

I have no idea how to do this, it would be so nice of someone could help! I will post my worthless piece of code here, its useless but eventually it contains some helpful information!

public class Functionality {
    public static void main(String[] args) {
        System.out.println(encode("111"));

    }

    public static String encode(String a) {
        int z = 0;
        int v = 0;
        String erg = "";

        while (a.length() == 0) {

            while (v == ErsterWert(a)) {
                z = z   1;
                subt(a);

            }

            String zx = String.valueOf(z);
            erg = erg   zx   " ";
            if (v == 0) {
                v = v   1;
            }

            if (v == 1) {
                v = 0;
            }

            z = 0;

        }
        String bg = "sds";
        return erg;
    }

    public static int ErsterWert(String a) {
        int f = a.charAt(0);
        return f;
    }

    public static String subt(String a) {
        a = a.substring(1);
        return a;
    }

}

CodePudding user response:

Here's a one-liner to impress your professor with:

public static String encode(String a) {
    return (a.startsWith("1") ? "0 " : "")  
        Arrays.stream(a.split("(?<=(.))(?!\\1)"))
          .map(String::length)
          .map(String::valueOf)
          .collect(Collectors.joining(" "));
}

This splits the string between characters that are different by using a lookbehind to capture the previous character and a negative lookahead for the back reference to that captured character.

These substrings are converted to their length, then the length as a String, finally being joined to a single string separated by a space.

The special case of the first character being a 1 is handled via a ternary.

CodePudding user response:

A recursive solution using String functions indexOf and substring may look like this:

  • we try to find the position of a digit X opposite to that in the beginning of the string to calculate the length of prefix.
public static String encode(String str) {
    if (str.startsWith("1")) {
        // append 0 at start, look for 0 after 1's
        return "0 "   encode(str, 0);
    }
    // string starts with 0, look for the first 1 after 0's
    return encode(str, 1);
}

// d - the digit to look for after current prefix 
public static String encode(String z, int d) {
    int pos = z.indexOf(String.valueOf(d));
    if (pos == -1) { // nothing found after current prefix
        return String.valueOf(z.length());
    }
    // append prefix length and toggle the number to look for
    return String.valueOf(pos)   " "   encode(z.substring(pos), 1 - d);
}

Tests:

for (String s : Arrays.asList("0", "1", "000", "11", "011", "101", "0011100001111100")) {
    System.out.println(s   " -> "   encode(s));
}

Output:

0 -> 1
1 -> 0 1
000 -> 3
11 -> 0 2
011 -> 1 2
101 -> 0 1 1 1
0011100001111100 -> 2 3 4 5 2
  • Related