检查java字符串中的正确字符数

时间:2012-08-04 06:08:59

标签: java arrays string split

我正在尝试计算java字符串中出现的字符数。

例如:

给出扑克牌6s / 3d / 2H / 13c / Ad

/字符发生了多少次? = 4

用户可以输入具有不断变化的卡变量数量的另一只手,因此硬编码方法以检查发生情况是不行的。

分隔符可以是以下任何一个: - / space(一只手中只允许使用一种分隔符类型)。 所以我需要能够检查其中一个分隔符是否出现4次,否则给出的格式不正确。

这是一些java代码,可以更好地了解我正在尝试做的事情:

    String hand = "6s/1c/2H/13c/Ad";
    System.out.println("Original hand: " + hand);

    // split the hand string into individual cards
    String[] cards = hand.split(hand);

    // Checking for separators
    // Need to check for the correct number of separators
    if(hand.contains("/")){
        cards = hand.split("/");
    } else if (hand.contains("-")){
        cards = hand.split("-");
    } else if (hand.contains(" ")){
        cards = hand.split(" ");
    } else {
        System.out.println("Incorrect format!");

    }

任何帮助都会很棒!

这也是一个学校项目/家庭作业。

编辑1 --------------------------------------------- -----------

好的,所以这是我的建议之后的代码

    String hand = "6s 1c/2H-13c Ad";
    System.out.println("Original hand: " + hand);

    // split the hand string into individual cards
    String[] cards = hand.split("[(//\\-\\s)]");

    if (cards.length != 5) {
        System.out.println("Incorrect format!");    
    } else {

        for (String card : cards) {
            System.out.println(card);
        }
    }

上面给出的手的格式不正确,因为用户只能为给定的手使用一种类型的分隔符。例如:

  • 6s / 1c / 2H / 13c / Ad - 正确
  • 6s-1c-2H-13c-Ad - 更正
  • 6s 1c 2H 13c Ad - 更正

如何确保用户只使用一种类型的分隔符?

为目前为止的答案干杯!

编辑2 ------------------------------------------

因此,使用嵌套的if语句,我的代码现在看起来像这样:

    String hand = "6s/1c/2H/13c/Ad";
    System.out.println("Original hand: " + hand);

    // split the hand string into individual cards

    if(hand.contains("/")){
        String[] cards = hand.split("/");
        if(cards.length != 5){
            System.out.println("Incorrect format! 1");
        } else {
            for (String card : cards) {
                System.out.println(card);
            }
        }

    } else if(hand.contains("-")){
        String[] cards = hand.split("-");
        if(cards.length != 5){
            System.out.println("Incorrect format! 2");
        } else {
            for (String card : cards) {
                System.out.println(card);
            }
        }

    } else if(hand.contains(" ")){
        String[] cards = hand.split(" ");
        if(cards.length != 5){
            System.out.println("Incorrect format! 3");
        } else {
            for (String card : cards) {
                System.out.println(card);
            }
        }
    } else {
        System.out.println("Incorrect format! 4");
    }

这种方式按预期工作但很难看!

任何建议都会很棒。

4 个答案:

答案 0 :(得分:1)

在不给出答案的情况下,您希望将分隔符指定为split,以便返回的字符串数组如下所示:

cards[0] = "6s"
cards[1] = "1c"
cards[2] = "2H"
.
.
.

在您的特定手牌String中,您可以使用一个方便的分隔符来实现此目的...

答案 1 :(得分:0)

使用regex

<强>例如

String reg = new String();
String s = "hjhjhkello/hi"; 
Pattern pattern = Pattern.compile("[(/-\\\\s)]");  // Will find for / or - or space
Matcher matcher = pattern.matcher(s);

while(matcher.find()){

 reg = matcher.group());

}


String[] arr = hand.split(reg);

答案 2 :(得分:0)

hand.split(hand)无效。正如@home所说,你应该将输入字符串拆分为正则表达式。理解正则表达式不必(也不应该)匹配整个输入字符串 - 它应匹配任何单独的分隔符。这是String.split在传递正则表达式时的工作方式 - 将正则表达式匹配的每个位置作为分隔符,匹配之间的部分作为数组返回。

