1

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

例如:

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

/ 字符出现了多少次?= 4

用户可以输入不同数量的牌变量,因此硬编码检查出现的方法是行不通的。

分隔符可以是以下任何一种: - / 空格(一只手只允许使用一种分隔符类型)。所以我需要能够检查是否有任何一个分隔符出现了 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

4 回答 4

1

在不泄露答案的情况下,您希望指定要拆分的分隔符,以便返回的字符串数组如下所示:

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

在您的特定手串中,您可以为每张卡片使用方便的分隔符来实现此目的...

于 2012-08-04T06:23:30.797 回答
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);
于 2012-08-04T06:23:02.030 回答
0

hand.split(hand)不会工作。正如@home 所说,您应该将输入字符串拆分为正则表达式。了解正则表达式不必(也不应该)匹配整个输入字符串——它应该匹配任何单独的separator。这就是String.split传递正则表达式时的工作原理——正则表达式匹配的每个位置都被视为分隔符,匹配之间的部分作为数组返回。

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

于 2012-08-04T06:25:48.233 回答
0

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

有关 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,.

于 2012-08-04T09:26:51.037 回答