0

I have a string line like the following :

A:B:C:D:E:F:G:H:I:J:K:L:M

It means delimiter ( : ) count is 12 . This line is valid.

Now suppose you have a following line :

A:B:C:D:E:F:G:H:::::

This line is also valid because it contains 12 delimiter . where 8 values are present and 4 values are blank.

Now the following line should be invalid :

A:B:C:D:E:F: -- Invalid - because it contains only 6 values but expected are 12.

how to do this .. ? I tried the following code , but not getting the desired output :

String strLine = "A:B:C:D:E:F:G:H:::::" ;
int delimiterCount = 12 ; 

String[] ValuesArray = strLine.split(":");
 if(ValuesArray.length != delimiterCounter){
 System.out.println(Invalid);
 }else {
 System.out.println("ValidLine");
 }

I am getting the output as Invalid where as it sould be Valid.

Beginner
  • 855
  • 9
  • 21
  • 37
  • Do a string replacement and change all the `:` to empty strings - then compare string lengths - if the new string is 12 chars smaller than the original, you've got your 12 delimiters. – Marc B Jun 28 '12 at 04:49
  • @MarcB How does this stack up in terms of performance? Would String replacement cause unnecessary overhead compared with counting the number occurrences? – cklab Jun 28 '12 at 04:55
  • depends on how much data is between the delimiters. for short strings, the replacement'll be heaver, on longer strings....probably need to benchmark. – Marc B Jun 28 '12 at 04:57

5 Answers5

4

Use following method to count occurance of particular String

public static int countOccurance(String inputString, String key) {
    int index = 0;
    int fromIndex = 0;
    int result = 0;

    if (inputString == null || key == null) {
        return 0;
    }

    while ((index = inputString.indexOf(key, fromIndex)) != -1) {
        result++;
        fromIndex = index + key.length();
    }
    return result;
}
Someone Somewhere
  • 23,475
  • 11
  • 118
  • 166
jmj
  • 237,923
  • 42
  • 401
  • 438
  • Should change "fromIndex = index + 1;" into "fromIndex = index + key.length;" 'cause the key string may have length > 1. (it's only precise on this situation only.) – Thinhbk Jun 28 '12 at 04:56
  • That will improve the length of step and so the performance little, logically I don't think it will impact on the function – jmj Jun 28 '12 at 04:59
3

If you want to use split, and it's not a bad approach really (although it might be for this particular situation), you need to pass -1 as the second argument to split otherwise it removes empty strings.

See http://ideone.com/gaUw5.

It is good to know this about split. Some languages require the -1 and some do not.

The code

class Main {
    public static void main(String[] args) {
        String line = "A:B:C:D:E:F:G:H:::::" ;
        int delimiterCount = 12 ; 

        String[] values = line.split(":", -1);
        if (values.length != delimiterCount + 1) {
            System.out.println("Invalid Line");
        } else {
            System.out.println("Valid Line");
        }
    }
}
Ray Toal
  • 86,166
  • 18
  • 182
  • 232
0

It should be

String strLine = "A:B:C:D:E:F:G:H: : : : : " ;
int delimiterCount = 12 ; 

String[] ValuesArray = strLine.split(":");
 if((ValuesArray.length - 1) != delimiterCounter){
 System.out.println(Invalid);
 }else {
 System.out.println("ValidLine");
 }

as array will have values not delimeter

Rahul Agrawal
  • 8,913
  • 18
  • 47
  • 59
0

No reason to use regex here. If the only criteria for checking the validity of an input is 12 delimeters :, just count them.

String strLine = "A:B:C:D:E:F:G:H:::::";
int EXPECTED_DELIMETERS = 12;
int delimiterCount = 0;
for (int idx = 0; idx < strLine.length(); idx++) {
    if (strLine.charAt(idx) == ':') {
        delimiterCount++;
    }
}

if (EXPECTED_DELIMETERS == delimiterCount) {
    System.out.println("ValidLine");
} else {
    System.out.println("Invalid");
}
cklab
  • 3,761
  • 20
  • 29
0

Concise Java 8 solution:

private static boolean isValid(String content, char delimiter, int count) {
    return count == content.chars().filter(c -> c == delimiter).count();
}
Jan Nielsen
  • 10,892
  • 14
  • 65
  • 119