所以:尝试编写一个匹配任何一个分隔符的正则表达式。然后,检查返回的数组是否具有正确数量的元素。如果数组被称为hand,则可以使用hand.length

答案 3 :(得分:0)

我在编辑第一个问题之前写了这个,所以我回答原来的问题而不是它的附录问题。

documentation on String.split中,不清楚空字符串是否算作子字符串。请注意"--".split("-").length == 0。这个问题可能隐含地保证两个或多个字符分隔分隔符,但这是一个冒险的假设,并且Java的String.split会出现问题。

这是一个更简单的部分实现:

    char[] delims = {'/', ' ', '-'};
    int result = 0;
    for (char delim : delims) {
        for (int i = 0; i < hand.length(); i++) {
            if (hand.charAt(i) == delim) {
                ++result;
            }
        }
    }

完整的代码如下,编辑评论用于家庭作业。

interface Counter {
    int count(String hand);
}
class FirstCounter implements Counter {
    public int count(String hand) {
        String[] cards = hand.split(hand);
        if(hand.contains("/")){
            cards = hand.split("/");
        } else if (hand.contains("-")){
            cards = hand.split("-");
        } else if (hand.contains(" ")){
            cards = hand.split(" ");
        } else {
            // Prefer to fail fast unless your requirement
            // really is to only print "incorrect format"
            //System.out.println("Incorrect format!");
            throw new RuntimeException("Incorrect format!");
        }
        if (hand.endsWith("-") || hand.endsWith("/") || hand.endsWith(" ")) {
            return cards.length;
        }
        return cards.length - 1;
    }    
}
class SecondCounter implements Counter {
    public int count(String hand) {
        char[] delims = {'/', ' ', '-'};
        int result = 0;
        for (char delim : delims) {
            for (int i = 0; i < hand.length(); i++) {
                if (hand.charAt(i) == delim) {
                    ++result;
                }
            }
        }
        if (result == 0) {
            // This is a hack or inconsistent with requirements,
            // but necessary to match original posted code behavior
            throw new RuntimeException("Incorrect format!");
        }
        return result;
    }
}
class Main {
    private static int testCount = 0;

    static void realAssert(boolean condition) {
        if (!condition) {
            throw new AssertionError("Java has no real assert");
        }
    }

    static void test(Counter counter) {
        ++testCount;
        try {
            realAssert(counter.count("6s/3d/2H/13c/Ad") == 4);
            realAssert(counter.count("6s-3d-2H-13c-Ad") == 4);
            realAssert(counter.count("6s 3d 2H 13c Ad") == 4);
            // Don't forget boundary conditions
            realAssert(counter.count("6s-3d-2H-13c-") == 4);
            realAssert(counter.count("6s/3d/2H/13c/") == 4);
            realAssert(counter.count("6s 3d 2H 13c ") == 4);
            realAssert(counter.count("-6s-3d-2H-13c-") == 5);
            realAssert(counter.count("/6s/3d/2H/13c/") == 5);
            realAssert(counter.count(" 6s 3d 2H 13c ") == 5);
            realAssert(counter.count("--") == 2);
            // Remember to test error conditions
            try {
                counter.count("foobar");
                realAssert(false);
            } catch (RuntimeException e) {
                // Catching RuntimeException is normally bad
                // done only as example.
                // Also normally bad, this is an empty catch
                // block. These are sometimes useful, but always
                // at least add a comment that explains that this
                // catch block really should be empty, in this case
                // because the test was meant to throw an Error.
            }
            try {
                counter.count("foo/bar-baz");
                // Left as exercise for reader, based on question
                // it is possible this should be disallowed.
                //realAssert(false);
            } catch (RuntimeException e) {
                // Ditto above, intentionally empty catch
            }
            System.out.println("Test " + testCount + " succeeded");
        }
        catch (Error e) {
            // XXX: Don't catch Error in non-example code
            System.out.println("Test " + testCount + " failed");
            /* Normally don't use printStackTrace either */
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        test(new FirstCounter());
        test(new SecondCounter());
    }
}

仅仅为了教育,正则表达方法可以很好。整个解决方案需要一行Ruby hand.split(/[\-\/ ]/, -1).length - 1